Skip to content

Floor: repair four out-of-closure witnesses refused by the Optional-at-Required wall; roster the compiler-origin specimen - #11865

Merged
gunbai-bot[bot] merged 2 commits into
mainfrom
session/gentle-koi-539
Sep 20, 2026
Merged

gunbai-bot[bot] merged 2 commits into
mainfrom
session/gentle-koi-539

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Sep 20, 2026

Copy link
Copy Markdown
Contributor

Work item adhoc-2fe20fe6-5e9 (floor: a witness module that fails resolve vanishes from the planned population). Receipt from neat-ibex-471 on the #11667 lane; parent ruling from eager-owl-205 (2026-09-20): do not build a second floor.

(1) The chain, and where it was unjustified

fleet_converge_workflow.on[0] is typed T? by v1.compiler.access check_index_access_node (with_optional_cardinality(elem)), and eval_index answers Null past the end — the typing is the runtime's, and indexing is a total operation exactly as DESIGN §5 wants. workflow_trigger_entry declares a required WorkflowTrigger. The witness asserted a cardinality the language never granted, so the witness is the earliest unjustified boundary; the indexing rule and #11720's RefusedOptionalAtRequired wall are both correct and untouched. The repair is the idiom #11720 established: the guard is the match.

The same grep census (xs[i], .first(), .last() at a direct-call argument, witness roots only) found three more out-of-closure modules refused by the same wall, repaired the same way: test.claim.fabric.fabric_control_plane_witness, test.claim.altra_memory_controller_witness, test.claim.nbd_proxy_virtual_media_install_witness. That census is a candidate list over one authored shape, not the population — the wall also judges list elements and undeclared list-literal members, and nothing has resolved the other declined modules.

(2) Established: never planned, never resolved — and dispositioned, not silent

From the floor log of run 35509509831 (site-projection line): declared=21557 sites=807 files=2316 claims=402 declined_long=0 declined_fixture=0 declined_outside_gate=405 declined_gate_closure=20750. The module matches no required_gate_prefixes row and was not diff-touched, so discovery enumerates its 18 identities (they are in declared), preparation never admits its module, and each identity is dispositioned DeclinedOutsideGateClosure at identity grain in required_floor_disposition.tsv. A module inside the prepared closure that fails resolve refuses the whole floor (prepare_repository_closure resolves ResolveTypecheckGate::Strict). So resolve failure never removes a discovered witness from the denominator: it is an executed verdict or a located planning refusal — satisfied today by the disposition row.

What the disposition row cannot say is whether a declined module resolves. Knowing that requires resolving it, and resolving the declined population is exactly the capability gunbc.rung_drop witness_floor_off_the_required_gate retired on 2026-09-20 (3197 modules, 14.3 min strict preparation). A floor refusal for an out-of-closure resolve failure IS that drop's restoration trigger, so this PR does not build one; it makes the row say so.

The sharper class: the falsifying change was the compiler. #11720 landed a wall in v1.compiler.infer with its census scoped (stated honestly in its body) to "what the required gates compile". A compiler change is a dependency of every witness and an import of none — src/v1 is outside the floor's source roots — so no changed-module seed, no arm-set consumer and no future import-transitive selector enumerates its victims.

Rows

  • gunbc.recurring_failure_mode.witness_that_fails_to_compile_is_absent_rather_than_red — fourth specimen (compiler-origin non-compilation), the two-sided discriminator (import-reachable falsifier → covered by transitive selection; compiler / data fixture / required-field growth → this class), and the honest-state receipt.
  • gunbc.recurring_failure_mode.witness_outside_gate_closure_falsified_by_other_file — its trigger named less than the capability; corrected by receipt, cross-referencing the sibling row.
  • gunbc.rung_drop.witness_floor_off_the_required_gate — population gains the resolve-standing member; restoration trigger names the capability: plan the enrolled population.

Deferred under the 2026-09-20 wind-down ruling (patch below, ready to lift)

Two pieces were authored and are NOT in this PR because their generated projections (.github/workflows/witnesses.yml, docs/design-rung-drops.md) could not be regenerated on this host in time (the gunbc run for main_wet_one sat 104 wall-minutes in disk-sleep for 2 CPU-minutes of work):

  • gunbc.compiler_gate_workflow: upload required_floor_disposition.tsv from the fleet lane as artifact required-floor-disposition (reusing witness_floor_tsv_upload_step), so the 20750 declined identities are a census by name — what adhoc-3bc1b8e0-982 / sleek-bat-381 need.
  • gunbc.rung_drop.witness_floor_off_the_required_gate: population gains the resolve-standing member; restoration trigger names the capability plan the enrolled population.

The row edit gunbc.recurring_failure_mode.witness_outside_gate_closure_falsified_by_other_file in this PR cross-references that trigger by name, which is correct today (the drop's trigger already says "plans and executes the enrolled witness population").

deferred_followup.patch
diff --git a/dag/gunbc/rung_drop/witness_floor_off_the_required_gate.dag b/dag/gunbc/rung_drop/witness_floor_off_the_required_gate.dag
index fef4344f8d6..734cfb05e08 100644
--- a/dag/gunbc/rung_drop/witness_floor_off_the_required_gate.dag
+++ b/dag/gunbc/rung_drop/witness_floor_off_the_required_gate.dag
@@ -39,7 +39,8 @@ data witness_floor_off_the_required_gate: RungDrop = RungDrop {
       "the generated-artifact phase -- the refusal that catches a committed projection diverging from its authority",
       "the regen fixed-point phase",
       "the parse sweep over every authored root",
+      "resolve standing of every witness module the gate closure does not reach: discovery still enumerates every claim-root identity and the floor dispositions each one -- an executed verdict, or a LOCATED planning refusal (`DeclinedOutsideGateClosure`, by identity, in `required_floor_disposition.tsv`) -- so a module that fails resolve never leaves the denominator; but a disposition row cannot tell `resolved and fine` from `never resolved`, and a compiler wall landed with a gate-scoped census leaves out-of-closure witnesses non-resolving behind a green floor (gunbc#11720 / `test.claim.workflow_dispatch_input_witness_test`, rostered as the fourth specimen of gunbc.recurring_failure_mode.witness_that_fails_to_compile_is_absent_rather_than_red)",
     ],
-    restoration_trigger: "THE CAPABILITY: the required gate again plans and executes the enrolled witness population on the revision that lands, at a cost the fleet can carry. gunbc.compiler_gate_workflow's header names the construction expected to get there -- the fold's preparation cost cut, by reusing resolved-module and reach-probe results across runs or by scoping preparation to a diff's closure -- and the MEASUREMENT that makes this the right target is that the claims were never the cost: on run 35462055101 the 4185 claims executed in 53 seconds while strict-preparation of 3197 modules took 14.3 minutes, reach probes 11 minutes, and parse, admission and bookkeeping the rest. WHAT DOES NOT RETIRE THIS ROW, stated because each is the likely mistake: re-emitting witnesses.yml from gunbc.witness_floor_workflow without the preparation repair, which restores the cost that caused the cut; a faster floor that still does not run on the merge path; and deleting gunbc.compiler_gate_workflow, which removes the stopgap rather than restoring the gate. The row retires on an OBSERVED required run that planned and executed the population on a landing revision, not on an emission",
+    restoration_trigger: "THE CAPABILITY: PLAN THE ENROLLED POPULATION -- the required gate again plans and executes the enrolled witness population on the revision that lands, at a cost the fleet can carry. Planning a claim-root module means RESOLVING it, so a witness module that does not resolve is a located floor refusal rather than a disposition row that cannot tell resolved-and-fine from never-resolved (gunbc.recurring_failure_mode.witness_that_fails_to_compile_is_absent_rather_than_red names the same capability as its trigger). gunbc.compiler_gate_workflow's header names the construction expected to get there -- the fold's preparation cost cut, by reusing resolved-module and reach-probe results across runs or by scoping preparation to a diff's closure -- and the MEASUREMENT that makes this the right target is that the claims were never the cost: on run 35462055101 the 4185 claims executed in 53 seconds while strict-preparation of 3197 modules took 14.3 minutes, reach probes 11 minutes, and parse, admission and bookkeeping the rest. WHAT DOES NOT RETIRE THIS ROW, stated because each is the likely mistake: re-emitting witnesses.yml from gunbc.witness_floor_workflow without the preparation repair, which restores the cost that caused the cut; a faster floor that still does not run on the merge path; and deleting gunbc.compiler_gate_workflow, which removes the stopgap rather than restoring the gate. The row retires on an OBSERVED required run that planned and executed the population on a landing revision, not on an emission",
   },
 }
diff --git a/dag/gunbc/witness/compiler_gate_workflow.dag b/dag/gunbc/witness/compiler_gate_workflow.dag
index ceb6b65ac44..b9fffbf1615 100644
--- a/dag/gunbc/witness/compiler_gate_workflow.dag
+++ b/dag/gunbc/witness/compiler_gate_workflow.dag
@@ -66,6 +66,8 @@ import gunbc.witness_floor_workflow {
   malloc_arena_max_env_key, malloc_arena_max_value,
   expected_red_roster_join_path,
   required_floor_disposition_path,
+  required_floor_disposition_artifact_name,
+  witness_floor_tsv_upload_step,
   long_home_storage_agreement_path,
   required_floor_claim_cost_path,
   required_floor_cross_claim_demand_path,
@@ -478,6 +480,30 @@ fn compiler_gate_candidate_upload_step() -> Step {
   }
 }
 
+// THE DISPOSITION ROSTER LEAVES THE RUNNER. The fold writes `required_floor_disposition.tsv` (one
+// row per DISCOVERED witness identity, with its disposition) and nothing read it back: the file
+// stayed on the runner, so the only observable was the site-projection count line. A count says
+// how many identities the floor declined; it cannot say WHICH, and the declined population is
+// the census a coverage question needs by name -- on 2026-09-20 `declined_gate_closure=20750`
+// held `test.claim.workflow_dispatch_input_witness_test`, a module that had stopped resolving
+// under gunbc#11720's wall with the floor green (gunbc.recurring_failure_mode
+// .witness_that_fails_to_compile_is_absent_rather_than_red, fourth specimen). The step is the
+// shared upload the previous floor workflow used for this same artifact, under the same name, so
+// a consumer that reads `required-floor-disposition` from a run reads one shape from either
+// producer. `!cancelled()` plus the build's success is the condition: a refused floor still
+// writes the roster at site projection, and a refusal AFTER that point is exactly when the
+// roster is worth reading.
+data compiler_gate_disposition_upload_step_name: String = "Upload the floor's admission roster"
+
+fn compiler_gate_disposition_upload_step() -> Step {
+  witness_floor_tsv_upload_step(
+    step_name: compiler_gate_disposition_upload_step_name,
+    artifact_name: required_floor_disposition_artifact_name,
+    path: required_floor_disposition_path,
+    condition: witness_floor_precondition()
+  )
+}
+
 fn compiler_gate_floor_bound_steps() -> List<CompilerGateBoundStep> {
   [
     CompilerGateBoundStep {
@@ -518,6 +544,11 @@ fn compiler_gate_floor_bound_steps() -> List<CompilerGateBoundStep> {
       role: consumes_only(capabilities: [RustfmtCapability]),
       step_name: "Nominal witnesses (one prepared subject, one fold)",
     },
+    CompilerGateBoundStep {
+      step: compiler_gate_disposition_upload_step(),
+      role: capability_neutral,
+      step_name: compiler_gate_disposition_upload_step_name,
+    },
     CompilerGateBoundStep {
       step: compiler_gate_drift_step(),
       role: capability_neutral,

Evidence

Local claim_batch (binary /cargo-target/release/claim_batch, sha256 387ca007bd64ee2e3cd75be00cc4692dd4176eafcbc4d790ad2567671512182b, copied before use), --source-root dag --source-root src/v2, all 18 test fns of the primary module:

  • Main head 4dd944e39ed (byte-identical file): claim_batch: resolve failed for dag/test/claim/workflow_dispatch_input_witness_test.dag: :151:73: error: value does not inhabit its declared type at the direct call argument for parameter 'trigger': declared 'Coproduct(WorkflowTrigger)', produced 'Optional<Coproduct(WorkflowTrigger)>' — exit 1, zero claims executed. This is neat-ibex-471's receipt reproduced.
  • Repaired bytes (this branch's witness files over main head 4dd944e39ed, the only difference being this PR's four witness edits): resolve succeeded; 18 witness(es), 18 PASS, 0 FAIL, including PASS workflow_dispatch_choice_input_projects_options_list. [resolve-summary] 1 resolve(s) in 1346407ms wall; 18 witness(es) in 333842ms wall (host load average ~270 during the run).
  • The three sibling modules: v1_src_dag_parse clean on all four edited files; their repairs are the identical shape at the identical diagnostic class (.first()/[0] at a required direct-call parameter). Their claim_batch runs were queued behind the primary one and killed under the wind-down ruling before reaching a verdict — not executed, stated plainly; the floor does not plan them either (all three are outside the gate closure), so their executing evidence is a follow-up claim_batch run.

Floor evidence that the module was never planned: run 35509509831, [floor-phase] phase=site-projection state=completed ... declared=21557 sites=807 files=2316 claims=402 declined_long=0 declined_fixture=0 declined_outside_gate=405 declined_gate_closure=20750; required-floor: planned=402 executed=402 ... claims_failed=0.

Not in this PR

🤖 Generated with Claude Code

gunbc-ci-auto-heal and others added 2 commits September 20, 2026 14:54
…t-Required wall; roster the compiler-origin specimen

dag/test/claim/workflow_dispatch_input_witness_test.dag stopped resolving when
#11720 landed RefusedOptionalAtRequired: list index is declared T? (and the
interpreter agrees), so the witness passing on[0] to a required WorkflowTrigger
was the earliest unjustified boundary. Repaired with the guard-is-the-match
idiom, plus three sibling sites the same grep census found
(fabric_control_plane, altra_memory_controller, nbd_proxy_virtual_media_install).

The floor never planned any of them: discovery enumerates the identities and
dispositions each DeclinedOutsideGateClosure (run 35509509831:
declined_gate_closure=20750), so the drop is located, not silent — but a
disposition row cannot tell resolved-and-fine from never-resolved, and the
capability that could is the witness_floor_off_the_required_gate restoration
trigger. No second floor is built (operating-lane ruling). The class is
appended to witness_that_fails_to_compile_is_absent_rather_than_red as its
fourth specimen (falsifier = the compiler, carried by no import graph), and the
sibling row's trigger is corrected by receipt.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… specimen of (review 69192)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@gunbai-bot

gunbai-bot Bot commented Sep 20, 2026

Copy link
Copy Markdown
Contributor Author

Review 69192 addressed at 1ad31ea (the lane that authored this PR has closed under the wind-down, so I pushed the one-symbol fix): the annotation now cites gunbc.recurring_failure_mode.witness_that_fails_to_compile_is_absent_rather_than_red — the row this same diff names the module as the fourth specimen of — with the compiler-wall falsifier stated. — sent from eager-owl-205

@gunbai-bot
gunbai-bot Bot added this pull request to the merge queue Sep 20, 2026
Merged via the queue into main with commit 4ccf673 Sep 20, 2026
8 checks passed
@gunbai-bot
gunbai-bot Bot deleted the session/gentle-koi-539 branch September 20, 2026 16:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants