Repository navigation
Carry the item kind the parse constructor already knew, and delete the predicates that guessed it from absence - #10459
Conversation
…e predicates that guessed it from absence `Node` had no item-kind field, so the parser dispatched on the `type` / `fn` / `data` / `service` / `resource` keyword and then discarded which one it saw. By the time any later stage asked, the kind survived only as a combination of which optional fields happened to be ABSENT -- and every consumer re-derived it that way, which fails silently toward whichever bucket absence defines. v1.std.core Node now carries module_item_kind: ParsedModuleItemKind. No second enum was minted: the coproduct already existed in v1.compiler.parse and MOVES to v1.std.core beside Node, gaining one variant NotAModuleItem for every node that was never constructed as an item. It is stamped at the eight parse item constructors from the ItemForm body_kind the parser was already dispatching on, propagated at every construction that rebuilds a node, and consumed by an exhaustive match in all three emitters. Five emit-side predicates that decided an item's KIND are deleted, including the byte-identical pair is_service_item / is_service_def_item. The four that decide TYPE STRUCTURE survive, each gated on the carried kind; is_bare_leaf_item is renamed is_leaf_type_item, the shape-not-kind name that let two capability-less resources reach the type arms. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013DAftHQMwtEPHPNEAYRc5E
Generated stage0 mirrors are taken from main here and regenerated in the next commit; only the .dag authorities are hand-resolved. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013DAftHQMwtEPHPNEAYRc5E
…nd climb the arm-order row The generated mirrors are taken from the regen candidate, not hand-edited. The hand-authored Rust that constructs `Node` -- cli_run, the interpreter, the witness binaries and one test module -- carries the new field explicitly; the three consumers that called is_data_def_item compare against the kind instead. gunbc.recurring_failure_mode dispatch_correctness_resting_on_arm_order named this change as its next-rung trigger. The trigger fired: the row moves to STRUCTURALLY IMPOSSIBLE and records the executed evidence, the enrolled RED/control pairs that survive the climb, and what did NOT climb. docs/design-failure-modes.md is regenerated from the authority via generated_artifact_gate main_wet_one, never hand-edited. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013DAftHQMwtEPHPNEAYRc5E
The roster is append-only and both sides appended DIFFERENT rows, so the union is the resolution rather than a choice; main's three rows keep their source order ahead of this branch's two, because the projection renders in roster order. Every generated artifact in conflict -- the stage0 mirrors and docs/design-failure-modes.md -- is taken from main here and regenerated from its authority in the next commit. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013DAftHQMwtEPHPNEAYRc5E
…he merge Every artifact here is taken from its producer -- the stage0 mirrors from the regen candidate tree, docs/design-failure-modes.md from generated_artifact_gate main_wet_one -- rather than hand-resolved. Both sides of the roster merge are present in the derived projection: main's verdict_stale_at_the_merge_instant and this branch's emitter_residual_renders_inert_text both render, which is the check side-taking could not have given. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013DAftHQMwtEPHPNEAYRc5E
Roster union again -- main appended container_status_read_as_a_claim_about_its_members, this branch appended two others -- with the projection taken from main and re-derived from the merged authority in the next commit rather than hand-resolved. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013DAftHQMwtEPHPNEAYRc5E
Both sides render: main's container_status_read_as_a_claim_about_its_members and this branch's emitter_residual_renders_inert_text. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013DAftHQMwtEPHPNEAYRc5E
Two CI reds, two distinct causes, neither a defect in the climb itself. NAMESPACE-WAVE-ADMISSION asked this change to say what it does. Carrying a positive kind on the parsed item puts `ParsedModuleItemKind` on `Node`, and `Node` is declared in `v1.std.core`, which cannot import `v1.compiler.parse` -- acyclicity, the import graph's one structural law. So the coproduct MOVES, and seven binding sites in `v1.compiler.parse` bind the same spellings to a different declaring module. That is a `TargetChanged` delta by construction and exactly the motion the wall exists to make visible, so it is admitted under one label rather than worked around. `NotAModuleItem` is not among the seven: it is authored here and has no base binding to change. The other three deltas are left to the wall, which already disposes them -- the two new roster rows as `ExplicitlyEvaluatedZeroDelta`, and the removed emit_core_support -> parse membership as `SameDeclarationIdentityRebind`, the import the deleted shape predicates no longer need. THE SIX gunbc#10439 ROWS ARE DELETED, AND THAT IS THE OBLIGATION RATHER THAN A COURTESY. #10439 merged; every one of its rows reported CONSUMED on this branch's own run, and the consumed receipt states the deletion is owed on the roster's next touch. This is that touch. THE `compiler_tests.rs` DRIFT IS REAL AND WAS NOT A STALE BINARY. A regen with a freshly built claim_executor reproduces the same FAIL as CI: the committed mirror is missing `direct_call_formal_authority_is_declaration_bound`, emitted from an authority that arrived with a merge of main. The candidate file is installed unmodified; no mirror is hand-edited. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013DAftHQMwtEPHPNEAYRc5E
# Conflicts: # docs/design-failure-modes.md # src/v1/stage0/src/compiler_tests.rs # src/v1/stage0/src/v1_compiler_emit_rust.rs
… main Taking the base side of a conflicted stage0 MIRROR produced a tree that cannot compile: main's v1_compiler_emit_rust.rs still calls the emit-side shape predicates this branch deletes, so claim_executor fails to build and no regen can run to produce the merged bytes. Base is not a neutral provisional for a mirror whose authority this branch changed -- it is the side guaranteed stale against that authority. These bytes are NOT the answer and are not claimed to be derived. They are the only side that BUILDS, which makes them usable scaffolding to reach a compiler; the regen candidate derived from the merged .dag replaces them in the next commit. The docs projection keeps the driver's base-side route, which has no bootstrap constraint. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013DAftHQMwtEPHPNEAYRc5E
# Conflicts: # dag/gunbc/recurring_failure_mode/roster.dag
Replaces the ours-side bootstrap bytes with the candidate emitted from the merged .dag: v1_compiler_emit_rust.rs (the shape-predicate call sites are gone, which is what the base side could not express) and gunbc_cli_dispatch_generated.rs (main-side drift, not this branch's). compiler_tests.rs no longer drifts. The regen this reads is trustworthy because the claim_executor build that produced it exited 0. A regen on a stale binary prints the same shaped verdict and means nothing; only the build exit code distinguishes them. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013DAftHQMwtEPHPNEAYRc5E
Ledger-Repair-Judged: docs/design-failure-modes.md Ledger-Rows-Repaired: docs/design-failure-modes.md absence_classifier_default_bucket Ledger-Rows-Repaired: docs/design-failure-modes.md dispatch_correctness_resting_on_arm_order Ledger-Rows-Repaired: docs/design-failure-modes.md emitter_residual_renders_inert_text Ledger-Rows-Repaired: docs/design-failure-modes.md kind_carried_but_its_fields_stay_optional Ledger-Repair-Judged: docs/design-rung-drops.md
gunbc_cli_dispatch_generated.rs on main carries seven argument pairs for the fleet-converge CLI entry (#10357). A previous commit here installed a regen candidate produced against an EARLIER tree, which wrote vec![] over them -- silently reverting another lane's landed content while looking like a clean mirror install. The file is now byte-identical to main again, which is correct: this branch changes nothing that feeds it. Install only from a regen that ran on the exact tree being committed. A stale candidate does not fail to compile; it deletes rows, and only a diff against the other side names what went dark. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013DAftHQMwtEPHPNEAYRc5E
# Conflicts: # dag/gunbc/recurring_failure_mode/roster.dag # docs/design-failure-modes.md # src/v1/stage0/src/v1_compiler_infer.rs
Main's 04_infer.dag work and this branch's module_item_kind propagation both land in v1_compiler_infer.rs, so the merge left it conflicted. Ours-side was restored as build scaffolding only -- main's version predates the field and cannot compile -- and this replaces it with the candidate emitted from the merged .dag by a regen whose build exited 0. Checked before committing, because the failure mode is silent: git diff against main on this path is 54 insertions and ZERO deletions, so nothing main landed is reverted. A stale candidate would have looked identical at the compiler and at clippy. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013DAftHQMwtEPHPNEAYRc5E
Review 60552: parse_type_after_kw's record-body and bare-leaf arms constructed type declarations while stamping module_item_kind NotAModuleItem -- a constructor lying about what it built, in the exact class this PR exists to close. Both now stamp ModuleItemTypeDeclaration. The dummy and named_dummy nodes in the same function keep NotAModuleItem and that is correct: they are error placeholders, never items, and the live parse_type_body_from_prefix stamps its dummy the same way. NOT A LIVE REGRESSION, AND NOT PRIMED TO FABRICATE EITHER. parse_type_def has no caller anywhere in .dag or Rust outside its own self-reference, and stamp_parsed_module_items REFUSES on NotAModuleItem, so a rewired call would have failed closed rather than fabricating a type bucket. It was still wrong: the PR's claim is that no consumer re-derives an item's kind, which a constructor stamping the wrong one contradicts. The reviewer's other option -- delete the dead functions -- is not taken here. gunbc.guarantee_stall.heterogeneous_child_list_stall cites parse_type_after_kw by name, so the deletion owes that authority an update and is a different subject from this brief. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013DAftHQMwtEPHPNEAYRc5E
# Conflicts: # dag/gunbc/recurring_failure_mode/roster.dag # src/v1/stage0/src/namespace_wave_admission.rs
Ledger-Repair-Judged: docs/design-failure-modes.md Ledger-Rows-Repaired: docs/design-failure-modes.md absence_classifier_default_bucket Ledger-Rows-Repaired: docs/design-failure-modes.md dispatch_correctness_resting_on_arm_order Ledger-Rows-Repaired: docs/design-failure-modes.md emitter_residual_renders_inert_text Ledger-Rows-Repaired: docs/design-failure-modes.md kind_carried_but_its_fields_stay_optional Ledger-Repair-Judged: docs/design-rung-drops.md
…calm-wolf-333 # Conflicts: # dag/gunbc/recurring_failure_mode/roster.dag
…ion/calm-wolf-333 # Conflicts: # docs/design-failure-modes.md
…calm-wolf-333 # Conflicts: # src/v1/stage0/src/namespace_wave_admission.rs
Ledger-Repair-Judged: docs/design-failure-modes.md Ledger-Rows-Repaired: docs/design-failure-modes.md absence_classifier_default_bucket Ledger-Rows-Repaired: docs/design-failure-modes.md dispatch_correctness_resting_on_arm_order Ledger-Rows-Repaired: docs/design-failure-modes.md emitter_residual_renders_inert_text Ledger-Rows-Repaired: docs/design-failure-modes.md kind_carried_but_its_fields_stay_optional Ledger-Repair-Judged: docs/design-rung-drops.md
…calm-wolf-333 # Conflicts: # dag/gunbc/recurring_failure_mode/roster.dag # docs/design-failure-modes.md
The required namespace-wave phase refused at 04ba08b with 0 unadjudicated deltas, 0 stale admissions, and 2 CONSUMED admissions due for deletion on this roster-touching change: both param_names_of rows, whose relocation to v2.std.fn_index the base already satisfies since #10300 merged. The roster's rule is that a consumed row's deletion comes due on the roster's next touch, and this change is that touch. Adjudicated by the run rather than by the trigger sentence: the phase named both rows by identity, 2 of 2, and blocked until they were gone. The #10300 entry above predicted this deletion for itself; it now records that it was paid. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013DAftHQMwtEPHPNEAYRc5E
…calm-wolf-333 # Conflicts: # dag/gunbc/recurring_failure_mode/roster.dag
…ion/calm-wolf-333 # Conflicts: # docs/design-failure-modes.md
The required namespace-wave phase refused at d8ad8b6 with 0 unadjudicated deltas, 0 stale admissions, and 2 CONSUMED admissions due for deletion on this roster-touching change: both host_converge_for_identity rows. Their own entry named its trigger as gunbc#10324 MERGING, and 3a1ee65 is in this branch's history, so main carries the wrapper in gunbc.host_converge, base and head bind the spelling identically, and no run can produce those deltas. HOST_CONVERGE_LOOKUP_MOVE_LABEL goes with them. Leaving the const behind would be an unused item, which -D warnings turns into an error rather than a warning, so the label and its rows have the same lifetime by construction. Adjudicated by a run and not by the trigger sentence: the phase named both rows by identity, 2 of 2, and blocked until they were gone. This is the third cohort this branch has paid for work it did not do -- gunbc#10439's six, gunbc#10300's two, now gunbc#10324's two. The toll is proportional to how long a branch stays open, which argues for shorter branches rather than against the rule: the roster stays small precisely because deletion comes due on touch. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013DAftHQMwtEPHPNEAYRc5E
Ledger-Repair-Judged: docs/design-failure-modes.md Ledger-Rows-Repaired: docs/design-failure-modes.md absence_classifier_default_bucket Ledger-Rows-Repaired: docs/design-failure-modes.md dispatch_correctness_resting_on_arm_order Ledger-Rows-Repaired: docs/design-failure-modes.md emitter_residual_renders_inert_text Ledger-Rows-Repaired: docs/design-failure-modes.md kind_carried_but_its_fields_stay_optional Ledger-Repair-Judged: docs/design-rung-drops.md
Answering codex review 60760Conceded and fixed. This was a real defect, it was reachable only because of this PR, and it is the What it found. With the kind carried, capability-less resources route to Worth stating plainly: the climb did not create this defect, it made a pre-existing Fixed as a gap, not refused, and another emitter decides it. Rust's Where it landed. The regression control you asked for, in Two notes on how it is written. The assertion uses Boundary, stated rather than left to be inferred: this control lives under the — sent from calm-wolf-333 |
…calm-wolf-333 # Conflicts: # docs/design-failure-modes.md # src/v1/stage0/src/v1_std_core.rs
…calm-wolf-333 # Conflicts: # src/v1/stage0/src/compiler_tests.rs # src/v1/stage0/src/v1_compiler_compiler_tests_rust.rs
Ledger-Repair-Judged: docs/design-failure-modes.md Ledger-Rows-Repaired: docs/design-failure-modes.md absence_classifier_default_bucket Ledger-Rows-Repaired: docs/design-failure-modes.md dispatch_correctness_resting_on_arm_order Ledger-Rows-Repaired: docs/design-failure-modes.md reported_required_refusal_does_not_precondition_landing Ledger-Rows-Repaired: docs/design-failure-modes.md emitter_residual_renders_inert_text Ledger-Rows-Repaired: docs/design-failure-modes.md kind_carried_but_its_fields_stay_optional Ledger-Repair-Judged: docs/design-rung-drops.md
…calm-wolf-333 # Conflicts: # dag/gunbc/recurring_failure_mode/roster.dag # docs/design-failure-modes.md
# Conflicts: # docs/design-failure-modes.md
Ledger-Repair-Judged: docs/design-failure-modes.md Ledger-Rows-Repaired: docs/design-failure-modes.md absence_classifier_default_bucket Ledger-Rows-Repaired: docs/design-failure-modes.md dispatch_correctness_resting_on_arm_order 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-Rows-Repaired: docs/design-failure-modes.md emitter_residual_renders_inert_text Ledger-Rows-Repaired: docs/design-failure-modes.md kind_carried_but_its_fields_stay_optional Ledger-Repair-Judged: docs/design-rung-drops.md
# Conflicts: # src/v1/stage0/src/v1_compiler_emit_rust.rs # src/v1/stage0/src/v1_std_core.rs
The merge brought main's 00_core.dag and 05_emit_rust.dag changes, so the ours-side mirrors taken to make the tree buildable were authority-behind. Regenerated from the merged .dag: v1_std_core.rs, v1_compiler_emit_rust.rs, and v1_compiler_compiler_tests_rust.rs, whose three changed lines are module_item_kind threading into the node constructors #10547 added. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013DAftHQMwtEPHPNEAYRc5E
|
Answering review 60865 (advisory finding). Declining the suggested change, on the merits rather than on cost. The five sites named are So the residual equality reads are membership tests against one named variant, not dispatch, and a new variant added later must not silently join — sent from calm-wolf-333 |
# Conflicts: # dag/gunbc/recurring_failure_mode/roster.dag # docs/design-failure-modes.md
Ledger-Repair-Judged: docs/design-failure-modes.md Ledger-Rows-Repaired: docs/design-failure-modes.md empty_observation_narrow Ledger-Rows-Repaired: docs/design-failure-modes.md absence_classifier_default_bucket Ledger-Rows-Repaired: docs/design-failure-modes.md dispatch_correctness_resting_on_arm_order Ledger-Rows-Repaired: docs/design-failure-modes.md comparison_keyed_on_part_of_the_identity_it_compares Ledger-Rows-Repaired: docs/design-failure-modes.md emitter_residual_renders_inert_text Ledger-Rows-Repaired: docs/design-failure-modes.md kind_carried_but_its_fields_stay_optional Ledger-Repair-Judged: docs/design-rung-drops.md
One regen round is not a fixed point: the regen is run by the binary built from the old mirrors, so installing a regenerated v1_compiler_emit_rust.rs changes what the emitter emits on the next round. compiler_tests.rs only drifts once that emitter is compiled in, which is why the first round named three files and stayed silent on this one. Iterated build/regen/install until two consecutive rounds reported REGEN=0. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013DAftHQMwtEPHPNEAYRc5E
# Conflicts: # dag/gunbc/recurring_failure_mode/roster.dag # docs/design-failure-modes.md
Ledger-Repair-Judged: docs/design-failure-modes.md Ledger-Rows-Repaired: docs/design-failure-modes.md edit_pass_that_matched_nothing_reports_success Ledger-Rows-Repaired: docs/design-failure-modes.md transport_close_read_as_completion Ledger-Rows-Repaired: docs/design-failure-modes.md absence_classifier_default_bucket Ledger-Rows-Repaired: docs/design-failure-modes.md dispatch_correctness_resting_on_arm_order Ledger-Rows-Repaired: docs/design-failure-modes.md edit_range_bounded_by_a_neighbour_rather_than_the_target Ledger-Rows-Repaired: docs/design-failure-modes.md one_disposition_defined_jointly_by_independent_matches Ledger-Rows-Repaired: docs/design-failure-modes.md emitter_residual_renders_inert_text Ledger-Rows-Repaired: docs/design-failure-modes.md kind_carried_but_its_fields_stay_optional Ledger-Repair-Judged: docs/design-rung-drops.md
…ed authority, and rescope the trigger to responsibility survival TWO OBLIGATIONS: G1, a real revert of somebody else's landed work, and T1, a trigger whose derivation reached an easier neighbouring property than the one it claimed. G1 -- THE MERGE DROPPED MAIN'S AUTHORITY BYTES FROM THE MIRROR. At ff3c0e4 `src/v1/compiler_tests_rust.dag` carried main #10459's `item_of_kind` helper and its `module_item_kind` rows (4 and 3 occurrences) while `src/v1/stage0/src/compiler_tests.rs` carried NEITHER, and that mirror blob was byte-identical to this branch's pre-merge side. Merging would have silently reverted another lane's tests with no conflict raised anywhere. THE CAUSE IS TRACED RATHER THAN ASSUMED, because a stale emitting binary was a hypothesis and not a finding. `compiler_tests.rs` is emitted from the SEED'S COMPILED-IN function, not from the `.dag`; the producer used for the first regeneration was built at 09:40, before the merge. The discriminating measurement: the candidate that binary produced carried `item_of_kind` ZERO times, and after rebuilding the seed from the merged tree the candidate carries it FOUR times, matching the authority. That is the producer demonstrably bound to the merged authorities, not an argument that it should be. Re-derived THROUGH THE EXISTING ROUTE -- `claim_executor --required-regen`, then the candidate taken whole. The generated file was NOT hand-patched, and the older fixture was NOT restored in the authority to manufacture agreement. Regeneration now reaches a FIXED POINT: `first_generation_equal=true planned=157 executed=157 adjudicated=157`. Verified at identity grain in both directions -- authority 4/3, mirror 4/3 -- and main's rows are present rather than merely non-conflicting. WHY THE EARLIER CHECK PASSED, which is the finding worth more than the fix. The verification said "both mirrors regenerated, set difference clean in both directions". The OTHER mirror genuinely did regenerate; one of the two did not, and a check whose subject was the pair I had in mind could not see the one I had not. THE SUBJECT OF THE CHECK WAS NARROWER THAN ITS CLAIM -- the class this PR spends its length filing, committed by the verification of the commit that filed it. The generated paths are now enumerated FROM THE DIFF rather than recalled. T1 -- THE TRIGGER CLAIMED RESPONSIBILITY SURVIVAL AND DERIVED DECLARATION WELL-FORMEDNESS. The previous wording required a closable owner to declare a continuation at authoring time, and derived rung 3 from claim and continuation being one object. A CONDITION'S PRESENCE IS NOT ITS FULFILMENT: attach discharge condition D to obligation O owned by A, never satisfy D, close A, and let no successor accept O -- every field the rule demands is present and responsibility is still lost, which is this tier exactly. Naming B is not B ACCEPTING O. So that rule removes the missing-declaration state and nothing more, and the derivation was true of well-formedness and false of survival. It also had a plain wording bug: the rule permits a successor OR a discharge condition, while the negative was written as "a closable owner with NO SUCCESSOR", which refuses the discharge-only case the rule permits. RESCOPED TO SURVIVAL, which is this tier's actual subject: responsibility cannot be retired through a modeled closure transition unless discharge evidence for that exact obligation is consumed or an accepted transfer is established; otherwise responsibility is RETAINED and the closure REFUSED. This predicts nothing -- the impossible ask was whether D will eventually hold -- it constrains what an accepted closure operation may do, the ordinary fail-closed move. Its BOUNDARY is stated: an external action bypassing the modeled transition does not acquire the guarantee because a declaration exists. Scope (a), claiming rung 3 for declaration well-formedness alone, was available and refused: it is true and cheaper, but it would make the trigger's subject NARROWER THAN THE FAILURE IT SERVES -- the same defect as G1's verification, one layer up. Both weaker triggers are recorded as refused with their reasons. No lifecycle machinery is implemented here; the obligation was an accurate trigger and derivation, not an implementation. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E7N3747vwQ8HvNFUbT8Xgv
…rom the merged authority THE ORDER INVERTED. #10571 merged first as 848365e, so this branch is the second of the two PRs that touch docs/design-failure-modes.md and is the one that regenerates. main also landed population_selector_that_cannot_admit_a_counterexample in the same window. RESOLVED AS AN AUTHORITY MERGE PLUS A REGENERATION, NOT AS A TEXT MERGE, because this is the same trap as the earlier compiler_tests.rs defect on this same projection one merge ago: a generated path resolved by choosing a side LOOKS resolved when it is not, and last time that would have reverted #10459. The roster is an authority and takes both sides -- main's row keeps its position and this branch's appends after it. The projection was taken from the base side and regenerated through gunbc.instruments.generated_artifact_gate main_wet. No side was forced and no conflict markers were edited. VERIFIED BY CONTENT AT IDENTITY GRAIN, ALL FOUR DIRECTIONS ASKED FOR, with one extractor naming both row shapes: - rows on main missing from the resolved projection: EMPTY - rows in the resolved projection that NEITHER side authored: EMPTY - roster rows missing from the projection: EMPTY - content: this branch's row present, #10571's NINTH FORM present, and main's population_selector_that_cannot_admit_a_counterexample present Neither mergeStateStatus nor an absence of conflict markers was consulted as evidence: this driver guarantees marker-free bytes on a refusal, so a marker count reports that the driver worked and never that its subject is intact. The approval at 057705e and that head's four green checks do NOT carry to this head -- an approval judges a candidate and does not travel to one nobody judged, which is the asymmetry this lane enforced all day and which now costs it a green it wanted. Fresh run and fresh adjudication are owed here. No content is reopened: T1, G1, the failure-mode row, the sibling witness and the PR body all stand as adjudicated. This is rebase-and-regenerate. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E7N3747vwQ8HvNFUbT8Xgv
…int an ownerless trigger to a durable owner (#10552) * Repair prose asserting a deleted CI premise, file the class, and repoint an ownerless trigger to a durable owner Three sections, one root: a claim that was TRUE when written and became false through a CORRECT edit elsewhere, with nothing executing over the survivors. (1) PROSE ASSERTING A DELETED PREMISE. The 2026-09-04 runner-capacity ruling deleted the `rust-unit-tests` job (`gunbc.rung_drop` `rust_unit_tests_off_the_merge_path`). Four sites still asserted it as live: - `v1_compiler.compiler_tests_rust` :4192 was the worst specimen and is rewritten from "THE WALL ... ENROLLED WHERE IT ACTUALLY EXECUTES" to "THE PROBE ... AND THE PATH IT DOES NOT EXECUTE ON". It claimed a wall on a lane that no longer runs -- DESIGN 4b(1) rung inflation, which is worse than sitting low because an inflated class never ranks for climbing. The block also rejected a wet transport on the grounds that it "would have been an inert lens asserting a safety property nothing runs", and the home it chose instead became exactly that: the argument's conclusion inverted without one word changing. That sentence is now quoted against itself in place. - `ct_fixture_closure_rustc_discrimination_test` and `ct_evaluation_budget_consequence_falsifier_test`: the deleted premise is replaced by RUNNABLE ON DEMAND, naming the invocation and who consumes the result, so neither reads as enrollment. - `gunbc.emitted_closure_compile_seed_growth` :104-107 "is ENROLLED AND AVAILABLE in `rust-unit-tests`" -> "is RUNNABLE ON DEMAND ... IT EXECUTES ON NO CI PATH", pointing at `witness_floor_lane_jobs` and the drop row; :197 keeps its 456.28s measurement and loses the present-tense clause. No fifth turnover note is added -- four already stand. (2) THE CLASS IS FILED. `gunbc.recurring_failure_mode` `stale_claim_survives_its_own_correct_edit`, with four severity tiers ordered by how badly each hides: ordinary stale description; rung inflation; reasoning that inverts while its words stay correct-looking; and a citation whose REFERENT'S LIFECYCLE ENDS. Rung found at 1, ceiling 2 with the reason stated per sub-case, and a next trigger named at capability grain. It also carries the measurement hazard, because three successive phrase-keyed detectors each returned a confident clean answer for a row they could not see. (3) THE ROUTE OWNER IS DURABLE NOW. Tier (iv) of that row is a defect this lane authored: `test.claim.phantom_marker_type_argument_identity_witness` named `node://adhoc-da8c65c0-b3b` as the owner of a next-rung trigger, that node reached DONE without the capability existing, and the repair repointed it to THIS LANE'S OWN WORK ITEM -- the same defect with a longer fuse. It now names `gunbc.emitted_closure_compile_seed_growth` `emitted_closure_compile_seed_growth_justification`, a standing authority SYMBOL that carries the route's growth obligation specifically (DESIGN section 3, cite the symbol not the position). The carrier states the durability test out loud -- if every session running today archived tonight, would this trigger still have an accountable owner tomorrow? -- and records that prose instability is not the same axis as ownership, so a future author of a projection check finds the distinction on the carrier rather than in a pull request description. Also recorded, on the instrument rather than in chat: the byte-verbatim authority-to-projection oracle cannot see rows whose emitted code rustfmt rewraps, so `ct_evaluation_budget_consequence_falsifier_test` mismatches identically on `origin/main`. Without that note the next person measuring with it reads a pre-existing rewrap as their own regression. Evidence: the witness compiles and `distinct_phantom_markers_do_not_render_identically` returns true; both projections regenerated and verified against their authority; `docs/design-failure-modes.md` regenerated through `gunbc.instruments.generated_artifact_gate` `main_wet`; `cargo fmt --all --check` clean. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E7N3747vwQ8HvNFUbT8Xgv * chore: regenerate drifted generated artifacts (ci auto-heal) Ledger-Repair-Judged: docs/design-failure-modes.md Ledger-Rows-Repaired: docs/design-failure-modes.md stale_claim_survives_its_own_correct_edit 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 stale_claim_survives_its_own_correct_edit Ledger-Repair-Judged: docs/design-rung-drops.md * Finish the false-premise correction, withdraw the row's impossibility claim, and make the owner's retirement conditional on the obligation Three findings from review 5120939460 at 4c04841. All three verified against the tree before acting; two of them are larger than reported. S1 -- THE FALSE PREMISE SURVIVED INSIDE MY OWN CORRECTION, AT FIVE SITES RATHER THAN THREE. `gunbc.emitted_closure_compile_seed_growth` said both that the 2026-09-04 deletion removed the path AND that the `#[ignore]` is the whole of it. At :112 the contradiction sat TWO LINES below the sentence correcting it. The review cited three sites; the other two are :227 ("rests on the `#[ignore]` alone", in the re-decision block) and :334 (the function-value-adapter row). Reconciled rather than annotated, because a fifth turnover note under a sentence still saying the opposite leaves both readings in the file, which IS the defect. The reconciliation is one fact stated once and reused: since 2026-09-04 there is NO LANE, which is dispositive on its own; the attribute only decides whether a run that DOES exist picks the test up by default. The conclusion -- candidate evidence, no wall -- is unchanged; what carries it is not. :334 is in one of the three rows held for the deferred item-6 repair, so only its MECHANISM half is corrected and its "ENROLLED AND AVAILABLE" wording is left exactly as it stands, marked in place as deliberately untouched. A conflicting claim about mechanism is not an overloaded description, which is why it is in scope while the wording is not. The cost paragraph keeps its 456.28s measurement and its +40% ratio and stops asserting a per-push fleet cost: the consequence is now explicitly CONDITIONAL on something invoking that suite per push, which nothing has since 2026-09-04. The 2026-09-03 reasoning block is NOT edited -- it is preserved whole in its own tense by this file's own rule that a number edited to match a later roster is no longer the number anything was decided on. S2 -- THE ROW OVERSTATED ITS HARM AND THE OVERSTATEMENT WEAKENED IT. It claimed the defect is invisible to every mechanism we have and that no review of either diff can detect it. THIS PR DISPROVES THAT: a review joining the retained assertion to the changed premise at the candidate tree detected it twice, and found instances my own phrase-keyed searches had missed. The accurate class is narrower and still real -- the change correctly modified one artifact and the existing checks did not validate the dependent assertion against the changed premise. The stale assertion sits outside the changed lines, but THE DELETION THAT INVALIDATED ITS PREMISE IS IN THE DIFF. An impossibility claim also makes the class never rank for a detector, which is 4b(1)'s inflation move aimed at a harm claim instead of a rung. The ceiling is corrected on the same ground: a declaration-existence check establishes EXISTENCE, not that a sentence stayed true, and not that the named declaration OWNS the cited obligation. Three properties; the check decides one. The undecidability of the third may not be borrowed to cap the first two. S3 -- THE OWNER HAS ITS OWN RETIREMENT CONDITION AND IT DID NOT COVER THE OBLIGATION. Read from the symbol's VALUE, not its commentary: `emitted_closure_compile_seed_growth_justification` is a SeedGrowthJustification whose trigger retires the host once the emission and cargo effects are modeled and which EXPRESSLY ADMITS A PARTIAL MIGRATION -- so "host effects migrate -> owner retires -> discriminator owned by nobody" was reachable. This is the second time this field has named an owner that can end before the obligation: first a session lifetime, now an artifact lifetime. The defect moved rather than being fixed, so the repair is not a third spelling of the owner. Existing symbol, relevant subject and durable responsibility are three different facts; a citation establishes two and cannot transfer an obligation. So the third is taken on IN THE OWNER'S OWN TEXT: that trigger now carries an explicit clause that it may not retire, in whole or in the partial shape it invites, while this discriminator obligation is undischarged and untransferred, requiring either discharge or a named successor, and naming silent retirement as the forbidden outcome. Both files also refuse the worst reading -- keeping an obsolete host alive so an owner string stays resolvable. If the host dissolves and nobody has taken the obligation, the obligation moves. Item 6 stays deferred and is not touched. The roster-to-projection join is a separate integration obligation and settles none of the above. Evidence: both .dag files compile and the witness returns true; the projection regenerated through gunbc.instruments.generated_artifact_gate main_wet; every substitution guarded by an exact-count assertion so a silent miss was impossible; no live assertion of the false premise remains, the one surviving occurrence being this row quoting the superseded claim in order to name it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E7N3747vwQ8HvNFUbT8Xgv * File the coincidental re-validation specimen: a claim no point-in-time check could ever have caught Manager finding on 03b22cb, verified against the file rather than accepted. The clause "rust-unit-tests is not a `needs` of the required aggregate" stood in gunbc.emitted_closure_compile_seed_growth. It was TRUE when written, made FALSE by gunbc#10078 promoting that job into the required aggregate, and made TRUE AGAIN by the 2026-09-04 ruling deleting the job. All three transitions are recorded in that file's own turnover notes, so this is an observed specimen and not a constructed one. WHY IT IS SHARPER THAN THE FOUR TIERS ALREADY IN THE ROW. Each of those is caught, in principle, by looking at the sentence. This one is not: read it today and it is green, read it during the #10078 window and it is red, read it today again and the green is COINCIDENTAL -- an unrelated deletion handed the truth back and the sentence never earned it. So the detector anyone would naturally build, "is this sentence true now", returns the correct answer today AND WOULD HAVE LICENSED THE CLAIM THROUGH THE ENTIRE PERIOD IT WAS FALSE. That is the strongest argument the row has for validating an assertion against the CHANGED PREMISE rather than checking it in isolation, which is what the next trigger already names -- so this specimen is what justifies that trigger rather than a weaker one. It also bounds the ceiling honestly, and the ceiling paragraph is corrected to say so: a point-in-time check is green during exactly the windows an assertion is accidentally true, so its silence carries no information about whether the claim was preserved. TRUE AND PRESERVED and TRUE AGAIN BY COINCIDENCE are indistinguishable at the moment of reading, and differ only in the history of the premise. Only a premise-join separates them. The practical consequence is recorded for the next author sweeping this class: a currently-green sentence is not evidence of a healthy sentence. Projection regenerated through gunbc.instruments.generated_artifact_gate main_wet. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E7N3747vwQ8HvNFUbT8Xgv * Separate retrospective detection from continuous enforcement in the ceiling reasoning Review 60886 (codex/gpt-6-astra, REQUEST_CHANGES) is correct and the finding is accepted without argument. WHAT WAS WRONG. The row said a point-in-time truth check "WOULD HAVE LICENSED THE CLAIM THROUGH THE ENTIRE PERIOD IT WAS FALSE". That is false. Such a check ENROLLED ON EVERY CHANGE would have evaluated the clause at gunbc#10078 and REFUSED, because the clause was false at that moment. What cannot recover the historical violation is a RETROSPECTIVE sweep -- the one-shot search an author runs over the tree in front of them -- and the sentence conflated the two. WHY IT MATTERED RATHER THAN BEING A WORDING SLIP. The ceiling paragraph BORROWED that argument to bound the attainable ceiling, so the row was steering a future author away from continuous enforcement, which is in fact the effective remedy for this specimen. DESIGN 4b requires an attainable ceiling DERIVED rather than aspirational, and a ceiling derived from a false premise is neither. THE CORRECTION. The specimen bounds the RETROSPECTIVE form only: a sweep of the current tree cannot distinguish TRUE AND PRESERVED from TRUE AGAIN BY COINCIDENCE, because both read green and the difference lives in the history of the premise. It does NOT bound a per-change check, which sees the falsifying transition as it happens and needs no history at all. What actually holds this class at 2 is the EVALUATION limit already stated in the same paragraph -- whether a free-prose sentence is true is not a property the source decides -- and not the timing of the reading. The two limits are independent, and conflating them makes continuous enforcement look futile when it is the remedy for every sub-case whose assertion can be evaluated at all. The next trigger names a premise-join because a join is DECIDABLE where a general truth test is not: a decidability argument, not a timing one. The superseded claim is named in place rather than silently overwritten, for the reason this row itself gives about plausible wrong mechanisms being adopted by later readers. Executed evidence at the previous head 03b22cb, which this commit builds on: all three jobs green and "generated-artifact population=registry-projections rostered=40 adjudicated=40 matches=40 drifted=0", so regenerating from the merged authority rather than leaving it to heal was correct and produced no heal cycle. Projection regenerated again here through gunbc.instruments.generated_artifact_gate main_wet. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E7N3747vwQ8HvNFUbT8Xgv * Take the free-prose sub-case off the ladder, replace the specimen headline, and separate historical reference from active responsibility REQUEST_CHANGES 5121228544 at 6831792, three items, all in stale_claim_survives_its_own_correct_edit. Each REPLACES the standing assertion rather than adding a clause under it, which is the correction this file has now needed three times and is the row's own class. 1. THE HEADLINE STILL ASSERTED WHAT THE BODY REFUTED. The paragraph opened "NO POINT-IN-TIME CHECK COULD EVER HAVE CAUGHT IT" while its own body correctly explained that a check enrolled on every change would have refused at #10078. The previous fix retracted the "would have licensed" sentence and left the headline standing. Replaced with the accurate claim: A CURRENT-TREE-ONLY RETROSPECTIVE TRUTH CHECK CANNOT RECOVER AN EARLIER FALSE INTERVAL AFTER THE CLAIM HAS BECOME TRUE AGAIN. Everything after it stands. 2. THE CEILING DID NOT FOLLOW, AND THE ROW CONTRADICTED ITSELF ABOUT IT. The header claimed CEILING: 2 for the free-prose form while the body said it stays at mitigation -- rung 1 -- so one sub-case carried two rungs in one row and neither was derived. Both are wrong. DESIGN 4b's rung 2 requires a mechanism that reliably exposes and blocks the invalid state; an assertion with no evaluator SUPPLIES no such mechanism, and the absence of an evaluator is what disqualifies a class from carrying a rung rather than what lowers it. The free-prose form therefore sits in 4b's adjacent column -- OUTSIDE THE MODELED GUARANTEE -- which the ladder deliberately excludes so "we do not model this" cannot masquerade as a weak implementation that should climb. It now carries a declared boundary obligation and NO number. The two structured sub-cases keep their own attainable ceilings and are the whole of this row's ladder claim. 3. HISTORICAL REFERENCE IS NOT ACTIVE RESPONSIBILITY. The tell asked whether a citation would still have a referent tomorrow, which condemns every citation of a closed thing. A closed work item is a perfectly good historical reference. The failure established here is narrower: an OUTSTANDING OBLIGATION losing accountable responsibility with neither discharge nor transfer. The tell now asks that question instead. This does not reopen S3 -- the discharge-or-transfer clause is unchanged and was already correct; only the general description was overbroad. Both superseded formulations are named in place rather than silently overwritten, including the header/body rung contradiction, because this row's own subject is corrections that leave the original claim readable. Verified per-row rather than per-file, since the projection carries about forty rows and a whole-file grep for "CEILING: 2" or "stays at mitigation" has no discriminating power for this one: within this row's body both are absent as assertions, the single surviving "stays at mitigation" being this row quoting the contradiction it retracts. Projection regenerated through gunbc.instruments.generated_artifact_gate main_wet. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E7N3747vwQ8HvNFUbT8Xgv * Remove four surviving ceiling and lifecycle assertions, and a fifth found by reading the sibling authority REQUEST_CHANGES 5121282475 at f7332fe. Four survivors, all inside the row a phrase-keyed sweep had certified clean, plus the non-blocking pronoun. A fifth was found here by reading the sibling authority, which no review named. 1. "What actually holds this class at 2 is the EVALUATION limit ... and not the timing of the reading" was a PRESENT-TENSE conclusion restating the derivation 5121228544 required withdrawing -- the paragraph said free prose carries NO RUNG at the top and held the class at 2 at the bottom, and the errata between them do not turn the ending into history. The limit now explains why the free-prose form carries no rung rather than deriving a number. 2. "the undecidability of the third may not be borrowed to cap the first two" asserted that OWNERSHIP is undecidable, which was never established: ownership is carried in a `String` here, and a current representation is a fact about this model rather than a proof that ownership cannot be modeled. Replaced with the reviewer's formulation -- a declaration-existence check establishes existence only; it establishes neither the truth of a dependent assertion nor continued responsibility; any guarantee for either structured relation must follow from THAT RELATION's own model and enforcement boundary. 3. "A work item fails it by construction, and so does the manager session above it" no longer follows from the corrected question: a work item can discharge before closing, or transfer to a successor that accepts responsibility. Now: in_progress status does not establish the property, and closure is safe only on discharge or valid transfer. 4. DISTINGUISHING FACTS tier (iv) still DEFINED the class as "a citation naming something that can be CLOSED ... dies silently when that lifecycle ends". Fixing the TELL had not replaced the DEFINITION -- this row's own class, inside the row about it. The tier heading carried the same old framing and is replaced with the definition. 5. The pronoun, now "the absence of a general free-prose evaluator does not derive a ceiling for the structured sub-cases". No erratum: it is a substitution, not a withdrawn claim. AND THE FIFTH, WHICH IS THE POINT OF SWEEPING BY READING. The same two claims stood in `test.claim.phantom_marker_type_argument_identity_witness`: the durability test asked whether a citation would still have a referent, and stated that a lane session and the manager session fail it BY CONSTRUCTION. Both are the corrected-away formulations, in a second authority, unflagged by any review. That block now asks the obligation question and records the superseded version. METHOD, because it is the finding rather than the fixes. A phrase-keyed sweep certified this row clean and missed all four: the live survivor read "WHAT ACTUALLY HOLDS THIS CLASS AT 2", which matches none of "ceiling of 2", "CEILING: 2", "rung 2" or "mechanically preventable". A semantic claim has unbounded phrasings, so within a surface a phrase search is a selection view one level down, and only READING closes it. Every surface here was read: row, sibling authorities, projection, PR body. Reading is also what caught that fix 4 had left a dangling article and an unreplaced heading -- a grep for the new wording would have reported success. The PR body's "Rung found at 1, ceiling 2" objection in that review is STALE and deliberately not acted on: it was fixed before the review ran and the body now carries zero occurrences. Re-answering a discharged objection is how a fix gets undone. Baseline: f7332fe has a full green verdict -- all four jobs success with rostered=40 adjudicated=40 matches=40 drifted=0, and heal SUCCESS rather than a heal cycle, so the projection regenerated from the merged authority was already correct. That green belongs to that sha and is not claimed for this one; it is a known-good point to difference against. Projection regenerated through gunbc.instruments.generated_artifact_gate main_wet; the witness compiles and returns true. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E7N3747vwQ8HvNFUbT8Xgv * Withdraw the phantom-marker opening rule, which asserted what the paragraph below it had already withdrawn The sixth fix was half done. Correcting the TEST in that block left standing the RULE that introduced it, so the surface contradicted itself with neither surviving sentence marked superseded. WHAT STOOD. The block opened "THE OWNER MUST OUTLIVE EVERY SESSION, AND A NODE IDENTITY CANNOT" and concluded that "a citation whose referent has a lifecycle dies silently when that lifecycle ends", while the paragraph added directly beneath it said an owner may discharge or transfer before closing, that being closable is not itself the failure, and that a closed owner remains a valid historical reference. THE REPAIR, taking the adjudicator's wording and REUSING the correct paragraph rather than adding a third explanation under the contradiction -- adding is what produced it. The rule is now "responsibility for an outstanding obligation must survive closure of its current owner, through discharge or valid transfer", and the paragraph concludes that the defect was allowing ACTIVE RESPONSIBILITY to end while the obligation remained undischarged and untransferred. The dated examples are unchanged. ONE FURTHER OVER-CLAIM IN THE SAME BLOCK, tightened in place rather than explained: "a trigger whose owner has ceased to exist is retired by nothing at all" now reads "ceased to exist WITHOUT DISCHARGING OR TRANSFERRING IT", which is what the corrected rule actually supports. WHY THIS IS THE THIRD INSTANCE OF ONE PATTERN AND NOT THREE MISTAKES. A repair lands at the site of the QUOTED text and leaves the FRAMING sentence that introduced it: in the row, the tier heading above a replaced definition; here, the opening rule above a replaced test. The framing is the part a fix's own search terms cannot contain, because those terms come from the text being replaced. The mechanical form is to read the sentence ABOVE a replacement and the heading above that -- which is how the over-claim two paragraphs down was found here, rather than by looking where the finding pointed. SCOPE HELD: no new test, no CI enrollment, no lifecycle machinery, no discriminator implementation, no item-6 vocabulary, and NO change to the now-accepted failure-mode row -- so the projection is untouched and needs no regeneration. The witness compiles and returns true. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E7N3747vwQ8HvNFUbT8Xgv * Re-derive the compiler_tests mirror from a producer bound to the merged authority, and rescope the trigger to responsibility survival TWO OBLIGATIONS: G1, a real revert of somebody else's landed work, and T1, a trigger whose derivation reached an easier neighbouring property than the one it claimed. G1 -- THE MERGE DROPPED MAIN'S AUTHORITY BYTES FROM THE MIRROR. At ff3c0e4 `src/v1/compiler_tests_rust.dag` carried main #10459's `item_of_kind` helper and its `module_item_kind` rows (4 and 3 occurrences) while `src/v1/stage0/src/compiler_tests.rs` carried NEITHER, and that mirror blob was byte-identical to this branch's pre-merge side. Merging would have silently reverted another lane's tests with no conflict raised anywhere. THE CAUSE IS TRACED RATHER THAN ASSUMED, because a stale emitting binary was a hypothesis and not a finding. `compiler_tests.rs` is emitted from the SEED'S COMPILED-IN function, not from the `.dag`; the producer used for the first regeneration was built at 09:40, before the merge. The discriminating measurement: the candidate that binary produced carried `item_of_kind` ZERO times, and after rebuilding the seed from the merged tree the candidate carries it FOUR times, matching the authority. That is the producer demonstrably bound to the merged authorities, not an argument that it should be. Re-derived THROUGH THE EXISTING ROUTE -- `claim_executor --required-regen`, then the candidate taken whole. The generated file was NOT hand-patched, and the older fixture was NOT restored in the authority to manufacture agreement. Regeneration now reaches a FIXED POINT: `first_generation_equal=true planned=157 executed=157 adjudicated=157`. Verified at identity grain in both directions -- authority 4/3, mirror 4/3 -- and main's rows are present rather than merely non-conflicting. WHY THE EARLIER CHECK PASSED, which is the finding worth more than the fix. The verification said "both mirrors regenerated, set difference clean in both directions". The OTHER mirror genuinely did regenerate; one of the two did not, and a check whose subject was the pair I had in mind could not see the one I had not. THE SUBJECT OF THE CHECK WAS NARROWER THAN ITS CLAIM -- the class this PR spends its length filing, committed by the verification of the commit that filed it. The generated paths are now enumerated FROM THE DIFF rather than recalled. T1 -- THE TRIGGER CLAIMED RESPONSIBILITY SURVIVAL AND DERIVED DECLARATION WELL-FORMEDNESS. The previous wording required a closable owner to declare a continuation at authoring time, and derived rung 3 from claim and continuation being one object. A CONDITION'S PRESENCE IS NOT ITS FULFILMENT: attach discharge condition D to obligation O owned by A, never satisfy D, close A, and let no successor accept O -- every field the rule demands is present and responsibility is still lost, which is this tier exactly. Naming B is not B ACCEPTING O. So that rule removes the missing-declaration state and nothing more, and the derivation was true of well-formedness and false of survival. It also had a plain wording bug: the rule permits a successor OR a discharge condition, while the negative was written as "a closable owner with NO SUCCESSOR", which refuses the discharge-only case the rule permits. RESCOPED TO SURVIVAL, which is this tier's actual subject: responsibility cannot be retired through a modeled closure transition unless discharge evidence for that exact obligation is consumed or an accepted transfer is established; otherwise responsibility is RETAINED and the closure REFUSED. This predicts nothing -- the impossible ask was whether D will eventually hold -- it constrains what an accepted closure operation may do, the ordinary fail-closed move. Its BOUNDARY is stated: an external action bypassing the modeled transition does not acquire the guarantee because a declaration exists. Scope (a), claiming rung 3 for declaration well-formedness alone, was available and refused: it is true and cheaper, but it would make the trigger's subject NARROWER THAN THE FAILURE IT SERVES -- the same defect as G1's verification, one layer up. Both weaker triggers are recorded as refused with their reasons. No lifecycle machinery is implemented here; the obligation was an accurate trigger and derivation, not an implementation. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E7N3747vwQ8HvNFUbT8Xgv --------- 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>
The parse constructors already knew which item they were building and then threw it away.
Nodehadno item-kind field, so by the time any later stage asked, the kind survived only as a combination of
which optional fields happened to be absent -- and every consumer re-derived it that way. This
carries the kind instead.
What lands
v1.std.core Nodegains one field,module_item_kind: ParsedModuleItemKind. No second enum wasminted: the coproduct already existed in
v1.compiler.parseand MOVES tov1.std.corebesideNode, becauseNodecannot import the parser. It gains one variant,NotAModuleItem, carried byevery expression, type-expression, field, variant, param and synthetic node -- a different statement
from
ModuleItemUnrecognized, which the parser's own item-error path stamps.v1.compiler.parse, from theItemFormbody_kindthe parser was already dispatching on: TypeBody/AliasBody -> TypeDeclaration, ExprBody/BlockBody ->
Function, ValueBody -> DataValue, ServiceBody -> Service, ResourceBody -> Resource, NoBody ->
Unrecognized.
resolve, inference and emission.
ParsedModuleItemKindvariant nowfails to compile at every dispatcher instead of falling through a residual arm.
parsed_module_item_kindandparsed_item_carries_resource_entriesare deleted -- the classifier isa field read.
The refusal census, which is what this change is actually accountable to
Before deleting a predicate family I enumerated what each member refuses. Full census in the lane
thread; the load-bearing results:
is_resource_def_item's second disjunct(
children == 0 && properties > 0 && body == none) becomeskind == ModuleItemResource. Its livedefect is the discriminating RED:
resource Networkandresource AuthContextinstd.resourcesdeclare no capabilities and no properties, satisfied NEITHER disjunct, and reached
is_type_alias_itemfirst in every emitter's if-chain -- so all three targets treated them astypes.
is_service_itemandis_service_def_itemwere byte-identical, bothexported, both consumed. Claiming this as a result rather than letting it disappear inside the diff.
is_type_def_item/is_type_alias_item/is_type_decl_item/is_leaf_type_item(renamed fromis_bare_leaf_item-- the shape-not-kindname that let two capability-less resources through) all range over ONE kind and split it by the
type's own structure. Each gains a kind conjunct and loses the now-dead
transport == noneone.Two orthogonal axes in one enum is a modelling failure, not a simplification.
is_function_itemandis_data_def_itemwere consumed as proof thatitem.body.valuewas safe.Node.bodyandNode.type_annotationstay optional, so a kind-stamped item with an Absent body is stillauthorable: every one of those arms keeps a
Presentmatch and REFUSES onAbsent. Reportingthose as closed would be rung inflation.
is_service_item'schildren > 0conjunct meant a zero-operation service reached the residual arm. Corpus census: 123 services,
ZERO with no operations. So the service arm now refuses it explicitly rather than inheriting a
behaviour by accident.
emit_py_typed_item's residualarm rendered
# unhandled node: X-- A COMMENT. An item no predicate claimed was silently omittedfrom the emitted Python module, while the same position in Rust rendered
compile_error!and in Goa panicking
init(). All three now refuse; Python's stop is a module-levelraise.Ledger
gunbc.recurring_failure_mode absence_classifier_default_bucketnamed this change as itsnext-rung trigger. The trigger fired; the row records what the climb covers (the CLASSIFICATION
axis, structurally impossible) and what it does not.
emitter_residual_renders_inert_textfor the Python fail-open -- filed at the moment itdisappears, because a silently repaired defect has a recorded frequency of zero and never ranks
for a wall.
kind_carried_but_its_fields_stay_optionalfor the payload residue, with the per-kind itemcarrier named as its trigger -- the capability, not an artifact.
Evidence
v1.tests.claim.item_kind_dissolves_shape_predicates_control_test: the discriminating RED is a nodesatisfying every conjunct of the old shape predicate while carrying
ModuleItemResource-- theshape-only predicate claimed it, the kind-gated one refuses it. Beside it, the accepted positive
control, which is what stops the RED being satisfied by a predicate that answers false for
everything. Both stay enrolled per section 4b(4). That file is not discovered by CI, for the reason
its two neighbours in the same directory state, and it says so rather than implying enrollment.
Rung
CLASSIFICATION axis: structurally impossible. An item cannot acquire a kind it was not constructed
with, and no item can land in the type bucket by default. PAYLOAD axis: unchanged, mechanically
preventable, rostered with its own trigger. The reported rung is the minimum across the paths.
The ledger rows
absence_classifier_default_bucketanddispatch_correctness_resting_on_arm_order(the rowcodex review 60254 produced on Home the kernel-identity authority beside the minter it asks, instead of above the module that had to re-spell it #10350) both named this change as their next-rung trigger. Both are
updated: the trigger fired, the classification axis reaches STRUCTURALLY IMPOSSIBLE, and each row
records what did NOT climb.
emitter_residual_renders_inert_text— the Python fail-open, filed at the moment itdisappears, because a silently repaired defect has a recorded frequency of zero and never ranks
for a wall. The row carries the fact that it was found by a census taken for another purpose.
kind_carried_but_its_fields_stay_optional— the R2 payload residue, with the per-kind itemcarrier named as the CAPABILITY that retires it.
docs/design-failure-modes.mdis re-derived bygenerated_artifact_gate main_wet_oneafter eachmerge, never hand-resolved; both sides of every roster merge were verified present in the derived
projection by name.
Executed evidence
Everything below was run with a
gunbcbuilt from this tree. The binary on PATH is not usable forthis: it predates §4c source annotations and reports 23363 errors on the current corpus, the first
against a leading
//block indag/extdeps/access/posix.dag.v1.tests.claim.item_kind_dissolves_shape_predicates_control_test— three rows PASS. Thediscriminating row was confirmed RED by the revert arm: restoring the shape-only body of
is_leaf_type_itemin the.dagand re-running the same claim reports FAIL.item_kind_dispatch_totality_test(Rust test tree) — a dispatch omitting one variant is refusedand the refusal names the omitted variant; the full-arm control compiles clean. The same pair was
run against the REAL
ParsedModuleItemKindunder live source roots: refused withnon-exhaustive match: missing variant(s) NotAModuleItem, control PASS.a_resource_item_is_not_read_as_a_type_item, the generated row that landed with Home the kernel-identity authority beside the minter it asks, instead of above the module that had to re-spell it #10350, survivesthe climb restamped with each fixture's kind; its third assertion — that the parse-side and
emit-side readers agree — is deleted, because there is no longer a second reader and an authority
agreeing with itself asserts nothing.
servicedeclarations, zero with no operations.cargo clippy --all-targets -- -D warnings: clean.claim_executor --required-regen: compileclean, drift only in the mirrors of the files this PR changes, all installed from the candidate
tree.
Not caused here, found while verifying
cargo test -p v1-compiler-testshas pre-existing failures on this tree that are not on the mergepath (the rust-unit-tests job was deleted by the 2026-09-04 runner-capacity ruling):
whole_tree_wiring_enum_testpassespool_rootstofn_arrow_decl_facts_live, which has requiredpool_filessince #10245; fourmaterialization_provider_*rows panic onHostBudgetUnreadablebecause the runner exposes no cgroup memory limit.
The declared boundary: none of this evidence executes on the merge path
§4b(1) measures a rung against a declared boundary, so the boundary is declared here rather than
left to be discovered from a log.
.dagcontrols reportstanding=declined-in-declared-non-executing-rooton therequired floor:
changed_witnesses=3 changed_witness_blocking=0 changed_witness_declined_in_declared_nonexecuting_root=3. They exercise v1 compiler types, sotheir home is the
v1prefix, whichgunbc.ci_layer_rootsnon_executing_witness_module_prefixesdeclares non-executing. That is a rostered exemption with its own §4b(2) trigger,
non_executing_witness_module_prefixes_restoration— bare references binding by containment,vehicle the namespace cut — and it is explicitly NOT satisfied by adding
--source-root src/v1to the required fold. Moving the controls out of
v1is not available: the subject theydiscriminate is a v1 type.
item_kind_dispatch_totality_test, is#[ignore]in a test target thatno CI step runs:
cargo test --release -p v1-compiler --libwas deleted with therust-unit-testsjob by the 2026-09-04 runner-capacity ruling (
gunbc.rung_droprust_unit_tests_off_the_merge_path).So: the rung-4 claim rests on evidence that EXECUTED — the refusal on the real
ParsedModuleItemKindunder live source roots, and the revert arm going FAIL — and on nothing thatexecutes on today's merge path. Green, green-that-ran-my-witness, and green-that-keeps-running-it
are three facts; this PR has the first two. Both probes stay enrolled per §4b(4) so that they
execute the moment either declared drop retires; neither is deleted, and neither is cited as
merge-path coverage.