Repository navigation
Salvage the one orphaned row from gunbc#10292: a trigger that names a route while the capability stays dead - #10320
gunbai-bot[bot] wants to merge 20 commits into
Conversation
…plit roster gunbc#10292 reads as a stale duplicate of the gunbc#10206 carrier split and it is not one. Its branch forked at cb0ec47, so it carries its own copy of the split alongside three later commits, and a diff against main scores the whole thing as behind. THREE OF ITS FOUR AMENDMENTS HAVE SINCE LANDED BY OTHER ROUTES and are deliberately not re-applied here, each checked against main rather than assumed: - the `accepted_source_emits_uncompilable_target` scope sentence and the `check_subject_narrower_than_its_declared_claim` refutation sentence are both present on main, inside receipts that have since grown further -- taking the branch's shorter form would DELETE a seventh and an eighth form; - the `namespace_wave_admission` dissolution record for the split's two admission rows is on main as NINETEENTH TRANSITION; the branch spells it TWENTIETH only because that branch carries an extra cohort; - and the branch's `recurring_failure_mode` preamble is the pre-review wording that called the receipts TYPED and the drift UNWRITABLE. Main's says SEVERABLE, NOT TYPED and names the open section 4c classification gap. That is a rung honesty repair, so restoring the branch text would be a section 4b(1) inflation committed inside the file that warns against it. WHAT IS ACTUALLY ORPHANED IS ONE ROW, and it is a measured specimen rather than a restatement of doctrine: `trigger_names_route_while_capability_remains_dead`. Its subject is `v2.workflow.floor_expected_red` chunk_23, whose removal trigger named `container_element_nominal_brand_mismatch` REACHING the direct-call-argument position -- a route that was already present on main while the capability it was supposed to restore was still dead, so the calibrated generic-container mismatch compiled clean. Section 4b(3) states the hazard; this row is the tree observation of it, and it bounds itself against both neighbours it could be confused with. Every symbol the row cites was re-checked as resolving on main today, and the one sentence with no symbol at all was amended: the permanent-witness claim now names `test.claim.record_literal_call_arg_handoff_witness_test` `record_literal_container_element_mismatch_at_call_arg_still_refuses`, which is the assertion that counts blocking DeclaredTypeNotInhabited rows at the generic type argument position, rather than saying "the permanent witness" and leaving a reader to find it. Section 3 cites the symbol. docs/design-failure-modes.md is the projection, two lines: the preamble identity and the row body. The generator is the adjudicator on the required lane; the projection function was reproduced byte-for-byte against an already-committed row before deriving this one, so a drift red would be a real disagreement and not a formatting guess. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FSjamJZnktJ59XsarNLyeH
# Conflicts: # dag/gunbc/recurring_failure_mode/roster.dag # docs/design-failure-modes.md
# Conflicts: # dag/gunbc/recurring_failure_mode/roster.dag # docs/design-failure-modes.md
# Conflicts: # docs/design-failure-modes.md
briansrls
left a comment
There was a problem hiding this comment.
APPROVE at exact head fe18dd3a2c7aed0598cb68d3b95a49d0bfc070fe, reviewed against main@5d3be34278b26752144a20ba7e0df0c055beffd2.
The exact diff is one new recurring-failure row, one terminal import/list append, and its regenerated projection; no unrelated source change. The historical premise is corroborated by #10226: the named trigger became true for one loss subject while the broader invalid state remained authorable, so subject-bound retirement is the right class.
REST check-runs are fully terminal on this exact SHA: six success and one declared skip, including successful required-witnesses, required-witnesses-build, required-witnesses-floor, and heal-generated-artifacts. The qualified generated-artifact control refuses and the candidate is driver-clean against the named main snapshot.
The head trails current main by three commits, but all three are outside the recurring-failure row type, roster, and projection authority; they do not create a semantic composition gap for this cut. Main's 95-row population plus this unique terminal append yields the expected 96-row authority/projection population.
No request changes. Non-blocking body correction: the prose says “three amendments” immediately before a table containing four.
…ells it The row cited `test.claim.record_literal_call_arg_handoff_witness_test`. No such module exists. The file dag/test/claim/record_literal_call_arg_handoff_witness_test.dag declares `test.claim.record_literal_call_arg_handoff_witness` -- the basename carries `_test`, the module tail does not. WHY IT PASSED EVERY CHECK I RAN. The function is real and at that path, the file is real, and a receipt is a String no resolver ever reads -- so the symbol greps, the file opens and the .dag compiles. It fails in exactly one way: a reader who looks up the module as written finds nothing, which is the failure DESIGN section 3's cite-the-symbol rule exists to prevent. A stale line number decays when lines move; this identity was never live. THE NAME IS NOT DERIVABLE FROM THE FILENAME IN EITHER DIRECTION. Of the 1186 dag/test/claim/*_test.dag files, 749 declare a module tail that DROPS `_test`, 322 KEEP it, and 115 do neither -- so guessing is right about two times in three, which is the rate that trains the habit without ever exposing it. Line 1 of the file is the only authority. Checked, not assumed: every backticked dotted identifier in this row is now matched against the corpus module list (`git grep -h '^module ' -- '*.dag'`). All three resolve -- test.claim.record_literal_call_arg_handoff_witness, v1.compiler.infer, v2.workflow.floor_expected_red. The sentence is unchanged; only the name in it was wrong. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FSjamJZnktJ59XsarNLyeH
# Conflicts: # dag/gunbc/recurring_failure_mode/roster.dag # docs/design-failure-modes.md
briansrls
left a comment
There was a problem hiding this comment.
APPROVE the source at exact head ffc8e0a053214df37793d668c05a828d988fab90, reviewed against main@6ef6a566cc14680e0359714e8abaf3e9a85a4dd9.
This supersedes my approval at fe18dd3a2c7. That head was not merely moved: it cited test.claim.record_literal_call_arg_handoff_witness_test, which is a filename-shaped name and not the module's declared identity. Commit 8038c42420a repairs the row to test.claim.record_literal_call_arg_handoff_witness; the named function exists there. The terminal merge commit then incorporates current main and resolves the roster/projection composition. The live diff remains the narrow cut: one 36-line recurring-failure row, one import/list append, and its two-line generated projection.
SOURCE VERDICT: APPROVE. MERGE ADMISSION: WITHHELD until the restarted check suite on this exact SHA is terminal with the required successes/declared skip and the head remains unchanged. GitHub currently reports the PR mergeable against the named base, but the exact-head substantive lanes are still running or queued.
Non-blocking body corrections: the PR body still uses the filename-shaped module identity with _test, and says “three amendments” immediately before a four-row table.
# Conflicts: # docs/design-failure-modes.md
…t the rung above codex review 59889 is right and it is a blocking defect: the row declared "CEILING: 3 (mechanically preventable)", and DESIGN.md section 4b numbers those differently -- 2 is mechanically preventable, 3 is structurally guaranteed. A row whose whole subject is a grain mismatch between a stated loss and its trigger carried a grain mismatch between its own ceiling's number and its name. THE NUMBER WAS RIGHT AND THE NAME WAS WRONG, established from the mechanism the row already described rather than by picking the safer digit. "Triggers and losses become typed references to the same capability identity" is a refusal the compiler derives from modeled structure, which is section 4b's rung 3 -- not a gate that must execute and stay enrolled, which is rung 2. AND THE ROW NOW DERIVES WHY IT IS NOT 4, because "could this be structurally impossible" is the question a corrected ceiling invites and leaving it unanswered is how the next reader re-opens it. Section 4b(1) reads a class's rung as the MINIMUM across its in-scope parts. The subject-mismatch half could reach 4: typed at one grain, a trigger naming a route has no constructor. The other half cannot, because retirement also requires the capability's discriminating witness to HOLD at its named position, and a witness holding is executed evidence rather than a constructor. The ceiling is the weaker of the two, and claiming 4 would be the rung inflation this ladder exists to name. Projection regenerated as a UNION rather than resolved to a side: main's content (#10282's amendment among it) plus this row's new body. Verified at both halves rather than by confirming my own row came back -- membership join 97/97 MISSING=0 order-equal, and the authority diff against main shows only this row file and the two roster lines, so every other row is byte-identical to main. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FSjamJZnktJ59XsarNLyeH
briansrls
left a comment
There was a problem hiding this comment.
APPROVE the source at exact head beba8442bb6d78a8afd14e3a2553e436c4598ebc.
The rung correction is substantive and correct. The row now says CEILING: 3 (structurally guaranteed), matching DESIGN 4b's numbering and the mechanism it describes: the subject-grain mismatch is rejected from modeled structure rather than by a detector that must remain enrolled. The explanation for not claiming rung 4 is also honest under the declared construction: retirement still depends on the discriminating witness holding at the named position, so the class minimum remains the execution-dependent half rather than the unconstructible identity-mismatch half.
The live diff remains the intended three-path cut: one new row, one import/list append, and its generated projection. GitHub reports 42 inserted lines on this head (38 in the row plus 2 roster plus 2 projection), so the separately reported +40 should not be used as a Git line-count receipt.
This is SOURCE APPROVAL only. Exact-head CI is nonterminal, and final composition must be computed from pinned current main and this unchanged head with the qualified merge-tree/driver oracle. Do not merge main into the branch merely because main moves while it waits.
# Conflicts: # dag/gunbc/recurring_failure_mode/roster.dag # docs/design-failure-modes.md
# Conflicts: # docs/design-failure-modes.md
# Conflicts: # dag/gunbc/recurring_failure_mode/roster.dag # docs/design-failure-modes.md
…ed route
The generated-artifact driver refused docs/design-failure-modes.md
(GeneratedArtifactConcurrentDivergence) because both sides changed the
projection since the merge base. Resolved by its own declared repair route
rather than by local re-derivation, which that route explicitly forbids:
1. took the merged-in side's projection verbatim, staging none of the ours
bytes the driver leaves in the worktree
2. verified BY SET DIFFERENCE, not by count, that no row main carried went
dark: the difference is empty
3. read the index stages rather than counting conflict markers — zero
markers is what this driver guarantees on a refusal, so a marker count
reports that the driver worked, never that its subject is intact
The carrier merged cleanly and is self-consistent at 101 rows, with imports,
roster list and file set in three-way agreement, no duplicates. The projection
carries 100. The sole authority-ahead-of-artifact drift is this branch's own
row, which is the one thing heal-generated-artifacts must derive from the
merged authorities.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FSjamJZnktJ59XsarNLyeH
…declared route heal-generated-artifacts pushed 31e04b5 regenerating the projection with this branch's row, so this merge is built on the healed head rather than over it. Main then moved to 7893241, making both lease paths two-sided. roster.dag: unioned both regions -- import block and list -- main's entries first, this branch's last, preserving each side's bytes. This branch was NOT a superset: it absorbs five rows main added (by_name_evaluation_is_a_string_not_a_binding, discriminating_arm_built_but_never_enrolled, policy_mechanism_adjudicates_the_merge_that_supersedes_it, reachability_answered_is_consumed_as_protection_established, verification_bound_to_the_revision_it_started_on). Union is admissible at semantic grain: none of the five is a claim about a trigger naming a route while the capability stays dead, so they are different obligations rather than an independently authored record of one event. docs/design-failure-modes.md: the generated-artifact driver's declared route -- take the merged-in side verbatim, verify by set difference that no row went dark (empty), and let heal derive from the merged authority. Not hand-resolved. Verified: imports order == list order, set(list) == file set, 106/106/106, no duplicates, all six rows present in BOTH halves. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FSjamJZnktJ59XsarNLyeH
…d route Main moved to c52fe5d (#10350), which filed two failure-mode rows from outside this branch's component, making both lease paths two-sided. roster.dag auto-merged. docs/design-failure-modes.md was refused by the generated-artifact driver and resolved by its declared route: merged-in side verbatim, no local regeneration, verified by set difference in both directions rather than by count. Verified against expectations stated before measuring: main's rows minus this branch's is empty (both dispatch_correctness_resting_on_arm_order and located_refusal_renders_its_span_in_the_wrong_units present in carrier and projection), authority minus projection is exactly this branch's own row, imports order == list order, set(list) == file set, no duplicates, and no row main carried went dark. The head this supersedes, c3dd15c, went green 4/4 with heal terminating cleanly, so it stands as the control for attributing any red here. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FSjamJZnktJ59XsarNLyeH
…ign-failure-modes.md are contended by three open PRs The class is real and stands (a printed remedy mangled by the medium that prints it, whose failure arm is a vacuous PASS rather than a refusal), but filing it needs a row file AND an import/entry edit in gunbc.recurring_failure_mode.roster, plus the regenerated docs/design-failure-modes.md projection -- and #10317, #10320 and #10326 are open against exactly those two paths. Landing it here would put this branch into a driver-refused merge on the very projection whose repair recipe this branch is fixing. So the driver repair lands alone, touching no contended path. The row follows in its own change against whatever roster head survives those three. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BPNfohdhatLvf5HT9jK5k6
…ne of which reported a vacuous PASS (#10460) * The merge driver's repair recipes: one refuses, one is mangled by the echo that prints it, one never matched half its subject Three defects in gunbc.generated_artifact_merge_driver, all one class: a documented command that does not do what it says when run verbatim. 1. AuthorRegeneratesBeforeMerge step 3 ended `claim_executor --required-regen-fixed-point` with no --source-root. That binary's argument guard sits ABOVE the fixed-point branch, so the run exits 2 on `provide at least one --source-root` before reaching a mode that reads no roots at all -- which is why the omission looked harmless to write. It is the last command of the arm every generated artifact takes except the two heal-delegated rosters, so the author has paid two builds and two regen passes when it refuses. 2. The heal arm's set-difference command is written between backticks, and the driver echoes every recipe line inside DOUBLE quotes (they are templates; $merged_path must interpolate). Executed against the committed .githooks/generated-artifact-merge: bash ran the capture group as a command substitution -- two `([a-z0-9_]*): command not found` lines -- and printed the instruction as `sed -n 's/^- .*/\1/p'`, capture group deleted. Pasted, that extracts zero rows from both sides and the difference over two empty sets is empty, which the recipe's own words read as MUST BE EMPTY: the mangled remedy reports the vacuous pass the intact remedy exists to prevent. Escaping now happens in emit_driver_stderr_echo, where the quoting decision is made; it deliberately differs from gunbc.shell_bash_runner bash_escape_for_double_quotes on exactly one character ($), and that difference is named in the module rather than left to read as a fork. 3. The same command's row extractor only ever matched docs/design-failure-modes.md. The other delegated projection, docs/design-rung-drops.md, carries `### Title — declared ...` headings, not slug bullets: 105 rows extracted from one file, 0 from the other, so on the rung-drops path the check was green by construction. One extractor now names both row identities. Evidence: test.claim.generated_artifact_merge_driver_recipe reads the EMITTED script rather than the authored list -- the second defect is invisible in the authored string -- and refuses the unescaped form. gunbc.recurring_failure_mode.printed_remedy_is_mangled_by_the_medium_that _prints_it files the class, with its boundary against restoration_promise_names_a_route_that_does_not_exist (there the route does not exist; here it does, and the rendering is what breaks, so every by-name instrument agrees the remedy is present). No emitted artifact hand-edited. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BPNfohdhatLvf5HT9jK5k6 * Hold the failure-mode row out of this branch: roster.dag and docs/design-failure-modes.md are contended by three open PRs The class is real and stands (a printed remedy mangled by the medium that prints it, whose failure arm is a vacuous PASS rather than a refusal), but filing it needs a row file AND an import/entry edit in gunbc.recurring_failure_mode.roster, plus the regenerated docs/design-failure-modes.md projection -- and #10317, #10320 and #10326 are open against exactly those two paths. Landing it here would put this branch into a driver-refused merge on the very projection whose repair recipe this branch is fixing. So the driver repair lands alone, touching no contended path. The row follows in its own change against whatever roster head survives those three. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BPNfohdhatLvf5HT9jK5k6 * chore: regenerate drifted generated artifacts (ci auto-heal) * The extractor may not take $1: the driver's own argv was substituting into the instruction it printed Caught by simulating the emitter over the authored strings and RUNNING the result, which is the only reading that sees this class at all. The recipe had been drafted as `rows() { git show "$1:$merged_path" | ... }` -- and $ stays active in the emitted echo by construction, because $merged_path must interpolate. So $1 was git's %O placeholder, and the printed instruction read `git show "O:docs/design-rung-drops.md"`: an author pasting it would have asked git for a ref named O. Escaping does not save it either, since the escaper doubles backslashes before the reader sees them, so `\$1` prints as a backslash. The line now names $merged_path -- the one variable the driver defines -- and pipes into a parameterless function. Witnessed by heal_recipe_names_only_the_variable_the_driver_defines. EXECUTED, as rendered, against a real divergence (this branch's base vs origin/main, which is ahead by a landed roster PR): failure-modes base=112 head=105 and the difference NAMES the seven rows, rung-drops base=35 head=35 difference empty Seven named rows and a measured empty -- neither of which the recipe could produce before this branch, on either projection. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BPNfohdhatLvf5HT9jK5k6 * chore: regenerate drifted generated artifacts (ci auto-heal) * Dissolve the second escaper into the shared authority, and declare this carrier's medium on the carrier Answers review 60392 (codex/gpt-5.6-sol, REQUEST_CHANGES) on its two actionable points. THE SECOND QUOTING IMPLEMENTATION IS GONE, which was the fair half of the finding: I had authored an escaper beside gunbc.shell_bash_runner bash_escape_for_double_quotes, and one concept with two names is what DESIGN section 3 forbids -- the next fix lands in one of them. But the two callers genuinely disagree about exactly one character. A literal line must have its $ escaped or the shell expands a variable the author never wrote; a TEMPLATE line, which is what a recipe naming $merged_path is, must leave $ active or the instruction prints a dollar sign instead of the path. So the shared function is SPLIT rather than copied: bash_escape_double_quote_specials_except_expansion holds the identical part, bash_escape_for_double_quotes is now composed from it plus the $ arm, and this module calls the shared arm. Backslash-first is preserved and annotated as load-bearing, since every later arm introduces backslashes. Behaviourally inert, and checked rather than asserted: every emitted heal line reproduces the committed .githooks bytes exactly, so the projection does not move. The reordering ($ after backtick instead of before) is output-identical because no arm introduces a character a later arm escapes. THE MEDIUM DISPOSITION IS NOW DECLARED ON THIS CARRIER. A git merge driver is one of the foreign executors DESIGN's shell-to-intent routing names -- git runs it with no gunbc runtime present -- so bash is the emitted medium and the concat-built spelling is an interim one. That was true before this branch and unmarked, which is the reviewer's point. It is now gunbc.local_tidy_spec generated_artifact_merge_driver_emit_scaffold, a Scaffold binding expected_generated_artifact_merge_driver_sh with dissolves_to RealizationDispatch, plus a DissolutionCondition on the module. Stated here rather than inherited from the hook-emit family for the reason review 45175 gave the pre-push sibling: a family trigger tracked once lets each member inherit it implicitly. THE TRIGGER NAMES THE CAPABILITY, NOT THIS ARTIFACT. Emitting this one script through the grammar path would retire nothing; what retires the row is the bash medium modelled well enough that a line's variable references and shell-active characters are DECLARED rather than spelled. That is the same ceiling this module's defects establish -- every one of them was a rendering the author could not see in the authored string. Witnessed by emitted_driver_carries_a_bound_medium_disposition_with_a _capability_trigger: the Scaffold's bind must name the emitter, and the trigger must carry the capability clause. A Scaffold binding nothing marks nothing. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BPNfohdhatLvf5HT9jK5k6 * My own witness was written against the authored string, not the emitted bytes -- the exact mistake it exists to catch CI floor lane: two of the five witnesses returned Bool(false). They were mine and they were wrong, in the same way the defects they check are wrong. I asserted the emitted script contains s/^- `\([a-z0-9_]*\)`.*/\1/p which is the AUTHORED spelling. What the emitter actually produces is s/^- \`\\([a-z0-9_]*\\)\`.*/\\1/p because the escaping pass doubles backslashes as well as escaping backticks -- the backslash arm is the first thing it does, and I read past it while writing a check whose entire premise is that the rendering differs from the authored text. The witness was built on the wrong artifact, which is this module's own failure mode applied to its own evidence. Now asserted against the real bytes, and every assertion in the file was EXECUTED against the committed .githooks projection before pushing rather than reasoned about: seven string reads, four expecting present and three expecting absent, all agreeing. The RED control is unchanged in meaning -- the raw-backtick form `- `\([a-z0-9_]*` must be absent, and it is, because that is what the escaper prevents. Two notes on what this does NOT change. The production fix was always correct: heal-generated-artifacts passes, so the committed hook is the exact projection of the authority, and running it prints the extractor intact. And the build lane's failure is still not mine -- inherited stage0-mirror drift, which #10467 repairs. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BPNfohdhatLvf5HT9jK5k6 --------- Co-authored-by: Brian Searls <briansearls1@gmail.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>
…ect belongs to (#10505) * The merge driver's repair recipes: one refuses, one is mangled by the echo that prints it, one never matched half its subject Three defects in gunbc.generated_artifact_merge_driver, all one class: a documented command that does not do what it says when run verbatim. 1. AuthorRegeneratesBeforeMerge step 3 ended `claim_executor --required-regen-fixed-point` with no --source-root. That binary's argument guard sits ABOVE the fixed-point branch, so the run exits 2 on `provide at least one --source-root` before reaching a mode that reads no roots at all -- which is why the omission looked harmless to write. It is the last command of the arm every generated artifact takes except the two heal-delegated rosters, so the author has paid two builds and two regen passes when it refuses. 2. The heal arm's set-difference command is written between backticks, and the driver echoes every recipe line inside DOUBLE quotes (they are templates; $merged_path must interpolate). Executed against the committed .githooks/generated-artifact-merge: bash ran the capture group as a command substitution -- two `([a-z0-9_]*): command not found` lines -- and printed the instruction as `sed -n 's/^- .*/\1/p'`, capture group deleted. Pasted, that extracts zero rows from both sides and the difference over two empty sets is empty, which the recipe's own words read as MUST BE EMPTY: the mangled remedy reports the vacuous pass the intact remedy exists to prevent. Escaping now happens in emit_driver_stderr_echo, where the quoting decision is made; it deliberately differs from gunbc.shell_bash_runner bash_escape_for_double_quotes on exactly one character ($), and that difference is named in the module rather than left to read as a fork. 3. The same command's row extractor only ever matched docs/design-failure-modes.md. The other delegated projection, docs/design-rung-drops.md, carries `### Title — declared ...` headings, not slug bullets: 105 rows extracted from one file, 0 from the other, so on the rung-drops path the check was green by construction. One extractor now names both row identities. Evidence: test.claim.generated_artifact_merge_driver_recipe reads the EMITTED script rather than the authored list -- the second defect is invisible in the authored string -- and refuses the unescaped form. gunbc.recurring_failure_mode.printed_remedy_is_mangled_by_the_medium_that _prints_it files the class, with its boundary against restoration_promise_names_a_route_that_does_not_exist (there the route does not exist; here it does, and the rendering is what breaks, so every by-name instrument agrees the remedy is present). No emitted artifact hand-edited. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BPNfohdhatLvf5HT9jK5k6 * Hold the failure-mode row out of this branch: roster.dag and docs/design-failure-modes.md are contended by three open PRs The class is real and stands (a printed remedy mangled by the medium that prints it, whose failure arm is a vacuous PASS rather than a refusal), but filing it needs a row file AND an import/entry edit in gunbc.recurring_failure_mode.roster, plus the regenerated docs/design-failure-modes.md projection -- and #10317, #10320 and #10326 are open against exactly those two paths. Landing it here would put this branch into a driver-refused merge on the very projection whose repair recipe this branch is fixing. So the driver repair lands alone, touching no contended path. The row follows in its own change against whatever roster head survives those three. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BPNfohdhatLvf5HT9jK5k6 * chore: regenerate drifted generated artifacts (ci auto-heal) * The extractor may not take $1: the driver's own argv was substituting into the instruction it printed Caught by simulating the emitter over the authored strings and RUNNING the result, which is the only reading that sees this class at all. The recipe had been drafted as `rows() { git show "$1:$merged_path" | ... }` -- and $ stays active in the emitted echo by construction, because $merged_path must interpolate. So $1 was git's %O placeholder, and the printed instruction read `git show "O:docs/design-rung-drops.md"`: an author pasting it would have asked git for a ref named O. Escaping does not save it either, since the escaper doubles backslashes before the reader sees them, so `\$1` prints as a backslash. The line now names $merged_path -- the one variable the driver defines -- and pipes into a parameterless function. Witnessed by heal_recipe_names_only_the_variable_the_driver_defines. EXECUTED, as rendered, against a real divergence (this branch's base vs origin/main, which is ahead by a landed roster PR): failure-modes base=112 head=105 and the difference NAMES the seven rows, rung-drops base=35 head=35 difference empty Seven named rows and a measured empty -- neither of which the recipe could produce before this branch, on either projection. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BPNfohdhatLvf5HT9jK5k6 * chore: regenerate drifted generated artifacts (ci auto-heal) * Dissolve the second escaper into the shared authority, and declare this carrier's medium on the carrier Answers review 60392 (codex/gpt-5.6-sol, REQUEST_CHANGES) on its two actionable points. THE SECOND QUOTING IMPLEMENTATION IS GONE, which was the fair half of the finding: I had authored an escaper beside gunbc.shell_bash_runner bash_escape_for_double_quotes, and one concept with two names is what DESIGN section 3 forbids -- the next fix lands in one of them. But the two callers genuinely disagree about exactly one character. A literal line must have its $ escaped or the shell expands a variable the author never wrote; a TEMPLATE line, which is what a recipe naming $merged_path is, must leave $ active or the instruction prints a dollar sign instead of the path. So the shared function is SPLIT rather than copied: bash_escape_double_quote_specials_except_expansion holds the identical part, bash_escape_for_double_quotes is now composed from it plus the $ arm, and this module calls the shared arm. Backslash-first is preserved and annotated as load-bearing, since every later arm introduces backslashes. Behaviourally inert, and checked rather than asserted: every emitted heal line reproduces the committed .githooks bytes exactly, so the projection does not move. The reordering ($ after backtick instead of before) is output-identical because no arm introduces a character a later arm escapes. THE MEDIUM DISPOSITION IS NOW DECLARED ON THIS CARRIER. A git merge driver is one of the foreign executors DESIGN's shell-to-intent routing names -- git runs it with no gunbc runtime present -- so bash is the emitted medium and the concat-built spelling is an interim one. That was true before this branch and unmarked, which is the reviewer's point. It is now gunbc.local_tidy_spec generated_artifact_merge_driver_emit_scaffold, a Scaffold binding expected_generated_artifact_merge_driver_sh with dissolves_to RealizationDispatch, plus a DissolutionCondition on the module. Stated here rather than inherited from the hook-emit family for the reason review 45175 gave the pre-push sibling: a family trigger tracked once lets each member inherit it implicitly. THE TRIGGER NAMES THE CAPABILITY, NOT THIS ARTIFACT. Emitting this one script through the grammar path would retire nothing; what retires the row is the bash medium modelled well enough that a line's variable references and shell-active characters are DECLARED rather than spelled. That is the same ceiling this module's defects establish -- every one of them was a rendering the author could not see in the authored string. Witnessed by emitted_driver_carries_a_bound_medium_disposition_with_a _capability_trigger: the Scaffold's bind must name the emitter, and the trigger must carry the capability clause. A Scaffold binding nothing marks nothing. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BPNfohdhatLvf5HT9jK5k6 * My own witness was written against the authored string, not the emitted bytes -- the exact mistake it exists to catch CI floor lane: two of the five witnesses returned Bool(false). They were mine and they were wrong, in the same way the defects they check are wrong. I asserted the emitted script contains s/^- `\([a-z0-9_]*\)`.*/\1/p which is the AUTHORED spelling. What the emitter actually produces is s/^- \`\\([a-z0-9_]*\\)\`.*/\\1/p because the escaping pass doubles backslashes as well as escaping backticks -- the backslash arm is the first thing it does, and I read past it while writing a check whose entire premise is that the rendering differs from the authored text. The witness was built on the wrong artifact, which is this module's own failure mode applied to its own evidence. Now asserted against the real bytes, and every assertion in the file was EXECUTED against the committed .githooks projection before pushing rather than reasoned about: seven string reads, four expecting present and three expecting absent, all agreeing. The RED control is unchanged in meaning -- the raw-backtick form `- `\([a-z0-9_]*` must be absent, and it is, because that is what the escaper prevents. Two notes on what this does NOT change. The production fix was always correct: heal-generated-artifacts passes, so the committed hook is the exact projection of the authority, and running it prints the extractor intact. And the build lane's failure is still not mine -- inherited stage0-mirror drift, which #10467 repairs. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BPNfohdhatLvf5HT9jK5k6 * Execute the merge driver's printed recipe, do not read it test.claim.generated_artifact_merge_driver_recipe asserts over the EMITTED SCRIPT and says so in its own header: its reads "cannot claim the command RUNS", and it points at test.claim.generated_artifact_merge_driver_real_execution as the wet arm that would. That arm carried no recipe claim. This adds it. The two assertions are different claims and only the second is the one that matters. A string read over the emitted bytes proves an escape was APPLIED. It cannot distinguish a correct escape from a wrong one -- doubling the wrong character, or escaping $ and killing the $merged_path the driver defines, both produce escaped bytes and a recipe that still does not work. Reading what bash ACTUALLY PRINTED after expansion is what proves the program survived the medium. driver_printed_step_two_carries_the_dark_row_extraction_program drives a real refused merge and reads merged.stderr. dark_row_extraction_program_names_a_row_that_went_dark runs that same declaration through real sed over a fixture ledger and over the same ledger with one row removed. THE SECOND ASSERTS AN IDENTITY JOIN, NOT NON-EMPTINESS, and the fixture is built FROM gunbc.recurring_failure_mode roster rather than from a hand-written row list. Non-emptiness proves acquisition and nothing else: it catches the total-failure mode and passes identically at 1 extracted row, at 40, and at 119 of 120, while the check quietly ranges over a fraction of its subject. The fixture also reproduces the projection's two-bullet shape -- one index bullet and one prose bullet per row -- so a program matching every bullet reads twice the roster count and reds, and one matching none reads zero and reds. extdeps.tools.sed gains ScriptSuppressAutoPrint: sed -n with the script as an ARGUMENT, so a caller executing a program it received from somewhere else does not have that program re-read by a shell on the way in. stdout_lines rather than stdout, because an empty capture and a refusal are indistinguishable as one string -- which is the failure its first consumer exists to catch. Both functions are enrolled in ci_layer_roots bin_wet, floor_route_gap and local_repo_wet_terminal, so they execute rather than merely exist. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F8wZ8BQ3mXe4cSfqDJiWNj * Execute the merge driver's printed recipe, do not read it #10460 repaired the recipe and enrolled the evidence it could reach: test.claim.generated_artifact_merge_driver_recipe asserts over the EMITTED SCRIPT, and its own header says those reads "cannot claim the command RUNS", naming test.claim.generated_artifact_merge_driver_real_execution as the wet arm that would. That arm carried no recipe claim. This adds it, and lifts the extractor so there is one program to execute rather than a copy of one. A STRING READ PROVES AN ESCAPE WAS APPLIED; ONLY STDERR AFTER EXPANSION PROVES IT IS CORRECT. Doubling the wrong character, or escaping $ and killing the $merged_path the driver defines, both produce escaped bytes and a recipe that still does not work -- and both pass the emitted-bytes assert while failing driver_printed_step_two_carries_the_row_extractor, which drives a real refused merge and reads merged.stderr. THE SECOND TEST ASSERTS A COVERAGE JOIN, NOT NON-EMPTINESS, and that is this recipe's own history rather than a principle applied from outside. The hole #10460 found on docs/design-rung-drops.md was a correct program pointed at a row shape it could not match: it rendered perfectly, read zero of 36 rows, and reported a pass it never measured. Non-emptiness cannot see that -- it passes at one extracted row, at forty, and at all-but-one. So the fixture is built FROM gunbc.recurring_failure_mode roster and gunbc.rung_drop roster, carries BOTH row spellings, and requires the extraction to name every rostered row on both sides, with one row of each shape removed on the second side and required to be named by the first and not the second. Dropping either sed clause reds it. THE EXTRACTOR IS NOW ONE DECLARATION. The landed step 2 spells a rows() shell function with two sed -e clauses inside a prose sentence, so the printed program and any executed copy are two things that can drift. The expressions are lifted to generated_artifact_merge_driver_row_identity_extraction_expressions; the printed text is derived from them, the witness executes them, and the emitted bytes are unchanged -- .githooks/generated-artifact-merge is byte-identical to main. The -e pairing lives in extdeps.tools.sed beside the -i it already owned, and the single-quote wrapping is extdeps.posix.shell_command_language posix_single_quote rather than a literal quote pair. extdeps.tools.sed gains ScriptsSuppressAutoPrint: sed -n with its scripts as argv entries, so a caller executing a program it received from somewhere else does not have that program re-read by a shell on the way in. stdout_lines rather than stdout, because an empty capture and a refusal are indistinguishable as one string -- the failure its first consumer exists to catch. Both functions are enrolled in ci_layer_roots bin_wet, floor_route_gap and local_repo_wet_terminal, so they execute rather than merely exist. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F8wZ8BQ3mXe4cSfqDJiWNj * File the class the driver's own defect belongs to, and hoist an annotation out of a service block THE ROW. gunbc.recurring_failure_mode.printed_remedy_is_mangled_by_the_medium _that_prints_it. calm-owl-417 identified this class while repairing #10460 and deliberately held it out of that branch, because filing needs roster.dag AND the regenerated projection, both of which were moving under open PRs -- which would have put the branch into a driver-refused merge on the very projection whose recipe it was repairing. The follow-up never landed and the session ended, so the class existed only in a merged pull request body. Their 7a and 7c specimens are carried here as theirs, with that provenance on the carrier. Section 3's hazard is a second authority forking an existing one; there was no authority to fork. WHAT THE ROW CARRIES BEYOND THE TWO ORIGINAL SPECIMENS. The recognition rule: the sender sees intact text, the recipient gets a silently shortened sentence, and nothing reports a failure. Every instrument that reads the AUTHORED artifact agrees the remedy is present, because it is present. The disproportion, measured: an invalid backreference makes sed refuse the ENTIRE program, so mangling one character in the first clause silences a second clause nothing touched. Against a fixture carrying both row spellings and 157 rostered rows, the intact program names 157 and the mangled program names ZERO -- not 36, which is what per-clause degradation would predict. Two further specimens in a different medium, both in messages ABOUT this class: agent message bodies passed to a double-quoted shell argument, backquoted spans substituted away, recipients receiving sentences with phrases missing. One was a message whose subject was instruments that report success without carrying their claim; the other was sent by the author repairing the first specimen. THE MANGLING EXECUTES, WHICH IS THE PART THAT CHANGES THE CLASS. Found as physical residue: a message containing `-> Bool` inside double quotes ran `-` as a command and `> Bool` as a REDIRECTION, creating an empty file in the repository working tree. A fragment of English prose was evaluated as a program. The lossy reading is the benign one; a backquoted span is command substitution, which is arbitrary execution. It did not reach a commit because the last commit happened to precede it by fifteen minutes -- recording that as "it did not land" would be luck reported as safety, so the row records the ordering as the reason. The check that licenses, which found a different residue in a second tree on its first application: inspect git status for unexplained worktree changes after any session that has sent shell-quoted messages, and do not stage with `git add -A` there. Generalized past messages, because any command that writes into the worktree as a side effect of verification leaves residue a reviewer cannot distinguish from intent. Bounded against empty_capture_read_as_clean_result by the argument that decides it: a substituted positional argument is not an empty capture at all, so the medium is the root and the empty operand is one consequence. THE HOIST. extdeps.tools.sed carried its new operation's annotation INSIDE the service block. DESIGN section 4c admits standalone leading comment blocks on module-scope declarations only, so that was a parse error -- invisible in a diff, indistinguishable from ordinary corpus style, and caught only by running the compiler over it. Moved above the service block with the operation named in its first line. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F8wZ8BQ3mXe4cSfqDJiWNj * Enroll the positive control and both mutation controls: cited but unexecuted is the class this row files Answers review 60644 (claude/claude-opus-4-7, REQUEST_CHANGES), which is correct and finds an instance of the very failure this branch exists to close. WHAT HAPPENED, because the mechanism is worth naming rather than just fixing. The first version of this branch had two wet tests and enrolled both. Review feedback then asked for a stronger reconciliation, so three more landed -- an accepting positive control and the two count-preserving mutation controls that are the whole reason the reconciliation is three sets rather than one number. The enrollment rosters were never revisited. So the file grew from two executed claims to five claims of which two executed, and the new row's evidence list cited one of the three that did not. That is `discriminating_arm_built_but_never_enrolled`, and it is DESIGN section 4b(1) inverted: the row reported a rung established by evidence that no lane ran. It is also section 5's specification-without-execution trap in its most deniable form -- the tests are real, correct, and would pass; they simply were not on any acceptance path, and nothing about reading the file says so. The mutation controls are the load-bearing ones and that makes the omission worse rather than lesser. The module header argues they exist BECAUSE a cardinality check passes on substitution and duplication and only an identity join separates them. An unenrolled control that the carrier calls load-bearing is a claim about coverage the tree cannot make. row_extractor_reconciles_with_both_rosters_by_real_execution row_extractor_refuses_a_substituted_identity_by_real_execution row_extractor_refuses_a_duplicated_identity_by_real_execution now carry bin_wet rows in gunbc.ci_layer_roots, entries in floor_route_gap_chunk_00, and WetScheduledClaim rows in local_repo_wet_schedule -- the same three rosters the two original tests were enrolled in. All five wet functions in the file are now on the acceptance path. The failure-mode row also cites both mutation controls, not just the positive one. A row whose evidence names only the accepting case describes half its own claim. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F8wZ8BQ3mXe4cSfqDJiWNj * chore: regenerate drifted generated artifacts (ci auto-heal) Ledger-Repair-Judged: docs/design-failure-modes.md Ledger-Rows-Repaired: docs/design-failure-modes.md printed_remedy_is_mangled_by_the_medium_that_prints_it Ledger-Repair-Judged: docs/design-rung-drops.md * Regenerate the ledger projection locally, and record the substitution firing on the row it belongs to TWO THINGS, both consequences of the same merge. THE PROJECTION WAS AUTHORITY-AHEAD BY EXACTLY THIS BRANCH'S ROW. roster.dag declared printed_remedy_is_mangled_by_the_medium_that_prints_it and docs/design-failure-modes.md contained it zero times, because an earlier merge resolution took the base side of the projection per the driver's own step 1 -- the documented state, waiting on heal, which had not pushed. Every by-name instrument agreed the row was filed, because it was, in the authority; the document a reader opens did not have it. Shipping that would have been this row's own subject. Regenerated with a gunbc built from this tree rather than the installed one. The installed binary predates DESIGN section 4c source annotations and fails the corpus at comment positions, which is why six earlier regeneration attempts emitted nothing at all -- they never reached evaluation. The tree-built binary writes. Verified by the same three-set reconciliation this branch enrolls: projection 128 rows, roster 128 entries, and rostered-minus-projected, projected-minus-rostered and duplicates all EMPTY. A count equality alone would not have established that, which is the whole argument of the witness. THE SUBSTITUTION CASE FIRED IN PRODUCTION AND IS NOW A RECEIPT ON THE ROW. Merging main reached this driver on that projection. It refused as specified -- zero conflict markers, three index stages, ours left clean -- and the repaired step 2 measured base 126 rows against ours 126 rows, COUNTS EQUAL, with the ours side dropping exactly one row main had added (duplicate_record_literal_field_silently_last_wins) and adding one of its own. A cardinality check passes on that and reports nothing; only the identity join names the casualty. So the case a review had challenged this branch to cover arrived unprompted, on the same projection, minutes after the controls for it were enrolled. It is a discriminating RED on the real acceptance path rather than a fixture, which is what DESIGN section 4b(1) asks a rung claim to rest on. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F8wZ8BQ3mXe4cSfqDJiWNj * Regenerate the projection from the merged authority: neither side's bytes were it The merge of main reached the generated-artifact driver on this projection and it refused as designed -- zero conflict markers, three index stages, ours left clean. Stages 1/2/3 were captured to files BEFORE any resolution, per the ordering rule that a resolving `git checkout` or `git add` clears the stages and a later read of them returns nothing. Measured across the captured stages, with a deletion positive control proving each direction can produce a non-empty answer: base 127 rows, ours 128, theirs 128 -- OURS AND THEIRS COUNT-EQUAL theirs carried edit_pass_that_matched_nothing_reports_success, which ours lacked ours carried printed_remedy_is_mangled_by_the_medium_that_prints_it, which theirs lacked So neither side's bytes were the projection of the merged authorities, which is the precise condition this driver exists to refuse rather than resolve. Taking either side would have dropped exactly one row at an unchanged total, and a count check reports nothing on that. The authority merged cleanly carrying BOTH rows, so the projection is regenerated from it rather than chosen between the two sides. Verified by the same three-set reconciliation this branch enrolls: projection 129 rows, roster 129 entries, missing/unexpected/duplicated all EMPTY, with a positive control that names a row deliberately dropped from the roster side. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F8wZ8BQ3mXe4cSfqDJiWNj * Regenerate the projection from the merged authority (three rows, two lanes) Fourth conflict cycle on this projection. Stages captured to files before any resolution, compared under one collation, with a deletion positive control so an empty answer is known to be discriminating: base 128, ours 129, theirs 130 theirs carried a_branch_property_falsified_by_a_derived_push and a_deconfliction_plan_does_not_enumerate_its_writers, which ours lacked ours carried printed_remedy_is_mangled_by_the_medium_that_prints_it, which theirs lacked Neither side's bytes were the projection of the merged authorities, so neither was taken as the answer. The authority merged additively with all three rows and the projection is regenerated from it. Verified by the three-set reconciliation this branch enrolls: projection 131 rows, roster 131 entries, missing/unexpected/duplicated all EMPTY, with a positive control that names absorbing_fallback when it is dropped from the roster side. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F8wZ8BQ3mXe4cSfqDJiWNj * Regenerate the failure-mode projection over the merged roster Cycle-5 regeneration after merging origin/main: the projection now carries all 133 rostered identities. Verified by three-set reconciliation (missing, unexpected, duplicated all empty) with a positive control that drops absorbing_fallback from the roster side and confirms it is named. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F8wZ8BQ3mXe4cSfqDJiWNj * chore: regenerate drifted generated artifacts (ci auto-heal) Ledger-Repair-Judged: docs/design-failure-modes.md Ledger-Rows-Repaired: docs/design-failure-modes.md printed_remedy_is_mangled_by_the_medium_that_prints_it Ledger-Repair-Judged: docs/design-rung-drops.md * chore: regenerate drifted generated artifacts (ci auto-heal) Ledger-Repair-Judged: docs/design-failure-modes.md Ledger-Rows-Repaired: docs/design-failure-modes.md reported_required_refusal_does_not_precondition_landing Ledger-Rows-Repaired: docs/design-failure-modes.md printed_remedy_is_mangled_by_the_medium_that_prints_it Ledger-Repair-Judged: docs/design-rung-drops.md --------- Co-authored-by: Brian Searls <briansearls1@gmail.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>
What
gunbc#10292 is not a stale duplicate of the gunbc#10206 carrier split. Its branch forked at
cb0ec47e5d9and carries its own copy of the split plus three later commits, so a plain diff against main scores the whole branch as behind and hides the one thing on it that never landed.This PR re-homes that one thing onto today's split roster: the failure-mode row
trigger_names_route_while_capability_remains_dead, plus itsgunbc.recurring_failure_mode.rosterentry and the two projected lines indocs/design-failure-modes.md.The four amendments deliberately NOT re-applied
Each was checked against main rather than assumed stale:
accepted_source_emits_uncompilable_targetscope sentencecheck_subject_narrower_than_its_declared_claimrefutation sentencenamespace_wave_admissiondissolution record for the split's two admission rowsNINETEENTH TRANSITIONTWENTIETHonly because that branch carries an extra cohortgunbc.recurring_failure_modepreamble wordingThe row
Subject is
v2.workflow.floor_expected_redchunk_23, whose removal trigger namedcontainer_element_nominal_brand_mismatchreaching the direct-call-argument position. That route was already present on main while the capability it was meant to restore was still dead, so the calibratedFreeMonoid<Node>-into-FreeMonoid<NormalizedTree>mismatch compiled clean. §4b(3) states the trigger hazard as doctrine; this row is the tree observation of it, and it bounds itself explicitly againstrestoration_promise_names_a_route_that_does_not_existandreachability_read_as_occupancy.One §3 amendment on top of the salvaged draft: the row's permanent-witness sentence named no symbol. It now names
test.claim.record_literal_call_arg_handoff_witnessrecord_literal_container_element_mismatch_at_call_arg_still_refuses— the assertion that counts blockingDeclaredTypeNotInhabitedrows whose rendered subject isgeneric type argument.Verification
direct_call_generic_type_argument_inhabitance_diags,container_element_nominal_brand_mismatch,direct_call_arg_type_mismatch,nominal_call_arg_brand_mismatch,declared_type_inhabitance,DeclaredTypeNotInhabited,PositionGenericTypeArgument, chunk_23. gunbc#10226 is MERGED.docs/design-failure-modes.mdis generated; the required lane's generated-artifact phase adjudicates it againstgunbc.design_ledgersexpected_design_failure_modes_md, which is the independent oracle here. Before deriving the new lines, the projection function was reproduced byte-for-byte against an already-committed row (premise_that_a_shared_subject_means_disagreement), so a drift red would be a real disagreement rather than a formatting guess.cargo fmt --all --check: clean (no Rust changed).🤖 Generated with Claude Code
https://claude.ai/code/session_01FSjamJZnktJ59XsarNLyeH
Amended after review
The citation named a module that does not exist. The row cited
test.claim.record_literal_call_arg_handoff_witness_test; the file of that basename declarestest.claim.record_literal_call_arg_handoff_witness— no_teston the module tail. I invented the identity from the filename while amending the row for §3, so the §3 repair produced a worse §3 violation: the original vague citation was unresolvable and obviously so, mine was unresolvable and looked authoritative. Fixed in the row and in the projection, since the receipt is copied into the generated markdown a reader actually reads.The name is not derivable from the path in either direction: of 1186
dag/test/claim/*_test.dagfiles, 749 drop_testfrom the module tail, 322 keep it, 115 do neither; and corpus-wide, 1354 of 4813.dagmodules have a whole directory segment absent from their identity. Line 1 of the file is the only authority. Every backticked dotted identifier in the row is now matched againstgit grep -h '^module ' -- '*.dag'; all three resolve.Heading said "three" over a four-row table. Corrected.
The ceiling rung was named wrong, and codex review 59889 caught it. The row declared
CEILING: 3 (mechanically preventable); DESIGN.md §4b numbers those differently — 2 is mechanically preventable, 3 is structurally guaranteed. A row whose whole subject is a grain mismatch between a stated loss and its trigger was carrying a grain mismatch between its own ceiling's number and its name. The number was right and the name wrong, resolved from the mechanism the row already described (a refusal derived from modeled structure is rung 3, not a gate that must stay enrolled), and the row now derives why it is not 4: §4b(1) reads a rung as the minimum across parts, and retirement also requires the discriminating witness to hold, which is executed evidence rather than a constructor.