Repository navigation
Partition the floor's 164 runtime-errored identities, and land the compiler control the specimens were the only evidence for - #9022
Merged
Conversation
…mpiler control the specimens were the only evidence for Required-floor run 32633501354 (main, head 907f19c) reports known_red_runtime_errored=164: programs the compiler ACCEPTED and the interpreter could not evaluate. That counter is the class's only observer and it falls to zero as the witnesses are repaired — gunbc#9006 is repairing 21 of them right now — so the evidence had to stop living in the specimens. The partition, its producer, and the per-identity rows are docs/plans/receipts/floor-runtime-error-partition-2026-08-23/. Five causal families; the reference-unavailable subset is 149 of the 164 and every one of its names IS declared somewhere in the corpus — the undeclared-anywhere class is EMPTY, so intended compile state never separates on the name not existing. It separates on where the declaration lives: 126 identities reference a module-scope `data` in an unimported module, 9 a bare variant or type name, 8 a `fn`, 5 a `test data` in another test file, 1 a type in call position. WHAT LANDS AS A FIXTURE: HOST-PRIMITIVE-CONTRACT, 11 of the 164. Measured on compile_dag_rust_emit_check at this head, a host primitive's argument list is unchecked at compile in every direction — two arguments, zero arguments, and one argument of the wrong type all compile clean, and the host arm then refuses each at evaluation with `requires exactly one string argument`. Three REDs assert the refusal belongs at compile; three positive controls (clean compiles, broken refuses, the CORRECT one-string call still compiles) make each RED discriminating rather than a blanket claim. All six measured by execution: controls true, REDs false. The three are enrolled in floor_expected_red so the day the contract is checked they PASS and red the build naming themselves. WHAT DOES NOT LAND, as a measurement rather than an omission: no fixture for the 149. Both .dag-callable compile-observation surfaces REFUSE that shape (compile_dag_rust_emit_check false, compile_diagnostic_census blocking) while the floor's own witness loader ACCEPTS it, because that loader runs extend_with_bare_reference_closure and resolves the name through the tree census. A fixture on either surface would be permanently green and cited as coverage of a class it never touches. Its next-rung trigger is a compile-observation surface resolving names by the witness loader's rule. Discriminating control for that claim, executed both ways: a source calling `argument_form_is_valid(design_argument)` with no imports compiles silent and throws NoSuchFunction at evaluation; the identical source with `import gunbc.design_argument { design_argument }` compiles and evaluates true. The import is the whole discriminator and the compiler says nothing about it. Enrolment verified by execution: roster length 203, the identity present once. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
gunbai-bot Bot
pushed a commit
that referenced
this pull request
Aug 23, 2026
…protects it
Fixing the ArgvCommand seal unmasked nothing -- this was already visible. With
preparation passing, the fold runs and refuses:
REQUIRED-FLOOR REFUSAL cause=ExpectedRedIdentityDidNotExecute count=3
test.claim.compile_accepted_unevaluable_program_control.primitive_call_with_{extra,missing,wrong}_...
gunbc#9022 landed both the module and the enrolment. Its annotation states the
belief directly -- the file declares ReadsLiveTree and is DeclinedLiveTree, so
the three are "held here so that admission does not red main" -- and that is
backwards. run_required_floor refuses on any enrolled identity absent from the
executed claims, so a row whose home DECLINES execution cannot satisfy its own
enrolment. The roster requires observation; a declined identity is never
observed.
Not inferred: #9022's own witnesses check reported this exact refusal, count=3,
naming these three, and it merged with that check red. So main carries two
independent preparation-and-fold blockers today, and only the first was mine.
This is the authority-substitution shape -- I registered it in A, so B now does
X -- with A the roster, B the floor's admission, and no relation between them
pointing the way the sentence assumed. The relation that exists points the other
way.
WHAT AN ENROLMENT ASSERTS is that the identity RAN and FAILED as predicted. For
one that cannot run there is no truth value to hold, so the enrolment follows
execution rather than preceding it.
NOTHING IS HIDDEN. The three do not execute either way, so removing them conceals
no failing assertion and deletes no evidence: the probes, their two positive
controls, and the module's reasoning all stay put. DESIGN 4b(4) protects the
evidence, not the roster row -- and the evidence is the file, which is untouched.
DECLARED RESTORATION TRIGGER (4b(3)): re-enrol all three in the same change that
admits the file to execution -- the DeclinedLiveTree arm deletion, gunbc#8977 or
gunbc#8982, both OPEN. On that change they become planned and return false, and
the roster holds them as authored; if they PASS instead, stale-quarantine reds
the build naming them, which is what the family wants.
Six chunks in this roster are already Empty {}, so the empty chunk keeps the
established shape rather than deleting a function another index depends on.
This was referenced Aug 23, 2026
gunbai-bot Bot
pushed a commit
that referenced
this pull request
Aug 23, 2026
…e floor The ArgvCommand repair in this branch unmasked a second main-red defect that had never been observed, because every run since it landed died at strict preparation before the fold could reach it. gunbc#9022 enrolled three compile_accepted_unevaluable_program_control identities in the expected-red roster while their file declares ReadsLiveTree, so the DeclinedLiveTree arm declines them (declined_live=899) and they are never planned. The floor requires every ENROLLED identity to be observed among the EXECUTED claims, so the run refuses with cause=ExpectedRedIdentityDidNotExecute count=3. Chunk 21's own annotation states the opposite belief -- "until it lands they are held here so that admission does not red main" -- and execution refutes it twice: on #9022's own run 32644795043, which was merged red, and again on run 32649496046 here, where it was the sole floor refusal once the seal stopped masking it. The precondition that enrolment was authored against has not landed: gunbc#8977 and gunbc#8982, which delete the decline arm, are both still open. The rows are correct and stay in chunk 21. Only their LIVENESS is wrong, so they join the file's existing exclusion in floor_expected_red_is_live -- the mechanism already used for the mock-totality family -- which keeps the rows for provenance while removing them from the live roster. Verified by execution, not by reading the predicate: each of the three returns excluded (exit 1) through --claim-run, and an arbitrary unrelated identity returns live (exit 0), so the predicate discriminates rather than excluding everything. The exclusion is a coupling, not a note: whoever lands #8977 or #8982 must delete these three exclusions in the same change, or the rows will execute while excluded, count as ordinary failures, and red the build. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This was referenced Aug 23, 2026
gunbai-bot Bot
pushed a commit
that referenced
this pull request
Aug 23, 2026
…overed Operator ruling 2026-08-23: kill/quarantine it and find out why. Both halves are here -- the move, and the measurement that makes this a filed defect rather than a cost row. #9031's run 32657761997 was otherwise clean (failed=0, stale_quarantine=0, interrupted_before_verdict=0) with ONE non-pass: COMPLETED-OVER-COST-REQUIREMENT qualified_spelling_takes_the_shared_layer wall_ms=57337 cpu_ms=57193 [floor-claim-memory] grew rss by 1.22GB (to 11.70GB) 11x the 5000ms executor fail-stop. The fail-stop is doing its job: at 11.70GB this claim genuinely threatens the process it runs in. THE SPLIT THAT WAS SUPPOSED TO FIX THIS DID NOTHING, and that is the finding. #8984's own note records the conjoined two-arm claim at 1.22GB RSS growth against 0.12GB for the whole rest of the roster, and splits the arms into separate test fns on the reasoning that two live compile_dag_rust_emit_check calls sat inside one claim. Measured after the split, the QUALIFIED ARM ALONE grows 1.22GB -- the identical figure -- and the bare arm appears in no over-cost or memory line at all. So the entire cost was always the qualified arm. It is not two compiles; it is the qualified-name resolution path specifically, which is the path #8984 exists to repair. WHY QUARANTINE AND NOT A COST ENVELOPE. An envelope large enough to admit 57s and 1.22GB would admit the defect rather than measure it. The dissolution condition on this row is therefore the REPAIR, explicitly not an envelope, so nobody closes it by raising the ceiling. WHY IT REACHED MAIN UNSEEN. #8984 landed in the batch after the last green run while main refused at floor PREPARATION on an unrelated ArgvCommand seal break, so its floor phase never executed and this row never surfaced on its own check. That is the same masking that hid #9022's roster defect in the same batch -- two independent defects merged behind one preparation refusal, which is the argument for consuming every gating cause on your own run rather than only the rows you meant to change. WHAT MOVES: the file to dag/test/claim/long/ with its module renamed, one WitnessExclusionRow carrying the measurement and the local recipe, and the provider fixture's prose pointer updated so it does not name a module path that no longer exists. WHAT DOES NOT MOVE: both arms, their assertions and the whole authored rationale are untouched. This is a home change and a declared rung drop, not a repair and not a weakening of what the witness claims.
gunbai-bot Bot
added a commit
that referenced
this pull request
Aug 23, 2026
…ather than by widening the seal (#9031) * Convert the one ArgvCommand site the seal missed, through a builder rather than by widening the seal main does not compile. `extdeps.exec.command` `ArgvCommand` became `sole_constructor { program, arguments }` in #8919, and its carrier states the invariant: "Every ArgvCommand construction site in the corpus was converted in the same change, because a partial seal is a dual-authority interval rather than a weaker seal." One site was not. `gunbc.runner_slot_provision` `observe_runner_slot_members_wet` still built `ArgvCommand { argv: ["ls", "-1", actions_runner_base_dir] }`, producing four distinct diagnostics and refusing the floor at strict-preparation — so no witness ran and no `required-floor` counter line was emitted at all. Not a missed conversion by that PR. #8992 ADDED this site after #8919 was authored and before it merged; neither touched the other's lines, so git merged both without a conflict and the corpus broke on semantics. A clean merge is not coherence. WHAT WAS DELIBERATELY NOT DONE: `runner_slot_provision` is not added to `argv_command`'s `admit_callers`. That list is forty named builders, each for ONE operation of ONE tool, homed in that tool's own extdeps module; admitting a product module would defeat the wall rather than satisfy it. A MODELED ALTERNATIVE WAS LOOKED FOR FIRST and does not exist at this layer. `ls -1 | parse` is a shell-ism, so the right first question was whether the substrate already answers "what entries are under this path" without shelling out. `dag/extdeps/filesystem` carries posix `EntryKind` but no listing operation, and the `list_dir` in `src/v2/extdeps/file_system.dag` is the v2 realization surface, not reachable from a v1-era `wet` observation running over `LocalExec`. So the builder is authored rather than the listing being re-modeled, and the call site keeps enumerating BY DIRECTORY — which its own carrier requires, since probing the desired names could only ever return a subset of what was already intended and would make an out-of-band slot invisible. `-1` is baked into the builder with its reason, following `rm_force_command`'s precedent: ls(1) columnates to a terminal and emits one-per-line to a pipe, so a caller that does not pass `-1` depends on where its output happens to go. It does not recurse and does not include dotfiles; a caller needing either needs its own name, not a flags parameter. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Enrolled-but-never-planned is not a parking spot: it refuses the whole floor The ArgvCommand repair in this branch unmasked a second main-red defect that had never been observed, because every run since it landed died at strict preparation before the fold could reach it. gunbc#9022 enrolled three compile_accepted_unevaluable_program_control identities in the expected-red roster while their file declares ReadsLiveTree, so the DeclinedLiveTree arm declines them (declined_live=899) and they are never planned. The floor requires every ENROLLED identity to be observed among the EXECUTED claims, so the run refuses with cause=ExpectedRedIdentityDidNotExecute count=3. Chunk 21's own annotation states the opposite belief -- "until it lands they are held here so that admission does not red main" -- and execution refutes it twice: on #9022's own run 32644795043, which was merged red, and again on run 32649496046 here, where it was the sole floor refusal once the seal stopped masking it. The precondition that enrolment was authored against has not landed: gunbc#8977 and gunbc#8982, which delete the decline arm, are both still open. The rows are correct and stay in chunk 21. Only their LIVENESS is wrong, so they join the file's existing exclusion in floor_expected_red_is_live -- the mechanism already used for the mock-totality family -- which keeps the rows for provenance while removing them from the live roster. Verified by execution, not by reading the predicate: each of the three returns excluded (exit 1) through --claim-run, and an arbitrary unrelated identity returns live (exit 0), so the predicate discriminates rather than excluding everything. The exclusion is a coupling, not a note: whoever lands #8977 or #8982 must delete these three exclusions in the same change, or the rows will execute while excluded, count as ordinary failures, and red the build. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * The srv4 activation witness re-spelled two programs the seal then moved Third blocker on main, and the first one visible only after the other two cleared: with preparation passing and the roster refusal gone, the fold reaches this row and it returns false. FAIL test.claim.runner_host_deploy.srv4_enables_its_declared_runner_instances The cause is one conjunct, and it is not the width axis this row is otherwise about: && string_contains(s: enable, pattern: "'sudo' 'systemctl' 'enable' '--now'") That was correct against the hand-built argv the row was written for. #8919 routed runner_enable_command_argv through extdeps.systemd.systemctl systemctl_enable_now_command, which mints through the sealed argv_command with sudo_binary_path (/usr/bin/sudo) as the program and inserts sudo's non-interactive flag -- so the rendered prefix is no longer the four words the pattern names, and #8919 updated two lines of this file without reaching this one. WHAT I CHECKED BEFORE CHANGING ANYTHING, because a witness edited to match the code it guards is worse than a red one. Quoting was the obvious suspect and it is NOT the cause: shell_quote single-quotes unconditionally (emit_test's shell_quote(arg: "plain") == "'plain'" pins it), so the unit-name conjuncts still match. Admission was the other suspect and it is not the cause either: the fixture receipts bind correctly on every arm admit_runner_activation checks -- instance host, managed_unit against intended_unit, all six verified flags, pool host, and slice_unit against intended_compile_pool -- so the command is READY and `enable` is a real render rather than the refusal arm's "". THE REPAIR CITES RATHER THAN RE-SPELLS. The old pattern was a third authoring of facts extdeps.sudo.elevation and extdeps.systemd.systemctl already own, which is why it rotted without anyone touching it (DESIGN section 3). The conjunct is now two, deriving the program spellings from those authorities and split because they assert different things: that activation ELEVATES NON-INTERACTIVELY, and that it reaches systemctl's ENABLE --NOW. WHY THIS IS NOT measure() == measure(). `enable` and `--now` stay literal, and they are the discriminating half: they are systemctl's own operands, spelled inline by the builder rather than read from any row, so a command that carried the units without the verb still fails here. What the derived halves buy is that a future re-homing of the sudo or systemctl spelling moves the assertion with the authority instead of leaving a fourth copy to rot. Not verified locally: the same stale-binary limit recorded on the previous commit applies. CI is the authority. * join is not a std.types export: the two derived patterns build with concat Preparation refused on the previous head with a single diagnostic -- runner_host_deploy_witness_test.dag:4:33: name 'join' not found in module 'std.types' -- so the import I added to carry the derived invocation patterns named a symbol that module does not export. The witness already builds every other composed pattern with concat and needs no import for it; the two new ones now do the same. This is my own defect from the previous commit, not new fallout: the repair it carries is unchanged, only its spelling of string concatenation. The stale-binary limit recorded there is exactly why it reached CI to be caught -- a local compile under a binary that predates the seal cannot answer questions about this tree. * Quarantine the qualified-spelling witness, and file the defect it uncovered Operator ruling 2026-08-23: kill/quarantine it and find out why. Both halves are here -- the move, and the measurement that makes this a filed defect rather than a cost row. #9031's run 32657761997 was otherwise clean (failed=0, stale_quarantine=0, interrupted_before_verdict=0) with ONE non-pass: COMPLETED-OVER-COST-REQUIREMENT qualified_spelling_takes_the_shared_layer wall_ms=57337 cpu_ms=57193 [floor-claim-memory] grew rss by 1.22GB (to 11.70GB) 11x the 5000ms executor fail-stop. The fail-stop is doing its job: at 11.70GB this claim genuinely threatens the process it runs in. THE SPLIT THAT WAS SUPPOSED TO FIX THIS DID NOTHING, and that is the finding. #8984's own note records the conjoined two-arm claim at 1.22GB RSS growth against 0.12GB for the whole rest of the roster, and splits the arms into separate test fns on the reasoning that two live compile_dag_rust_emit_check calls sat inside one claim. Measured after the split, the QUALIFIED ARM ALONE grows 1.22GB -- the identical figure -- and the bare arm appears in no over-cost or memory line at all. So the entire cost was always the qualified arm. It is not two compiles; it is the qualified-name resolution path specifically, which is the path #8984 exists to repair. WHY QUARANTINE AND NOT A COST ENVELOPE. An envelope large enough to admit 57s and 1.22GB would admit the defect rather than measure it. The dissolution condition on this row is therefore the REPAIR, explicitly not an envelope, so nobody closes it by raising the ceiling. WHY IT REACHED MAIN UNSEEN. #8984 landed in the batch after the last green run while main refused at floor PREPARATION on an unrelated ArgvCommand seal break, so its floor phase never executed and this row never surfaced on its own check. That is the same masking that hid #9022's roster defect in the same batch -- two independent defects merged behind one preparation refusal, which is the argument for consuming every gating cause on your own run rather than only the rows you meant to change. WHAT MOVES: the file to dag/test/claim/long/ with its module renamed, one WitnessExclusionRow carrying the measurement and the local recipe, and the provider fixture's prose pointer updated so it does not name a module path that no longer exists. WHAT DOES NOT MOVE: both arms, their assertions and the whole authored rationale are untouched. This is a home change and a declared rung drop, not a repair and not a weakening of what the witness claims. * Two zero-byte shell artifacts were committed at the repo root `exit_code` and `{` are both empty files introduced by 96da63f. They are redirect and brace-expansion debris from an interactive shell, not source, and nothing references either as a path: the `exit_code` hits in the corpus are shell-transport OUTPUT FIELD decodings (`exit_code: Int from "exit_code"` in extdeps.shell.exec and friends), which name a captured field, not a file. Removed rather than ignored. A .gitignore rule does not untrack a path already in the branch, and leaving them would land two junk files in the repo root on merge. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: Brian Searls <briansearls1@gmail.com>
briansrls
pushed a commit
that referenced
this pull request
Aug 23, 2026
* WIP: MAIN RED #4: eight runner-slot/fleet-capacity witnesses return Bool(fals * Fix record-like if condition brace parsing * Unenrol the seventeen rows this fix made pass, and keep the four beside them that it did not The floor reported seventeen v2.test.claim.generated_conformance_floor identities as STALE-QUARANTINE -- enrolled as expected-red and PASSED. That is this branch's fix working: all seventeen were previously KNOWN-RED-RUNTIME-ERRORED, throwing `no such function` on names that were genuinely declared, because the reference-closure collector narrowed on binding metadata its own producer never populates. Deriving the closure from lexical binders instead makes the calls resolve, the witnesses answer, and every one of them answers PASS. The two arms are not symmetric and that is why this reds the build. KNOWN-RED-RUNTIME-ERRORED is reported and deliberately NOT gating (claim_executor required_floor_outcome_is_clean lists seven causes and that is not one of them); STALE-QUARANTINE IS one of the seven. So the fix moved seventeen rows from a non-gating arm to a gating one, and the roster edit is the prescribed remedy the floor's own message names. The four generated_coproduct_exhaustiveness_* rows in the same generated module are retained deliberately. They were not reported passing, so they are still red for their own reasons -- unenrolling the module wholesale would have dropped four live reds under cover of a repair that never reached them. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Convert the one ArgvCommand site the seal missed, through a builder rather than by widening the seal main does not compile. `extdeps.exec.command` `ArgvCommand` became `sole_constructor { program, arguments }` in #8919, and its carrier states the invariant: "Every ArgvCommand construction site in the corpus was converted in the same change, because a partial seal is a dual-authority interval rather than a weaker seal." One site was not. `gunbc.runner_slot_provision` `observe_runner_slot_members_wet` still built `ArgvCommand { argv: ["ls", "-1", actions_runner_base_dir] }`, producing four distinct diagnostics and refusing the floor at strict-preparation — so no witness ran and no `required-floor` counter line was emitted at all. Not a missed conversion by that PR. #8992 ADDED this site after #8919 was authored and before it merged; neither touched the other's lines, so git merged both without a conflict and the corpus broke on semantics. A clean merge is not coherence. WHAT WAS DELIBERATELY NOT DONE: `runner_slot_provision` is not added to `argv_command`'s `admit_callers`. That list is forty named builders, each for ONE operation of ONE tool, homed in that tool's own extdeps module; admitting a product module would defeat the wall rather than satisfy it. A MODELED ALTERNATIVE WAS LOOKED FOR FIRST and does not exist at this layer. `ls -1 | parse` is a shell-ism, so the right first question was whether the substrate already answers "what entries are under this path" without shelling out. `dag/extdeps/filesystem` carries posix `EntryKind` but no listing operation, and the `list_dir` in `src/v2/extdeps/file_system.dag` is the v2 realization surface, not reachable from a v1-era `wet` observation running over `LocalExec`. So the builder is authored rather than the listing being re-modeled, and the call site keeps enumerating BY DIRECTORY — which its own carrier requires, since probing the desired names could only ever return a subset of what was already intended and would make an out-of-band slot invisible. `-1` is baked into the builder with its reason, following `rm_force_command`'s precedent: ls(1) columnates to a terminal and emits one-per-line to a pipe, so a caller that does not pass `-1` depends on where its output happens to go. It does not recurse and does not include dotfiles; a caller needing either needs its own name, not a flags parameter. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Handle record-like conditions on operator RHS * An enrolled identity that cannot execute is what reds main, not what protects it Fixing the ArgvCommand seal unmasked nothing -- this was already visible. With preparation passing, the fold runs and refuses: REQUIRED-FLOOR REFUSAL cause=ExpectedRedIdentityDidNotExecute count=3 test.claim.compile_accepted_unevaluable_program_control.primitive_call_with_{extra,missing,wrong}_... gunbc#9022 landed both the module and the enrolment. Its annotation states the belief directly -- the file declares ReadsLiveTree and is DeclinedLiveTree, so the three are "held here so that admission does not red main" -- and that is backwards. run_required_floor refuses on any enrolled identity absent from the executed claims, so a row whose home DECLINES execution cannot satisfy its own enrolment. The roster requires observation; a declined identity is never observed. Not inferred: #9022's own witnesses check reported this exact refusal, count=3, naming these three, and it merged with that check red. So main carries two independent preparation-and-fold blockers today, and only the first was mine. This is the authority-substitution shape -- I registered it in A, so B now does X -- with A the roster, B the floor's admission, and no relation between them pointing the way the sentence assumed. The relation that exists points the other way. WHAT AN ENROLMENT ASSERTS is that the identity RAN and FAILED as predicted. For one that cannot run there is no truth value to hold, so the enrolment follows execution rather than preceding it. NOTHING IS HIDDEN. The three do not execute either way, so removing them conceals no failing assertion and deletes no evidence: the probes, their two positive controls, and the module's reasoning all stay put. DESIGN 4b(4) protects the evidence, not the roster row -- and the evidence is the file, which is untouched. DECLARED RESTORATION TRIGGER (4b(3)): re-enrol all three in the same change that admits the file to execution -- the DeclinedLiveTree arm deletion, gunbc#8977 or gunbc#8982, both OPEN. On that change they become planned and return false, and the roster holds them as authored; if they PASS instead, stale-quarantine reds the build naming them, which is what the family wants. Six chunks in this roster are already Empty {}, so the empty chunk keeps the established shape rather than deleting a function another index depends on. * Enrolled-but-never-planned is not a parking spot: it refuses the whole floor The ArgvCommand repair in this branch unmasked a second main-red defect that had never been observed, because every run since it landed died at strict preparation before the fold could reach it. gunbc#9022 enrolled three compile_accepted_unevaluable_program_control identities in the expected-red roster while their file declares ReadsLiveTree, so the DeclinedLiveTree arm declines them (declined_live=899) and they are never planned. The floor requires every ENROLLED identity to be observed among the EXECUTED claims, so the run refuses with cause=ExpectedRedIdentityDidNotExecute count=3. Chunk 21's own annotation states the opposite belief -- "until it lands they are held here so that admission does not red main" -- and execution refutes it twice: on #9022's own run 32644795043, which was merged red, and again on run 32649496046 here, where it was the sole floor refusal once the seal stopped masking it. The precondition that enrolment was authored against has not landed: gunbc#8977 and gunbc#8982, which delete the decline arm, are both still open. The rows are correct and stay in chunk 21. Only their LIVENESS is wrong, so they join the file's existing exclusion in floor_expected_red_is_live -- the mechanism already used for the mock-totality family -- which keeps the rows for provenance while removing them from the live roster. Verified by execution, not by reading the predicate: each of the three returns excluded (exit 1) through --claim-run, and an arbitrary unrelated identity returns live (exit 0), so the predicate discriminates rather than excluding everything. The exclusion is a coupling, not a note: whoever lands #8977 or #8982 must delete these three exclusions in the same change, or the rows will execute while excluded, count as ordinary failures, and red the build. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * The srv4 activation witness re-spelled two programs the seal then moved Third blocker on main, and the first one visible only after the other two cleared: with preparation passing and the roster refusal gone, the fold reaches this row and it returns false. FAIL test.claim.runner_host_deploy.srv4_enables_its_declared_runner_instances The cause is one conjunct, and it is not the width axis this row is otherwise about: && string_contains(s: enable, pattern: "'sudo' 'systemctl' 'enable' '--now'") That was correct against the hand-built argv the row was written for. #8919 routed runner_enable_command_argv through extdeps.systemd.systemctl systemctl_enable_now_command, which mints through the sealed argv_command with sudo_binary_path (/usr/bin/sudo) as the program and inserts sudo's non-interactive flag -- so the rendered prefix is no longer the four words the pattern names, and #8919 updated two lines of this file without reaching this one. WHAT I CHECKED BEFORE CHANGING ANYTHING, because a witness edited to match the code it guards is worse than a red one. Quoting was the obvious suspect and it is NOT the cause: shell_quote single-quotes unconditionally (emit_test's shell_quote(arg: "plain") == "'plain'" pins it), so the unit-name conjuncts still match. Admission was the other suspect and it is not the cause either: the fixture receipts bind correctly on every arm admit_runner_activation checks -- instance host, managed_unit against intended_unit, all six verified flags, pool host, and slice_unit against intended_compile_pool -- so the command is READY and `enable` is a real render rather than the refusal arm's "". THE REPAIR CITES RATHER THAN RE-SPELLS. The old pattern was a third authoring of facts extdeps.sudo.elevation and extdeps.systemd.systemctl already own, which is why it rotted without anyone touching it (DESIGN section 3). The conjunct is now two, deriving the program spellings from those authorities and split because they assert different things: that activation ELEVATES NON-INTERACTIVELY, and that it reaches systemctl's ENABLE --NOW. WHY THIS IS NOT measure() == measure(). `enable` and `--now` stay literal, and they are the discriminating half: they are systemctl's own operands, spelled inline by the builder rather than read from any row, so a command that carried the units without the verb still fails here. What the derived halves buy is that a future re-homing of the sudo or systemctl spelling moves the assertion with the authority instead of leaving a fourth copy to rot. Not verified locally: the same stale-binary limit recorded on the previous commit applies. CI is the authority. * Repin the srv4 enable witness on the grounded sudo spelling, and stop its refusal arm from erasing the cause srv4_enables_its_declared_runner_instances was red on main, and not on the roster/units join it exists to check. Its last conjunct pinned 'sudo' 'systemctl' 'enable' '--now', which was the rendering before extdeps.sudo.elevation grounded the elevation words -- sudo_binary_path at the absolute /usr/bin/sudo, sudo_non_interactive_flag at -n -- and systemctl_enable_now_command now builds its argv from those rows. Both modules' own annotations record that re-spelling as deliberate ("callers that previously spelled a bare sudo now render this row -- a real change in the emitted words"), so the witness was the straggler that update missed, not a defect in the fleet model. The pattern is repinned as a literal rather than rebuilt from those two rows, because deriving it from the same authority the builder consumes would make the conjunct agree with itself whatever the rows say. The second half of the brief is why neither falsification of this row located itself. The refusal arm collapsed to "", so an activation refusal and a command that says something else both arrived as one indistinguishable false -- every string_contains below fails identically on an empty render. That is the not-applicable-versus-malformed conflation DESIGN names, sitting in a witness. Refusal is now its own match arm returning false directly, and the content assertions run only inside RunnerCommandReady, where a command actually exists. The same collapse in srv4_runner_installer_command_cites_installer_with_env is fixed the same way, since it was one shape written twice. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014oG2tMMAxgZeAQxDjvNsFm * Remove trailing whitespace from expected-red roster * join is not a std.types export: the two derived patterns build with concat Preparation refused on the previous head with a single diagnostic -- runner_host_deploy_witness_test.dag:4:33: name 'join' not found in module 'std.types' -- so the import I added to carry the derived invocation patterns named a symbol that module does not export. The witness already builds every other composed pattern with concat and needs no import for it; the two new ones now do the same. This is my own defect from the previous commit, not new fallout: the repair it carries is unchanged, only its spelling of string concatenation. The stale-binary limit recorded there is exactly why it reached CI to be caught -- a local compile under a binary that predates the seal cannot answer questions about this tree. * Drop the enable-conjunct change: #9031 owns that row, and the derivation ruling is right RULING ACCEPTED (swift-badger-524). #9031 fix/argv-command-ls-seal already carries a fix for srv4_enables_its_declared_runner_instances, authored directly on that branch minutes before this PR opened, and it is the branch unblocking main's ledger. That row is restored here to main's text verbatim so the two edits cannot collide; #9031's version lands. I WAS WRONG ABOUT THE DERIVATION AND THE REASON MATTERS. I kept the elevation words as a literal and cited DESIGN's oracle rule -- automating a literal's update must not collapse the assertion to measure() == measure(). That rule is correct and its premise is absent here, because there are TWO producers, not one: the witness's pattern would derive from extdeps.sudo.elevation and extdeps.systemd.systemctl, while the string being searched is produced by runner_activate_command's BUILDER. measure(builder) == measure(authority) is the join actually worth asserting -- that the builder routes through the authorities instead of spelling its own words -- and it stays discriminating: hardcode a bare sudo in the builder while the authority says /usr/bin/sudo and the derived conjunct goes red. The collapse I feared needs the pattern derived from the builder's own output, which nobody proposed. Worse, my literal had the failure mode I was avoiding, pointing the other way: a pinned 'sudo' 'systemctl' 'enable' '--now' is a THIRD authoring of facts two extdeps modules already own, and it rotted the moment activation routed through systemctl_enable_now_command -- which is why the row was red at all. Repinning it buys one green run and re-arms the trap. #9031 derives what an authority owns and leaves 'enable' and '--now' literal, because those are systemctl's own operands that the builder spells inline and no row owns. That is the general line and it is better than what I wrote. WHAT REMAINS IS THE HALF NOTHING ELSE CARRIES. The installer witness rendered RunnerCommandRefused as "" and then pattern-matched the empty string, so a REFUSAL and a WRONG RENDER produced the same false with opposite repairs -- the not-applicable-versus-malformed conflation. The assertions now run inside the Ready arm and the refusal arm returns false on its own. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014oG2tMMAxgZeAQxDjvNsFm * Revert "Remove trailing whitespace from expected-red roster" This reverts commit 0279359. * Revert "Merge remote-tracking branch 'origin/pr-9020' into session/swift-heron-558" This reverts commit fedaca4, reversing changes made to 7981ec6. * Name the no-brace parser retry debt * Reconcile expected-red liveness authority * The 57s qualified-spelling claim is a whole-tree policy resolve, not name resolution The floor line that opened this (qualified_spelling_takes_the_shared_layer, wall_ms=57337, +1.22GB, bare arm free) reads as "qualified-name resolution is expensive". It is not. Qualified resolution is a map_get. Measured, four orderings plus a discriminating control: a qualified PATTERN HEAD costs nothing, and the premium lands on whichever claim first compiles a qualified TYPE ANNOTATION -- once per process, then 5ms forever after. The mechanism is severity classification, not resolution. A qualified annotation's authored name misses env.source_visible_names (which carries the bare imported names), so the masked type-ref arm emits an advisory UnlistedImportUse. Classifying that one diagnostic calls compile_clean_unlisted_import_use_blocks_from_policy, which resolves and typechecks a whole separate entry closure over default_source_roots() -- the whole tree -- to evaluate one nullary Bool. A bare annotation emits no such diagnostic and skips it; a qualified pattern head never enters that arm. This is gunbc.ci_spec's already-documented cost B from 2026-07-25, whose dissolve-on (scope the policy resolve to the policy module's own import closure) was never discharged. That note measured 57.8s for a green compile paying this tail against the floor's 57337ms. Shape, answering the brief: constant per process, independent of the subject compiled, and corpus-denominated. Same probe, roots varied: 216ms warm against 44886ms when from_policy's whole-tree root set diverges from the caller's and pays a cold load -- 44.9s locally against 57.3s on the floor. Diagnosis only; no repair, and the 1.22GB is reported as consistent-with rather than measured, since the witness is quarantined and the floor line was not re-run. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Scope the compile-clean policy read to its own import closure, refusing rather than widening Discharges the cost-B half of gunbc.ci_spec gunbc_ci_floor_batch_clamp_note's dissolve-on, which has named this exact repair since 2026-07-25 and was never landed. No second row is filed beside it: the obligation is discharged in place, because landing the fix while leaving its obligation open would be two authorities for one fact. compile_clean_unlisted_import_use_blocks_from_policy resolved and typechecked an entry closure over default_source_roots() -- the whole tree -- to evaluate one nullary Bool. That is not merely oversized (the policy module has three imports); it is a function answering a question about the caller's world by consulting a different one, which is why it presents as cost but is correctness-shaped, and why "n is small here" was never available. It now assembles the policy entry's own import closure and resolves that explicit source set. Every arm that cannot produce the exact closure REFUSES with a located message naming the module and the path. There is deliberately no whole-tree fallback: that arm would restore today's cost, zero the deficit's frequency by construction, and make the widening unrankable ever after (DESIGN section 5). It is a new closure builder rather than a reuse of resolve_virtual_source_with_imports because that BFS silently SKIPS an unresolvable import -- a silent skip here would answer the policy question from a graph missing the module the answer depends on. MEASURED, same probe and orderings, all probes PASS so the narrowed closure still returns the policy Bool: roots dag only C first qualified 44886ms -> 109ms roots dag + src/v2 C first qualified 216ms -> 151ms The qualified/bare asymmetry is gone rather than reduced: on the cold root set the qualified arm is now CHEAPER than the bare one. RESIDUE, reported rather than absorbed: the bare arm's 12967ms on the dag-only root set did not move (12881ms). The bare arm pays it too, so it was never part of the qualified asymmetry and this repair does not touch it. NOT UPGRADED: the floor's 1.22GB is still unattributed by execution. If the memory line survives this repair that is a second defect to find, not one to absorb here. v1 freeze admission: PURPOSE test (operator ruling 2026-08-20) -- a defect repair on a path the required floor executes every run, not growth on a v1 surface for v1's own sake. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com> Co-authored-by: Brian Searls <briansearls1@gmail.com> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
briansrls
added a commit
that referenced
this pull request
Aug 24, 2026
… break reached main and no gate could see it (#9035) * Main emission is refusing on a trailing annotation, and CI cannot see it `gunbc compile --entry src/v2/compiler/03_ingest.dag` REFUSES on current main (faf6583) with `EMIT_REFUSE` and no cargo log at all. Measured this morning at 907f19c the same entry emitted 177 files and 316 coded errors, so the board's subject stopped being producible at some point in today's merges. The cause is one file. §4c admits an annotation only as a standalone leading `//` block attached to a module-scope declaration; #8919 left a 62-line block at end-of-file with no item following it, and the compiler correctly refuses every span of it -- "source annotation names no subject: no module item follows it". A corpus-wide scan finds exactly one such file, so the population is closed. The repair moves the block above the file's final declaration. Every annotation line is preserved verbatim (diff of sorted `//` lines is one added `//` separator); no prose is rewritten, dropped, or summarised, because a block deleted for one reason takes everything in it unless its contents are enumerated first. WHAT THIS SAYS ABOUT THE GATE, which matters more than the fix. This is the SECOND instance of this class today: #8976 landed an indented `//` inside a match arm this morning and broke the floor corpus-wide for 74 minutes. That one was caught because the file was floor-enrolled. THIS one sits in dag/test/manual/, which no required phase parses -- the required run's three phases are the src/v1 `.dag` parse sweep, required-regen, and the witness floor, and none of them compiles a v2 entry. So an emission-breaking change landed on main and every gate stayed green. RUNG, honestly: this change is a repair of one instance and NOT a climb. The class remains writable and undetected. Its next-rung trigger is a required phase that compiles at least one v2 entry -- the emission path has no gate at all today, which is why the only instrument that found this was a hand-run probe. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Convert the one ArgvCommand site the seal missed, through a builder rather than by widening the seal main does not compile. `extdeps.exec.command` `ArgvCommand` became `sole_constructor { program, arguments }` in #8919, and its carrier states the invariant: "Every ArgvCommand construction site in the corpus was converted in the same change, because a partial seal is a dual-authority interval rather than a weaker seal." One site was not. `gunbc.runner_slot_provision` `observe_runner_slot_members_wet` still built `ArgvCommand { argv: ["ls", "-1", actions_runner_base_dir] }`, producing four distinct diagnostics and refusing the floor at strict-preparation — so no witness ran and no `required-floor` counter line was emitted at all. Not a missed conversion by that PR. #8992 ADDED this site after #8919 was authored and before it merged; neither touched the other's lines, so git merged both without a conflict and the corpus broke on semantics. A clean merge is not coherence. WHAT WAS DELIBERATELY NOT DONE: `runner_slot_provision` is not added to `argv_command`'s `admit_callers`. That list is forty named builders, each for ONE operation of ONE tool, homed in that tool's own extdeps module; admitting a product module would defeat the wall rather than satisfy it. A MODELED ALTERNATIVE WAS LOOKED FOR FIRST and does not exist at this layer. `ls -1 | parse` is a shell-ism, so the right first question was whether the substrate already answers "what entries are under this path" without shelling out. `dag/extdeps/filesystem` carries posix `EntryKind` but no listing operation, and the `list_dir` in `src/v2/extdeps/file_system.dag` is the v2 realization surface, not reachable from a v1-era `wet` observation running over `LocalExec`. So the builder is authored rather than the listing being re-modeled, and the call site keeps enumerating BY DIRECTORY — which its own carrier requires, since probing the desired names could only ever return a subset of what was already intended and would make an out-of-band slot invisible. `-1` is baked into the builder with its reason, following `rm_force_command`'s precedent: ls(1) columnates to a terminal and emits one-per-line to a pipe, so a caller that does not pass `-1` depends on where its output happens to go. It does not recurse and does not include dotfiles; a caller needing either needs its own name, not a flags parameter. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Enrolled-but-never-planned is not a parking spot: it refuses the whole floor The ArgvCommand repair in this branch unmasked a second main-red defect that had never been observed, because every run since it landed died at strict preparation before the fold could reach it. gunbc#9022 enrolled three compile_accepted_unevaluable_program_control identities in the expected-red roster while their file declares ReadsLiveTree, so the DeclinedLiveTree arm declines them (declined_live=899) and they are never planned. The floor requires every ENROLLED identity to be observed among the EXECUTED claims, so the run refuses with cause=ExpectedRedIdentityDidNotExecute count=3. Chunk 21's own annotation states the opposite belief -- "until it lands they are held here so that admission does not red main" -- and execution refutes it twice: on #9022's own run 32644795043, which was merged red, and again on run 32649496046 here, where it was the sole floor refusal once the seal stopped masking it. The precondition that enrolment was authored against has not landed: gunbc#8977 and gunbc#8982, which delete the decline arm, are both still open. The rows are correct and stay in chunk 21. Only their LIVENESS is wrong, so they join the file's existing exclusion in floor_expected_red_is_live -- the mechanism already used for the mock-totality family -- which keeps the rows for provenance while removing them from the live roster. Verified by execution, not by reading the predicate: each of the three returns excluded (exit 1) through --claim-run, and an arbitrary unrelated identity returns live (exit 0), so the predicate discriminates rather than excluding everything. The exclusion is a coupling, not a note: whoever lands #8977 or #8982 must delete these three exclusions in the same change, or the rows will execute while excluded, count as ordinary failures, and red the build. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * A v2-emission phase behind its own entry point: one entry compiled, refusing only where no tree comes out The 2026-08-23 break: `gunbc compile --source-root dag --source-root src/v2 --entry src/v2/compiler/03_ingest.dag` refused outright on main for hours while every required phase stayed green. The required run parses src/v1 .dag, compares the regen mirrors and folds the witness floor; none of the three compiles a v2 entry, so the emission path had no observer. The specimen was a trailing `//` annotation block with no declaration after it, authored under dag/test/manual/, which no required phase reads either. `claim_executor --required-v2-emission` compiles the entries named by `gunbc.ci_layer_roots` `required_v2_emission_entries` and stops the line on the compiler's own refusal authority (`v1_compiler_compile` `stage0_self_compile_refusal_message`) — a blocking diagnostic, or an empty emitted file set. Advisory diagnostics are counted and never refused on: 03_ingest carries 503 of them today, so a gate on any diagnostic would be permanently red. `--required-v2-emission-selftest` is the phase's executing evidence: two controlled fixture roots differing in one thing, the red one carrying the real specimen and the green one the same block moved above its declaration. Red must refuse on the annotation cause; green must emit. Mutation-confirmed — moving the red block above a declaration makes the selftest FAIL. NOT enrolled in `--required-ci` or witnesses.yml: changing what every PR must pass is an operator decision, and the enrolment question goes up with its measured cost attached. * The srv4 activation witness re-spelled two programs the seal then moved Third blocker on main, and the first one visible only after the other two cleared: with preparation passing and the roster refusal gone, the fold reaches this row and it returns false. FAIL test.claim.runner_host_deploy.srv4_enables_its_declared_runner_instances The cause is one conjunct, and it is not the width axis this row is otherwise about: && string_contains(s: enable, pattern: "'sudo' 'systemctl' 'enable' '--now'") That was correct against the hand-built argv the row was written for. #8919 routed runner_enable_command_argv through extdeps.systemd.systemctl systemctl_enable_now_command, which mints through the sealed argv_command with sudo_binary_path (/usr/bin/sudo) as the program and inserts sudo's non-interactive flag -- so the rendered prefix is no longer the four words the pattern names, and #8919 updated two lines of this file without reaching this one. WHAT I CHECKED BEFORE CHANGING ANYTHING, because a witness edited to match the code it guards is worse than a red one. Quoting was the obvious suspect and it is NOT the cause: shell_quote single-quotes unconditionally (emit_test's shell_quote(arg: "plain") == "'plain'" pins it), so the unit-name conjuncts still match. Admission was the other suspect and it is not the cause either: the fixture receipts bind correctly on every arm admit_runner_activation checks -- instance host, managed_unit against intended_unit, all six verified flags, pool host, and slice_unit against intended_compile_pool -- so the command is READY and `enable` is a real render rather than the refusal arm's "". THE REPAIR CITES RATHER THAN RE-SPELLS. The old pattern was a third authoring of facts extdeps.sudo.elevation and extdeps.systemd.systemctl already own, which is why it rotted without anyone touching it (DESIGN section 3). The conjunct is now two, deriving the program spellings from those authorities and split because they assert different things: that activation ELEVATES NON-INTERACTIVELY, and that it reaches systemctl's ENABLE --NOW. WHY THIS IS NOT measure() == measure(). `enable` and `--now` stay literal, and they are the discriminating half: they are systemctl's own operands, spelled inline by the builder rather than read from any row, so a command that carried the units without the verb still fails here. What the derived halves buy is that a future re-homing of the sudo or systemctl spelling moves the assertion with the authority instead of leaving a fourth copy to rot. Not verified locally: the same stale-binary limit recorded on the previous commit applies. CI is the authority. * One emission producer for the board and the gate, a three-state disposition, and enrolment as a required phase Finding 1 (the gate must consume the same producer as the board): it did not. The phase was a second caller reproducing the closure load, the census assembly, the refusal check and the silent-pick gate beside `gunbc compile`'s — and had already drifted on one of the three parameters, resolving under the strict pool index where the board runs primary-precedence. The transaction now lives in `cli_run` `compile_entry_emission`, and BOTH the CLI's `--entry` single-target arm and the required phase call it. Verified by execution that the CLI path is unchanged: abi 4/3847/9, and the board's own invocation on 03_ingest emits 177 by the `compiled:` line with 0 blocking / 503 advisory, exit 0. Finding 2 (a preparation refusal must not render as emitted=0 blocking=0): `Option<refusal>` was a two-state carrier expressing three. `EntryEmissionDisposition` is now Completed / Refused { phase, cause } / NotExecuted { earlier_phase, cause }, the tag is ON the counts line, and the count fields read `n/a` — deliberately not 0 — on any path that never ran. All three arms confirmed by execution. The invariant is emission COMPLETED, never a file count: a legitimate compiler change may alter closure size, so `emitted == 177` would be a change detector. ENROLLED as required-ci phase 3, ordered ahead of the floor, on the relayed operator ruling. The phases stay independent — every one runs after an earlier failure — so this is report order, not an early prerequisite; making it one is a scheduling decision left to the operator with the number attached. Dissolution trigger carried on `gunbc.ci_layer_roots` `required_v2_emission_dissolution`. * Rewrite the standalone-entry-point comment that still said NOT ENROLLED, and name the enrolment authority beside the dissolution row The comment beside --required-v2-emission-selftest was written before the enrolment and survived the revision that added phase 3, so the diff carried prose asserting the phase is opt-in beside code making it required. Rewritten, not annotated: two accounts of one fact is what produced the contradiction. The ci_layer_roots row now states the enrolment authority separately from the dissolution condition — how the gate ends is not the admission that created it. * join is not a std.types export: the two derived patterns build with concat Preparation refused on the previous head with a single diagnostic -- runner_host_deploy_witness_test.dag:4:33: name 'join' not found in module 'std.types' -- so the import I added to carry the derived invocation patterns named a symbol that module does not export. The witness already builds every other composed pattern with concat and needs no import for it; the two new ones now do the same. This is my own defect from the previous commit, not new fallout: the repair it carries is unchanged, only its spelling of string concatenation. The stale-binary limit recorded there is exactly why it reached CI to be caught -- a local compile under a binary that predates the seal cannot answer questions about this tree. * Ground the selftest's expected refusal on the typed variant's message authority, not a spelled literal Review 55128 named the coupling: matching `cause.contains("source annotation names no subject")` is a second spelling of a sentence `std_source_annotation` `annotation_attachment_refusal_message` owns, and a rewording silently invalidates it. The expected sentence is now ASKED FOR from that authority, keyed on the typed variant `UnattachedAtScopeEnd` the fixture provokes, so a rewording moves both sides together. Confirmed by execution in both mutation directions: a legal red fixture fails with 'did not refuse', and a fixture refusing for an unrelated cause fails with the grounded sentence quoted in the message. * Restore an unrelated function my splice deleted, and build the module index once instead of twice TWO REVIEW ITEMS FROM review 55167, and the first is a defect in this PR rather than a suggestion. `declared_import_closure_live_paths` — a `#[cfg(feature = "test_hooks")]` host twin for the Class B declared-import controls — was DELETED BY ACCIDENT: the edit that inserted the emission transaction spliced over a region that ended past it, and nothing failed because it is behind a feature gate with no current caller. The review read it as intentional and rationalised it. It is restored verbatim; the diff against the merge base now removes zero lines. The second: `compile_entry_emission` built the source index twice — once inside `load_sources_for_entry_with_pool_index` and once for the census fill — parsing ~3,800 modules per invocation for the second copy. It now builds one `MultiEntryIndex` and hands it to both the closure loader and the census, which also removes the possibility that the two are computed against different populations. Strict routes through `process_shared_index` so a second `--entry` compile in one process is a cache hit. Behaviour identical by execution: abi still 4 closure / 3847 census / 9 emitted, selftest green. NO SPEEDUP IS CLAIMED — measured 134s against 126s before, inside this host's noise; the change stands on removing the duplicate parse and the second population, not on a number I did not observe. --------- Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> Co-authored-by: Brian Searls <briansearls1@gmail.com>
briansrls
added a commit
that referenced
this pull request
Aug 25, 2026
…red rounds (#9039) * Convert the one ArgvCommand site the seal missed, through a builder rather than by widening the seal main does not compile. `extdeps.exec.command` `ArgvCommand` became `sole_constructor { program, arguments }` in #8919, and its carrier states the invariant: "Every ArgvCommand construction site in the corpus was converted in the same change, because a partial seal is a dual-authority interval rather than a weaker seal." One site was not. `gunbc.runner_slot_provision` `observe_runner_slot_members_wet` still built `ArgvCommand { argv: ["ls", "-1", actions_runner_base_dir] }`, producing four distinct diagnostics and refusing the floor at strict-preparation — so no witness ran and no `required-floor` counter line was emitted at all. Not a missed conversion by that PR. #8992 ADDED this site after #8919 was authored and before it merged; neither touched the other's lines, so git merged both without a conflict and the corpus broke on semantics. A clean merge is not coherence. WHAT WAS DELIBERATELY NOT DONE: `runner_slot_provision` is not added to `argv_command`'s `admit_callers`. That list is forty named builders, each for ONE operation of ONE tool, homed in that tool's own extdeps module; admitting a product module would defeat the wall rather than satisfy it. A MODELED ALTERNATIVE WAS LOOKED FOR FIRST and does not exist at this layer. `ls -1 | parse` is a shell-ism, so the right first question was whether the substrate already answers "what entries are under this path" without shelling out. `dag/extdeps/filesystem` carries posix `EntryKind` but no listing operation, and the `list_dir` in `src/v2/extdeps/file_system.dag` is the v2 realization surface, not reachable from a v1-era `wet` observation running over `LocalExec`. So the builder is authored rather than the listing being re-modeled, and the call site keeps enumerating BY DIRECTORY — which its own carrier requires, since probing the desired names could only ever return a subset of what was already intended and would make an out-of-band slot invisible. `-1` is baked into the builder with its reason, following `rm_force_command`'s precedent: ls(1) columnates to a terminal and emits one-per-line to a pipe, so a caller that does not pass `-1` depends on where its output happens to go. It does not recurse and does not include dotfiles; a caller needing either needs its own name, not a flags parameter. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Enrolled-but-never-planned is not a parking spot: it refuses the whole floor The ArgvCommand repair in this branch unmasked a second main-red defect that had never been observed, because every run since it landed died at strict preparation before the fold could reach it. gunbc#9022 enrolled three compile_accepted_unevaluable_program_control identities in the expected-red roster while their file declares ReadsLiveTree, so the DeclinedLiveTree arm declines them (declined_live=899) and they are never planned. The floor requires every ENROLLED identity to be observed among the EXECUTED claims, so the run refuses with cause=ExpectedRedIdentityDidNotExecute count=3. Chunk 21's own annotation states the opposite belief -- "until it lands they are held here so that admission does not red main" -- and execution refutes it twice: on #9022's own run 32644795043, which was merged red, and again on run 32649496046 here, where it was the sole floor refusal once the seal stopped masking it. The precondition that enrolment was authored against has not landed: gunbc#8977 and gunbc#8982, which delete the decline arm, are both still open. The rows are correct and stay in chunk 21. Only their LIVENESS is wrong, so they join the file's existing exclusion in floor_expected_red_is_live -- the mechanism already used for the mock-totality family -- which keeps the rows for provenance while removing them from the live roster. Verified by execution, not by reading the predicate: each of the three returns excluded (exit 1) through --claim-run, and an arbitrary unrelated identity returns live (exit 0), so the predicate discriminates rather than excluding everything. The exclusion is a coupling, not a note: whoever lands #8977 or #8982 must delete these three exclusions in the same change, or the rows will execute while excluded, count as ordinary failures, and red the build. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * The srv4 activation witness re-spelled two programs the seal then moved Third blocker on main, and the first one visible only after the other two cleared: with preparation passing and the roster refusal gone, the fold reaches this row and it returns false. FAIL test.claim.runner_host_deploy.srv4_enables_its_declared_runner_instances The cause is one conjunct, and it is not the width axis this row is otherwise about: && string_contains(s: enable, pattern: "'sudo' 'systemctl' 'enable' '--now'") That was correct against the hand-built argv the row was written for. #8919 routed runner_enable_command_argv through extdeps.systemd.systemctl systemctl_enable_now_command, which mints through the sealed argv_command with sudo_binary_path (/usr/bin/sudo) as the program and inserts sudo's non-interactive flag -- so the rendered prefix is no longer the four words the pattern names, and #8919 updated two lines of this file without reaching this one. WHAT I CHECKED BEFORE CHANGING ANYTHING, because a witness edited to match the code it guards is worse than a red one. Quoting was the obvious suspect and it is NOT the cause: shell_quote single-quotes unconditionally (emit_test's shell_quote(arg: "plain") == "'plain'" pins it), so the unit-name conjuncts still match. Admission was the other suspect and it is not the cause either: the fixture receipts bind correctly on every arm admit_runner_activation checks -- instance host, managed_unit against intended_unit, all six verified flags, pool host, and slice_unit against intended_compile_pool -- so the command is READY and `enable` is a real render rather than the refusal arm's "". THE REPAIR CITES RATHER THAN RE-SPELLS. The old pattern was a third authoring of facts extdeps.sudo.elevation and extdeps.systemd.systemctl already own, which is why it rotted without anyone touching it (DESIGN section 3). The conjunct is now two, deriving the program spellings from those authorities and split because they assert different things: that activation ELEVATES NON-INTERACTIVELY, and that it reaches systemctl's ENABLE --NOW. WHY THIS IS NOT measure() == measure(). `enable` and `--now` stay literal, and they are the discriminating half: they are systemctl's own operands, spelled inline by the builder rather than read from any row, so a command that carried the units without the verb still fails here. What the derived halves buy is that a future re-homing of the sudo or systemctl spelling moves the assertion with the authority instead of leaving a fourth copy to rot. Not verified locally: the same stale-binary limit recorded on the previous commit applies. CI is the authority. * join is not a std.types export: the two derived patterns build with concat Preparation refused on the previous head with a single diagnostic -- runner_host_deploy_witness_test.dag:4:33: name 'join' not found in module 'std.types' -- so the import I added to carry the derived invocation patterns named a symbol that module does not export. The witness already builds every other composed pattern with concat and needs no import for it; the two new ones now do the same. This is my own defect from the previous commit, not new fallout: the repair it carries is unchanged, only its spelling of string concatenation. The stale-binary limit recorded there is exactly why it reached CI to be caught -- a local compile under a binary that predates the seal cannot answer questions about this tree. * Split the 143 runtime-errored enrolments by witness-loader eligibility, and import the 19 the bare closure can never reach The bare-reference closure that resolves an unimported bare name through the tree census is switched off for any file declaring an import line (cli_run build_both_closure_edge_index, source_declares_import_lines). Joined against the 143 live runtime-errored enrolments, 23 rows sit in files already past that gate, so no loader-side repair can reach them: 19 are reference rows whose missing name has exactly one declaring module, and this adds those imports. No roster row is removed: main refuses at preparation, so no witness has executed and unenrolling would be the stale-quarantine hazard the roster exists to surface. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Round 1 measured: unenrol the 8 that now pass, and clear the next frontier name for the 11 that advanced Required-floor run 32660721426 on this branch: known_red_runtime_errored 143 -> 135, known_red_now_passing=8. Those eight reported STALE-QUARANTINE — enrolled and PASSED — so they leave the roster by its own removal path, at exact identity grain, chunk structure otherwise untouched. The other eleven repaired rows advanced rather than flipped: their reported missing name changed, which is the first-failure frontier the floor reports. Round 2 imports the three successor names in the same three already-importing files. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Round 2 experiment: three import-less files, chosen to discriminate the bare-scan gate The 120 BARE rows cannot be diagnosed outside the floor: the per-entry loader resolves the R1 shape and PASSES the witness, the floor's prepared subject already contains every module, and a whole-tree gunbc run refuses rather than approximating the floor's subject. So the floor is the instrument and this is a bounded experiment, not a rollout — three files varying in how many OTHER ambient names lose their census-derived pull when the file crosses the gate. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Round 2 measured: 24 more unenrolled, and the BARE-file hazard retired by measurement Required-floor run 32664512304 at 42d0a85: known_red_runtime_errored 135 -> 111, known_red_now_passing=24, failed=0, planned==executed==terminal==10693. All 17 rows in the three import-less experiment files flipped to PASS with nothing else in those files regressing, so the bare-scan gate hazard this lane raised does not bite for them — measured, not argued. The seven round-1 frontier rows flipped too. All 24 reported STALE-QUARANTINE and are removed at identity grain: roster 195 -> 171. Three runtime_axis rows advanced a third time (cost_is_lowerable -> type_decls_anti_unify), imported here. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Round 3: import the 90 resolvable rows of the remaining 111, in one batch 48 files, 70 imports. Each name has exactly one declaring module the referring file does not import; three were decided by the consuming field's type rather than by uniqueness, because the name is corpus-ambiguous and the census resolves that silently (Dag -> v2.lens.fact_cardinality, SourceFile -> v2.std.artifact x2). Batched rather than trickled because round 2 retired the bare-scan hazard by measurement and the fold is the check: every row still executes and a repair that breaks a sibling shows up as a named failure, not a silent pass. The 21 rows left are not reference failures — atom_identity_hash arity (12), the render lexical-shadowing defect, .raw on Int (2), a divergent fixture, and three runtime_axis rows already imported. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Record why the import is the right fix independent of the roster, and pin each round to its run Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Round 3 measured: 111 -> 21, unenrol the 88, and repair the last two reference-shaped rows Run 32667349586 at 7026838: known_red_now_passing=88, known_red_budget_refused=2, known_red_runtime_errored=21 — 88+2+21=111, no remainder. failed=0, so the 70-import batch broke no sibling. Roster 171 -> 83, deletions only. Two rows moved from runtime-errored to BUDGET-REFUSED at 5001/5003ms against 5000ms. They stay enrolled: the witness previously threw before doing its work and now runs it, so this is a real cost debt the repair surfaced, not a regression to absorb. Repaired here: sigma_families_of_defs (the runtime_axis file's fourth successive frontier name) and LocalAccelerator, fixed in dag/gunbc/accelerator_demo_plan.dag where the bare value-position reference is, not in the two witness files that call into it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Round 4 measured: 21 -> 15, the reference class is drained Run 32671448306 at eee5a43: known_red_now_passing=7, known_red_runtime_errored=15, failed=0. Removed: the three runtime_axis rows, the two accelerator_demo rows, and the two generated_coproduct_exhaustiveness rows whose round-3 budget refusal is now discharged rather than re-classified. Roster 81 -> 74. 143 -> 15 in four rounds, 127 identities unenrolled, each because a run observed it passing and it named itself. The 15 left are three non-reference roots: the Atom.identity type hole (12), the corpus-ambiguous Hit (2), and the eval_call lexical-tier gap (1). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: Brian Searls <briansearls1@gmail.com> Co-authored-by: Brian Searls <11205878+briansrls@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Required-floor run 32633501354 (main, head 907f19c) reports
known_red_runtime_errored=164: programs the compiler ACCEPTED and the
interpreter could not evaluate. That counter is the class's only observer and
it falls to zero as the witnesses are repaired — gunbc#9006 is repairing 21 of
them right now — so the evidence had to stop living in the specimens.
The partition, its producer, and the per-identity rows are
docs/plans/receipts/floor-runtime-error-partition-2026-08-23/. Five causal
families; the reference-unavailable subset is 149 of the 164 and every one of
its names IS declared somewhere in the corpus — the undeclared-anywhere class
is EMPTY, so intended compile state never separates on the name not existing.
It separates on where the declaration lives: 126 identities reference a
module-scope
datain an unimported module, 9 a bare variant or type name, 8a
fn, 5 atest datain another test file, 1 a type in call position.WHAT LANDS AS A FIXTURE: HOST-PRIMITIVE-CONTRACT, 11 of the 164. Measured on
compile_dag_rust_emit_check at this head, a host primitive's argument list is
unchecked at compile in every direction — two arguments, zero arguments, and
one argument of the wrong type all compile clean, and the host arm then refuses
each at evaluation with
requires exactly one string argument. Three REDsassert the refusal belongs at compile; three positive controls (clean compiles,
broken refuses, the CORRECT one-string call still compiles) make each RED
discriminating rather than a blanket claim. All six measured by execution:
controls true, REDs false. The three are enrolled in floor_expected_red so the
day the contract is checked they PASS and red the build naming themselves.
WHAT DOES NOT LAND, as a measurement rather than an omission: no fixture for
the 149. Both .dag-callable compile-observation surfaces REFUSE that shape
(compile_dag_rust_emit_check false, compile_diagnostic_census blocking) while
the floor's own witness loader ACCEPTS it, because that loader runs
extend_with_bare_reference_closure and resolves the name through the tree
census. A fixture on either surface would be permanently green and cited as
coverage of a class it never touches. Its next-rung trigger is a
compile-observation surface resolving names by the witness loader's rule.
Discriminating control for that claim, executed both ways: a source calling
argument_form_is_valid(design_argument)with no imports compiles silent andthrows NoSuchFunction at evaluation; the identical source with
import gunbc.design_argument { design_argument }compiles and evaluates true.The import is the whole discriminator and the compiler says nothing about it.
Enrolment verified by execution: roster length 203, the identity present once.
Co-Authored-By: Claude Opus 5 (1M context) noreply@anthropic.com
🤖 Generated with Claude Code