Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module gunbc.rung_drop.shared_index_residency_asserted_after_the_run

import std.types { NonEmptyStr }
import gunbc.rung_drop { RungDrop, Standing, TypedDeclaration, ReplacementStaged }
import gunbc.rung_drop { RungDrop, Retired, TypedDeclaration, ReplacementStaged }
import gunbc.guarantee_rung { MechanicallyPreventable, Mitigatable }

// THE DECLARED RUNG DROP for where one-pool-per-slot is enforced in the thread's shared index memo
Expand Down Expand Up @@ -31,7 +31,7 @@ data shared_index_residency_asserted_after_the_run: RungDrop = RungDrop {

declared: "2026-09-30",

standing: Standing,
standing: Retired { trigger_fired: "2026-09-30 -- every population caller's root set was audited (the table on the retiring PR): each passes the run's own roots except three one-shot readers of a fixture pool (the regen round's dag-artifact identity compile, the XL-1 primary-root tap, the required-lane resolution census builtin), which now own their index; try_process_shared_index_for_pool refuses a second resident pool in a slot at the build site (SharedIndexSecondResidentPool, naming both root sets and the demanding site), and shared_index_residency_control stays as its positive control" as NonEmptyStr },

declaration: TypedDeclaration {
previous: MechanicallyPreventable,
Expand Down
4 changes: 3 additions & 1 deletion docs/design-rung-drops.md
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,8 @@ the python->typescript compile inhabitance claim (the real parse, bridge and com

an edited witness file classified BinWitnessWet in gunbc.ci_layer_roots witness_exclusion_frontier: the required floor's changed-witness sublane declines it as DeclinedNoCiWetLane instead of blocking, and no CI lane executes it: RUNG DROP, mechanically preventable -> mitigatable (lost as a passenger of the per-PR bin-witness wet batch, deleted with the floor cut of 2026-08-15, and .github/workflows/falsifier.yml, deleted at 611fd02770 (gunbc#8283)). Population: self_host_artifact_materialization_real_execution_witness_test.dag, stage0_regen_convergence_real_execution_witness_test.dag, typed_witness_invocation_test.dag, namespace_structural_root_exposure_generated_witness_test.dag, emit_host_typed_smoke_test.dag, build_artifact_corruption_probe_witness_test.dag, dag_collect_fingerprint_witness_test.dag, dag_compile_clean_perturb_receipts_test.dag, test/claim/diagnostics_test.dag, effects_rest_transport_parse_witness_test.dag, test/claim/parse_test.dag, v1_dag_parse_witness_test.dag, auth_declared_but_unwired_witness_test.dag, test/claim/bootstrap_test.dag, infer_semantics_witness_test.dag, dag_compile_clean_shard_a_witness_test.dag, dag_compile_clean_shard_totality_witness_test.dag, dag_compile_clean_seam_witness_test.dag, run_verdict_exit_status_witness_test.dag, http_client_get_real_execution_witness_test.dag, roadmap_belt_actuate_witness_test.dag, host_build_cache_provision_real_execution_witness_test.dag, materialized_ssh_key_file_real_execution_witness_test.dag, proc_self_cgroup_real_execution_witness_test.dag, repo_local_git_config_real_execution_witness_test.dag, transport_script_stdin_byte_fidelity_witness_test.dag, push_event_witness_wet_test.dag. Restored when: a REQUIRED lane executes changed BinWitnessWet rows for the same pull_request or merge_group -- builds their witness binaries and runs the edited entries to a terminal verdict on a host that admits their effects -- so the changed-witness sublane can plan them instead of declining; sufficient for deleting DeclinedNoCiWetLane and this row together.

### one resident pool per precedence slot in the thread's shared index memo (entry_resolve::PROCESS_RESOLVE_INDEX) — declared 2026-09-30
### one resident pool per precedence slot in the thread's shared index memo (entry_resolve::PROCESS_RESOLVE_INDEX) — declared 2026-09-30 · RETIRED

**RETIRED — TRIGGER FIRED.** 2026-09-30 -- every population caller's root set was audited (the table on the retiring PR): each passes the run's own roots except three one-shot readers of a fixture pool (the regen round's dag-artifact identity compile, the XL-1 primary-root tap, the required-lane resolution census builtin), which now own their index; try_process_shared_index_for_pool refuses a second resident pool in a slot at the build site (SharedIndexSecondResidentPool, naming both root sets and the demanding site), and shared_index_residency_control stays as its positive control

one resident pool per precedence slot in the thread's shared index memo (entry_resolve::PROCESS_RESOLVE_INDEX): RUNG DROP, mechanically preventable -> mitigatable (replacement staged: the caller audit plus a build-site refusal in try_process_shared_index_for_pool (the follow-up to gunbc#12821)). Population: v1_compiler::bin::claim_batch::run, v1_compiler::cli_run::call_compile_clean_bool_list_fn, v1_compiler::cli_run::ci_floor_commit_witness_claim_pairs, v1_compiler::cli_run::compile_clean::compile_clean_scope_plan_from_touched_paths, v1_compiler::cli_run::compile_emission, v1_compiler::cli_run::discover_owned_data_decls, v1_compiler::cli_run::emit_host::compile_dag_candidate_resolved_call_edges_uncached, v1_compiler::cli_run::emit_host::compile_xl1_primary_root_tap, v1_compiler::cli_run::emitted_crate_workspace_host::evaluate_plan, v1_compiler::cli_run::entry_resolve::load_sources_for_entry, v1_compiler::cli_run::entry_resolve::load_sources_for_entry_with_pool_index, v1_compiler::cli_run::entry_resolve::resolve_entry_graph, v1_compiler::cli_run::handle_serve, v1_compiler::cli_run::install_group_syntax, v1_compiler::cli_run::install_output_policy, v1_compiler::cli_run::materialization_provider_consumer::build_materialization_provider_ctx_cold, v1_compiler::cli_run::measure_selected_entry_closure_overlap, v1_compiler::cli_run::prime_witness_execution_legs_from_authority, v1_compiler::cli_run::project_witness_cost_receipt, v1_compiler::cli_run::render_batch_summary_line, v1_compiler::cli_run::required_floor_runner::cost_debt_changed_witness_ceiling, v1_compiler::cli_run::required_floor_runner::floor_base_test_decl_census, v1_compiler::cli_run::required_floor_runner::floor_compile_clean_emit_ok_via_index, v1_compiler::cli_run::required_floor_runner::floor_diff_baseline_readout, v1_compiler::cli_run::required_floor_runner::floor_diff_comparison_readout, v1_compiler::cli_run::required_floor_runner::floor_git_diff_name_status_range, v1_compiler::cli_run::required_floor_runner::floor_git_diff_range, v1_compiler::cli_run::required_floor_runner::head, v1_compiler::cli_run::required_floor_runner::run_discovery_corpus_with_options_inner, v1_compiler::cli_run::required_floor_runner::run_required_floor, v1_compiler::cli_run::required_floor_runner::unimported_bare_provider_roster_source_at_base, v1_compiler::cli_run::required_lane_resolution_census::entry_closure_module_identities, v1_compiler::cli_run::required_lane_resolution_census::required_floor_nominal_subject_module_identities, v1_compiler::cli_run::resolve, v1_compiler::cli_run::resolve_workspace_entry, v1_compiler::cli_run::run_required_bare_reference_admission, v1_compiler::cli_run::terminal_ledger_publish::build_ledger_wire_ctx, v1_compiler::cli_run::test_module_hygiene_bridge::resolve_hygiene_ctx, v1_compiler::cli_run::witness_gates::commit_witness_claim_pair_resolvable, v1_compiler::cli_run::witness_gates::commit_witness_claim_roster_defects, v1_compiler::generated_artifact_boundary_host::generated_artifact_ctx, v1_compiler::generated_artifact_boundary_host::run_docs_projection_agreement, v1_compiler::pre_push::load_plan_ctx, v1_compiler::required_regen_host::load, v1_compiler::required_regen_host::partition_rebuild_actuation, v1_compiler::required_regen_host::regen_generation_role_population, v1_compiler::required_regen_host::render_affected_set_bound, v1_compiler::required_regen_host::render_round_cost_receipt, v1_compiler::required_regen_host::render_scope_selection. Restored when: every population caller's root set is audited (it passes the run's own roots, or owns an index for a pool no other caller reads) and try_process_shared_index_for_pool refuses a second resident pool in a slot at the build site, before it is built; shared_index_residency_control then becomes the positive control of that refusal. Observed at retirement: the build-site refusal fires on a two-pool fixture and the floor and a regen round pass with it; this row retires in the same change.
81 changes: 52 additions & 29 deletions src/v1/stage0/src/cli_run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8558,6 +8558,20 @@ pub fn compile_entry_emission(
/// the returned files, renders diagnostics and picks an exit code -- those are boundary
/// concerns, not a second pipeline.
pub fn compile_emission(request: &CompileRequest) -> CompileRun {
compile_emission_over(request, IndexResidency::SharedProcessPool)
}

/// WHO HOLDS THE INDEX A COMPILE RESOLVES OVER. The run's own pool lives in the thread's shared
/// memo, one per precedence slot (`try_process_shared_index_for_pool`, which refuses a second).
/// A compile over a different pool whose index nothing after it reads -- a fixture root compiled
/// once by a control -- owns its index for the length of the compile instead.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum IndexResidency {
SharedProcessPool,
OwnedByThisCompile,
}

pub fn compile_emission_over(request: &CompileRequest, residency: IndexResidency) -> CompileRun {
let source_roots: &[String] = &request.source_roots;
let primary_precedence = request.primary_precedence;
let subject_label = request.subject.label();
Expand Down Expand Up @@ -8746,7 +8760,23 @@ pub fn compile_emission(request: &CompileRequest) -> CompileRun {
// compiling N entries reconciled the shared prefix N times over closures that overlap almost
// entirely. See `try_process_shared_index_for_pool` for why that is a §2 cost-shape defect
// rather than a budget fact, and for what is NOT changed by the routing.
let index: Rc<MultiEntryIndex> = if primary_precedence {
let index: Rc<MultiEntryIndex> = if residency == IndexResidency::OwnedByThisCompile {
let built = if primary_precedence {
try_build_module_index_primary_precedence(source_roots)
} else {
try_build_module_index(source_roots)
};
match built {
Ok(module_index) => Rc::new(new_multi_entry_index_shell(
module_index,
source_roots,
None,
)),
Err(cause) => {
return compile_not_executed(&request.subject, started, "source-discovery", cause)
}
}
} else if primary_precedence {
match try_process_shared_index_for_pool(source_roots, true) {
Ok(idx) => idx,
Err(cause) => {
Expand Down Expand Up @@ -10473,41 +10503,34 @@ mod closure_edge_demand_tests {
.unwrap();
}

/// The residency bound refuses a second resident pool per slot and admits one.
/// A SECOND POOL REFUSES AT BUILD, naming both root sets and the demanding site, and the
/// resident pool survives it: the residency control still reads one pool and the first
/// roots are still served from the memo. Red before the build-site refusal (the second
/// demand built and returned a second index); green with it.
#[test]
fn a_second_resident_pool_in_one_slot_refuses() {
fn a_second_pool_in_one_slot_refuses_at_build() {
let a = Fixture::new(&[("m.dag", "module res_a\nfn f() -> Int { 1 }\n")]);
let b = Fixture::new(&[("m.dag", "module res_b\nfn f() -> Int { 1 }\n")]);
try_process_shared_index(&[a.0.to_string_lossy().into_owned()]).unwrap();
assert_eq!(entry_resolve::shared_index_residency_control(), Ok(1));
try_process_shared_index(&[b.0.to_string_lossy().into_owned()]).unwrap();
let err = entry_resolve::shared_index_residency_control().unwrap_err();
assert!(err.contains("SharedIndexMoreThanOneResidentPool"), "{err}");
}

/// DISTINCT ROOTS ARE KEPT SIDE BY SIDE, NOT EVICTED. Roots A, then roots B, then A again on
/// one thread (the regen round's shape): the third demand returns the FIRST index -- the same
/// `Rc`, its parse and typed caches intact -- rather than rebuilding A (a one-entry slot) or
/// refusing it (the #12765 refusal that broke the regen round).
#[test]
fn alternating_roots_on_one_thread_reuse_each_index() {
let a = Fixture::new(&[("m.dag", "module alt_a\nfn f() -> Int { 1 }\n")]);
let b = Fixture::new(&[("m.dag", "module alt_b\nfn f() -> Int { 1 }\n")]);
let roots_a = vec![a.0.to_string_lossy().into_owned()];
let roots_b = vec![b.0.to_string_lossy().into_owned()];
let first_a = try_process_shared_index(&roots_a).unwrap();
let first_b = try_process_shared_index(&roots_b).unwrap();
assert_eq!(entry_resolve::shared_index_residency_control(), Ok(1));
let err = match try_process_shared_index(&roots_b) {
Ok(_) => panic!("a second pool in slot 0 was built"),
Err(err) => err,
};
assert!(err.contains("SharedIndexSecondResidentPool"), "{err}");
for roots in [&roots_a, &roots_b] {
let canonical = entry_resolve::canonical_shared_index_roots(roots);
assert!(
err.contains(&format!("{canonical:?}")),
"names {canonical:?}: {err}"
);
}
assert!(err.contains(file!()), "names the demanding site: {err}");
assert_eq!(entry_resolve::shared_index_residency_control(), Ok(1));
let again_a = try_process_shared_index(&roots_a).unwrap();
let again_b = try_process_shared_index(&roots_b).unwrap();
assert!(
Rc::ptr_eq(&first_a, &again_a),
"A is reused after B, not rebuilt"
);
assert!(Rc::ptr_eq(&first_b, &again_b), "B is reused after A");
assert!(
!Rc::ptr_eq(&first_a, &first_b),
"distinct roots are distinct indexes"
);
assert!(Rc::ptr_eq(&first_a, &again_a), "the resident pool is kept");
}

/// THE VALID TWIN: the same shape with the homonym removed is admitted by the entry and by
Expand Down
2 changes: 1 addition & 1 deletion src/v1/stage0/src/cli_run/emit_host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2448,7 +2448,7 @@ pub(crate) fn compile_xl1_primary_root_tap(
),
};
}
let index = match try_process_shared_index(source_roots) {
let index = match super::entry_resolve::try_index_for_run_or_owned_pool(source_roots) {
Ok(idx) => idx,
Err(cause) => {
return Xl1PrimaryRootTap::Refused {
Expand Down
Loading
Loading