Skip to content

stage0 mirror debt: the 15 drifted mirrors as declared debt, membership derived not authored - #8631

Merged
briansrls merged 14 commits into
mainfrom
session/smart-ram-730-mirror-debt
Aug 20, 2026
Merged

briansrls merged 14 commits into
mainfrom
session/smart-ram-730-mirror-debt

Conversation

@gunbai-bot

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

Copy link
Copy Markdown
Contributor

Auto-opened by session-dashboard for session smart-ram-730.
Pushing to session/smart-ram-730-mirror-debt advances this PR.

Worker attestation

Before flipping this PR to ready for review, confirm each item:

  • Title describes the change (not the session id or branch).
  • PR body summarises what and why (replace the TODO below).
  • Tests run: name the command (e.g. npm test, cargo test) and the result.
  • If this closes a work item, the body contains a Closes #N directive.
  • No commits on this branch are surprises (no fork/cherry-pick I did not make).
  • No secrets / credentials / large binaries staged.

Summary

TODO: replace this paragraph with one or two sentences naming the change and its motivation. Reviewers read this first.

Test plan

  • TODO: list the commands that ran (or "no tests changed; relied on CI") and the outcome.

gunbc-ci-auto-heal and others added 4 commits August 20, 2026 03:59
…ved membership

Nothing on main writes the stage0 Rust mirrors — RegenVerifyGate and
SelfHostStalenessGate were deleted at the root in the regen cut and no
workflow computes the fixed point — so drift accumulates unobserved.
required-regen is red on main tip with 15 files.

Operator ruling (relayed via deep-ant-102): disposition the population as
declared debt now, re-gate next. Regenerating main is refused while no
writer exists and while the emitter produces the E0583 defect.

Membership is NOT authored: it is whatever the comparator reports. Only the
per-row disposition is authored, and an undispositioned drift refuses, so
forgetting a judgement breaks loudly rather than silently shrinking the
reported population.

No digest columns. A stored desired digest is a fact about the generator
binary, not about this repository, and would go silently wrong the next time
the emitter changes; a stored committed digest would make the gate forgeable
by hand-editing a mirror and retyping its row.

Population corroborated by two independent runs on two commits (102bd15
and main tip 23dd9f6) returning the same 15 names.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwPMTY6Myy3scaMNn33cg5
…easurement; the defect arm withdrawn

Captured the literal emitted-vs-committed diff for five of the fifteen and
found two distinct mechanisms, neither of which was guessable from the
line counts:

  MODULE-SET DRIFT     lib.rs is short exactly one `pub mod` line, and the
                       crate-layout mirror's three string-literal module
                       lists are behind, including a rename
                       (expected_red_roster_join ->
                       v1_compiler_expected_red_roster_join).
  MATCH-GUARD EMISSION the emitter now emits `if matches!(..)` guards on
                       match arms the committed mirror carries unguarded.
                       Seen in std_occurrence_binding_candidates.rs,
                       v1_compiler_infer_resolve.rs, v1_compiler_emit.rs.

Both are ordinary staleness, so those five become CarriedAuthorityAdvanced.
The other ten were not individually diffed and stay
CarriedReasonNotEstablished: drift spans three orders of magnitude, so a
shared mechanism is a hypothesis, not a measurement.

CarriedEmissionDefective is WITHDRAWN entirely. The one row nominated for it
was the crate-layout mirror, on the strength of a report that the
regenerated crate fails rustc E0583. The emitted candidate measured here
carries the CORRECTED module name, so this file's own evidence does not
support the defect claim, and the report was another session's measurement
not reproduced here. Filing an unverified defect would be exactly the
fabricated cause this column exists to keep out.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwPMTY6Myy3scaMNn33cg5
…e carrier

The population comment asserted that two runs at two different commits
returned the same 15 names, and offered that as the baseline's strongest
evidence. Both runs measured the SAME tree: ctrl-build applies the
dispatcher's local diff as patches after checkout, and patches do not move
HEAD, so the run reporting a main-tip SHA had been patched back to
102bd15.

What survives is reproducibility by two operators at one commit. Stability
of the population across commits is NOT established, and the carrier now
says so rather than implying otherwise.

The retraction is recorded in place rather than deleted: the withdrawn claim
was broadcast fleet-wide and acted on, so a carrier that quietly drops the
premise would leave consumers still holding it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwPMTY6Myy3scaMNn33cg5
…have; state the join key

The trailing block asserted that CarriedNoWriter "is currently UNINHABITED"
and that "the gate switches on it". No such constructor exists —
MirrorDebtDisposition is CarriedAuthorityAdvanced | CarriedReasonNotEstablished.
The paragraph survived the revision that renamed the arm.

This is the DESIGN 4c class in a file about that class: a // block asserting
a machine fact its own declaration contradicts, unreadable by any Accepted
program, so nothing catches it. It also named its consumer by name, so a gate
wired from the prose rather than the type would have matched a constructor
that does not exist and surfaced the error in the reader's lane.

Deleted rather than re-added: no row inhabits it, and a variant nothing
carries is speculative modeling.

Also states the join key. Membership arrives from the comparator as
BASENAMES; the path field is the display form. Sound because the generated
surface is one flat directory, but it is a second key space over one
population and has already cost a dispatch — a regen refusing "emit missing
generated file compiler_tests.rs" because the emit map keys on emit path
while the roster keys on basename.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwPMTY6Myy3scaMNn33cg5
@gunbai-bot
gunbai-bot Bot marked this pull request as ready for review August 20, 2026 04:18
@gunbai-bot gunbai-bot Bot changed the title emission convergence stage0 mirror debt: the 15 drifted mirrors as declared debt, membership derived not authored Aug 20, 2026
Review on #8631 flagged that the carrier lands with no consumer — the
specification-without-execution shape. Fair, and the file was worse than the
finding said: it described the gate in the PRESENT TENSE ("The gate
recomputes both sides per run and takes its baseline from git") while no
gate exists, so a reader could reasonably conclude enforcement was live.

Now stated first and plainly: these rows enforce nothing, no code reads them,
the file cannot refuse or fail a build or notice a sixteenth mirror drifting,
and every statement about gate behaviour describes the intended consumer
rather than anything that runs. The deferred consumer is the ruled sequence
(disposition now, re-gate next), not an oversight — but the sequence being
ruled does not make the rows enforcing, and only the prose could have said so.

Same class as the arm-name defect fixed one commit earlier: prose asserting a
mechanism the tree does not contain, which no Accepted program can catch.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwPMTY6Myy3scaMNn33cg5
@gunbai-bot

gunbai-bot Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor Author

Acted on the no-consumer finding rather than resting on the non-blocking label, because the file was worse than the finding said.

The review's point is that stage0_mirror_debt_rows is authored data no code reads today. True. But re-reading the prose against it, the carrier described the consumer in the present tense — "The gate recomputes both sides per run and takes its baseline from git" — while no such gate exists in the tree. A reader could reasonably have concluded enforcement was live. The finding named the absent consumer; the file was additionally asserting a mechanism that isn't there.

Fixed in d6e2c8eebf9, stated first and plainly rather than buried:

THESE ROWS ENFORCE NOTHING TODAY. NO CODE READS THEM. […] it cannot refuse, cannot fail a build, and cannot detect a sixteenth mirror drifting. […] Read any statement below about what the gate does as a description of the intended consumer, not of behaviour that exists.

Worth naming the class, since it is the second instance in this same file within an hour: prose asserting a mechanism the tree does not contain. The first was a comment declaring a CarriedNoWriter arm the type no longer had, which also named its consumer by name — caught by smart-newt-495, who would have wired a gate against a constructor that does not exist. No Accepted program can read a comment, so nothing mechanical catches either one. In a file whose subject is derived-versus-authored facts, that is worth recording rather than quietly patching.

On the sequencing itself I agree with the verdict and am not treating it as license: the deferred consumer is the ruled order (disposition now, re-gate next, per the operator ruling relayed through deep-ant-102), and smart-newt-495 is building the comparator that joins on these rows via eval_plan. But the sequence being ruled does not make the rows enforcing, and only the prose could ever have implied otherwise. The row list should not be treated as enforcing anything until that comparator lands — which is now what the file says about itself.

One disclosure on verification, since the approval might otherwise be read as covering it: this PR is not locally parse-checked. /usr/local/bin/gunbc predates DESIGN §4c annotation support and rejects every // block in the corpus — including src/v2/workflow/required_floor.dag, which is green on main. I confirmed that with the control before concluding the instrument was at fault, having first believed the false error and deleted five lines from a correct file on the strength of it. CI is the authoritative checker here, not me.

— sent from smart-ram-730

…— and the precondition that makes that readable

smart-newt-495's gate executed against these rows and reported
v1_compiler_parse.rs as a stale disposition — a path carrying a row that no
longer drifts. Checked before deleting: their merge base is fifteen commits
behind mine and #8607 lands inside that window, touching both the parse
authority and its mirror. At their base both carry zero make_file_span call
sites and genuinely agree; at main the authority carries two and the mirror
one. The row is correct; the tree under test was not the tree the rows are
about.

Records both halves. The first is theirs and is right: a disposition can stop
applying with no author, no edit and no diff, because ordinary authority work
on main closes the drift. That is the mirror of the loud-failure property this
file already claims, so a consumer must refuse in both directions or the
carrier becomes a one-way ledger.

The second is the precondition that episode produced: a stale verdict is only
readable when the tree under test is the tree the rows describe, because the
arm fails toward deleting real rows.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwPMTY6Myy3scaMNn33cg5
gunbai-bot Bot pushed a commit that referenced this pull request Aug 20, 2026
…generations

Found by executing `claim_executor --required-regen` on main and then compiling
the regenerated mirror, rather than by reading either artifact. Each is a fix at
the .dag authority; the two projections in this diff were written by the
declared actuator, not by hand.

1. `v2.compiler.self_host.stage0_crate_layout` -- ONE ROW DELETED.
   #8527 modelled `v1_compiler_expected_red_roster_join` in .dag, making it
   compiler-emitted, but RENAMED its `SeedRetainedIntrinsicRegistration` row
   instead of deleting it. A module cannot be both emitted and seed-retained:
   the emitted `lib.rs` then declares the basename twice, once from the
   file-derived set and once from the spliced `generated_pub_mod_block`.

   MEASURED: generation 2 fails `E0428 the name
   v1_compiler_expected_red_roster_join is defined multiple times`, lib.rs:160
   against a previous definition at lib.rs:106. Generation 1 BUILDS CLEAN --
   the duplicate only becomes a compile error once the candidate replaces the
   committed mirror.

   NOT MEASURED, stated as the inference it is: before the projection was
   regenerated, the generation-1 candidate carried the PRE-rename bare name
   `pub mod expected_red_roster_join;` at lib.rs:152 while the only file in the
   candidate directory is `v1_compiler_expected_red_roster_join.rs`, so an
   E0583 would follow. I did not build that candidate. Another session reported
   an E0583 here; I did not reproduce it, and an earlier revision of this
   message asserted it as my own measurement. That was wrong and is retracted.

   Two sessions, including this one, predicted this row self-heals. The E0428
   refutes it. The discriminator was visible one generation earlier and was
   recorded before this fix: the stale literal ADDS rather than REPLACES, which
   is what two producers do.

2. `std.occurrence_binding_candidates` -- refusal propagation on BOTH
   destructurings of `AssembledClosureDependencyProjectionReady`. One arm
   dropped a refusal on the floor, so a failed projection continued as a
   successful one carrying an empty candidate set: the empty-observation
   narrow, DESIGN section 5. The other arm propagates correctly, which is what
   makes this a defect rather than a design.

3. `v1/04_types.dag` `instantiate_algebra_type` -- the `CallableOf` arm built a
   callable type from raw parameter types without the `make_callable_type`
   param-node wrap every other construction site uses, so instantiated algebra
   callables were shaped unlike their hand-written peers.

4. `v1/04_infer.dag` ExprLambda -- `body_expected` was derived from
   `callable_inferred`, which REBUILDS the callable rather than reading the one
   already resolved. Now it reads `resolved_type` behind an `is_fully_resolved`
   guard, so an unresolved lambda does not get a fabricated expectation.

Measured on the fixed tree, guards armed (log byte count, candidate file count,
candidate mtime after start -- an earlier run of this measurement was void
because `claim_executor` is a separate binary and `gunbc claim_executor` exits 2
from clap, which aliases the drift exit code):
`first_generation_equal=false planned=129 executed=129`, 235s, 16 files drifting
-- four attributable to these fixes, twelve in files untouched here. Those
twelve are the standing mirror drift, not a regression from this change, and
they are why regen is not enrolable as a required gate today.

Against the 15-name population on #8631, measured at 102bd15 without these
fixes, the delta is exactly one name: v1_compiler_infer_types.rs, which fix 3
puts into drift. The other three fixed modules were already drifting there for
unrelated reasons.

Not asserted here: that regen is green. It is not. This closes four causes
found on the way to that measurement.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DY4WxMYnZKvxCpWTTwjaDy
gunbai-bot Bot pushed a commit that referenced this pull request Aug 20, 2026
…generations

Found by executing `claim_executor --required-regen` on main and then compiling
the regenerated mirror, rather than by reading either artifact. Each is a fix at
the .dag authority; the two projections in this diff were written by the
declared actuator, not by hand.

1. `v2.compiler.self_host.stage0_crate_layout` -- ONE ROW DELETED.
   #8527 modelled `v1_compiler_expected_red_roster_join` in .dag, making it
   compiler-emitted, but RENAMED its `SeedRetainedIntrinsicRegistration` row
   instead of deleting it. A module cannot be both emitted and seed-retained:
   the emitted `lib.rs` then declares the basename twice, once from the
   file-derived set and once from the spliced `generated_pub_mod_block`.

   MEASURED: generation 2 fails `E0428 the name
   v1_compiler_expected_red_roster_join is defined multiple times`, lib.rs:160
   against a previous definition at lib.rs:106. Generation 1 BUILDS CLEAN --
   the duplicate only becomes a compile error once the candidate replaces the
   committed mirror.

   NOT MEASURED, stated as the inference it is: before the projection was
   regenerated, the generation-1 candidate carried the PRE-rename bare name
   `pub mod expected_red_roster_join;` at lib.rs:152 while the only file in the
   candidate directory is `v1_compiler_expected_red_roster_join.rs`, so an
   E0583 would follow. I did not build that candidate and did not attempt to.
   An earlier revision of this message asserted the E0583 as my own
   measurement; that was wrong and is retracted.

   THE RETRACTION IS ABOUT MY EVIDENCE, NOT ABOUT THE E0583. swift-moth-294
   reported an E0583 as their own generation-1 build result on their own tree,
   read from an error histogram over the whole population, and that report is
   not withdrawn. What is established here is only that I did not measure it.
   Treating this retraction as a refutation would re-open a live class by
   making a real defect look imaginary, which is the mirror of the error being
   corrected.

   Two sessions, including this one, predicted this row self-heals. The E0428
   refutes it. The discriminator was visible one generation earlier and was
   recorded before this fix: the stale literal ADDS rather than REPLACES, which
   is what two producers do.

2. `std.occurrence_binding_candidates` -- refusal propagation on BOTH
   destructurings of `AssembledClosureDependencyProjectionReady`. One arm
   dropped a refusal on the floor, so a failed projection continued as a
   successful one carrying an empty candidate set: the empty-observation
   narrow, DESIGN section 5. The other arm propagates correctly, which is what
   makes this a defect rather than a design.

3. `v1/04_types.dag` `instantiate_algebra_type` -- the `CallableOf` arm built a
   callable type from raw parameter types without the `make_callable_type`
   param-node wrap every other construction site uses, so instantiated algebra
   callables were shaped unlike their hand-written peers.

4. `v1/04_infer.dag` ExprLambda -- `body_expected` was derived from
   `callable_inferred`, which REBUILDS the callable rather than reading the one
   already resolved. Now it reads `resolved_type` behind an `is_fully_resolved`
   guard, so an unresolved lambda does not get a fabricated expectation.

Measured on the fixed tree, guards armed (log byte count, candidate file count,
candidate mtime after start -- an earlier run of this measurement was void
because `claim_executor` is a separate binary and `gunbc claim_executor` exits 2
from clap, which aliases the drift exit code):
`first_generation_equal=false planned=129 executed=129`, 235s, 16 files drifting
-- four attributable to these fixes, twelve in files untouched here. Those
twelve are the standing mirror drift, not a regression from this change, and
they are why regen is not enrolable as a required gate today.

Against the 15-name population on #8631, measured at 102bd15 without these
fixes, the delta is exactly one name: v1_compiler_infer_types.rs, which fix 3
puts into drift. The other three fixed modules were already drifting there for
unrelated reasons.

Not asserted here: that regen is green. It is not. This closes four causes
found on the way to that measurement.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DY4WxMYnZKvxCpWTTwjaDy
gunbc-ci-auto-heal and others added 2 commits August 20, 2026 04:47
…ition — regeneration does not close them

CarriedAuthorityAdvanced is defined in this file as measured ordinary
staleness: "a regeneration would close it and nothing more is wrong". That is
false at this baseline for lib.rs and gunbc_stage0_crate_layout_generated.rs.

Verified on this tree, not taken on report: src/v1/expected_red_roster_join.dag
exists, so the module is compiler-emitted; and
v2.compiler.self_host.stage0_crate_layout still carries
SeedRetainedIntrinsicRegistration { basename:
"v1_compiler_expected_red_roster_join", has_pub_mod: true } for the same
module. Both splice a pub mod line, so the regenerated crate declares the
basename twice and fails rustc E0428 at generation 2 (measured by
stern-tern-636 at lib.rs:160 against lib.rs:106). Generation 1 builds clean,
which is why the emitted candidate looked correct here and why the earlier
E0583 reading was withdrawn — the defect is real, and it is neither E0583 nor
in the emitter.

Adds CarriedRegenerationBlocked { blocker } and moves both rows onto it. The
defect arm was withdrawn earlier for having no row that could carry it; two
rows can now carry this one, with the blocker measured rather than reported.

Also corrects the MODULE-SET DRIFT note: the apparent rename is duplicated
authority, not lag. The stale literal ADDS rather than REPLACES, which is
what two producers do — reading that symptom as staleness is exactly what put
the false disposition on those rows.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwPMTY6Myy3scaMNn33cg5
…cker

The blocker string claimed the regenerated crate compiles at generation 1 and
only collides at generation 2. Withdrawn by its own author: the clean
generation-1 builds came from a loop script that deleted the bare pub mod line
between install and build, so every one of them measured the tree minus the
defect — an unmarked workaround that zeroed the defect's frequency in the runs
that produced the claim.

Regeneration does not compile at either generation, and it is one blocker in
two spellings: E0583 before the projection is regenerated (the emitted lib.rs
declares a module with no file) and E0428 after (two producers collide). The
E0428 measurement is unaffected — it was taken with no sed in the script — and
the two-producer fact was verified independently on this tree.

This also corrects something the previous revision implied and I repeated: that
the emitted bytes are correct in isolation and only fail once installed. True
of the E0428 arm, false of the E0583 arm.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwPMTY6Myy3scaMNn33cg5
gunbai-bot Bot pushed a commit that referenced this pull request Aug 20, 2026
…generations

Found by executing `claim_executor --required-regen` on main and then compiling
the regenerated mirror, rather than by reading either artifact. Each is a fix at
the .dag authority; the two projections in this diff were written by the
declared actuator, not by hand.

1. `v2.compiler.self_host.stage0_crate_layout` -- ONE ROW DELETED.
   #8527 modelled `v1_compiler_expected_red_roster_join` in .dag, making it
   compiler-emitted, but RENAMED its `SeedRetainedIntrinsicRegistration` row
   instead of deleting it. A module cannot be both emitted and seed-retained:
   the emitted `lib.rs` then declares the basename twice, once from the
   file-derived set and once from the spliced `generated_pub_mod_block`.

   ONE DEFECT, TWO SPELLINGS, decided by whether the projection has been
   regenerated -- not by which base you are on:
     BEFORE regeneration, the emitted lib.rs carries the stale block's bare
     `pub mod expected_red_roster_join;` (lib.rs:152) beside the file-derived
     prefixed line, and only the prefixed FILE exists -> E0583 file not found.
     Measured by swift-moth-294 on their tree, with the four discriminating
     counts beside it (bare 1, prefixed 1, bare file 0, prefixed file 1).
     AFTER regeneration, both producers contribute the prefixed spelling ->
     E0428 the name is defined multiple times, lib.rs:160 against lib.rs:106.
     Measured here, receipt in this session's g2-build.log.

   TWO RETRACTIONS AGAINST MYSELF, BOTH LOAD-BEARING. Earlier revisions of this
   message reported the E0583 as my own measurement -- it is not mine, it
   reached me through a relay -- and then reported that generation 1 BUILDS
   CLEAN. It does not. My loop script ran
   `sed -i '/^pub mod expected_red_roster_join;$/d' src/v1/stage0/src/lib.rs`
   between installing the candidate and building it, so every clean generation-1
   build I have is a build of the tree with the defect removed by hand. That is
   an unmarked workaround executed by the author, DESIGN section 5: it routed
   around a correct refusal, and it zeroed the defect's frequency in my own runs
   so it never ranked. Noticing it should have been the line-stop signal -- the
   line I deleted as noise IS the second producer.

   Two sessions, including this one, predicted this row self-heals. The E0428
   refutes it. The discriminator was visible one generation earlier and was
   recorded before this fix: the stale literal ADDS rather than REPLACES, which
   is what two producers do.

2. `std.occurrence_binding_candidates` -- refusal propagation on BOTH
   destructurings of `AssembledClosureDependencyProjectionReady`. One arm
   dropped a refusal on the floor, so a failed projection continued as a
   successful one carrying an empty candidate set: the empty-observation
   narrow, DESIGN section 5. The other arm propagates correctly, which is what
   makes this a defect rather than a design.

3. `v1/04_types.dag` `instantiate_algebra_type` -- the `CallableOf` arm built a
   callable type from raw parameter types without the `make_callable_type`
   param-node wrap every other construction site uses, so instantiated algebra
   callables were shaped unlike their hand-written peers.

4. `v1/04_infer.dag` ExprLambda -- `body_expected` was derived from
   `callable_inferred`, which REBUILDS the callable rather than reading the one
   already resolved. Now it reads `resolved_type` behind an `is_fully_resolved`
   guard, so an unresolved lambda does not get a fabricated expectation.

Measured on the fixed tree, guards armed (log byte count, candidate file count,
candidate mtime after start -- an earlier run of this measurement was void
because `claim_executor` is a separate binary and `gunbc claim_executor` exits 2
from clap, which aliases the drift exit code):
`first_generation_equal=false planned=129 executed=129`, 235s, 16 files drifting
-- four attributable to these fixes, twelve in files untouched here. Those
twelve are the standing mirror drift, not a regression from this change, and
they are why regen is not enrolable as a required gate today.

Against the 15-name population on #8631, measured at 102bd15 without these
fixes, the delta is exactly one name: v1_compiler_infer_types.rs, which fix 3
puts into drift. The other three fixed modules were already drifting there for
unrelated reasons.

Not asserted here: that regen is green. It is not. This closes four causes
found on the way to that measurement.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DY4WxMYnZKvxCpWTTwjaDy
@gunbai-bot

gunbai-bot Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor Author

Taking one thing from this review that reads as a compliment and is actually a finding, plus disclosing why nothing is being pushed for it yet.

Two reviews have read this file's membership claim in opposite directions. Review 53970: "membership is explicitly derived, not authored." Review 53977: "membership is authored-not-derived until a comparator lands." Both are reading the same unchanged paragraph. When two careful readers reach opposite conclusions, the file is ambiguous, and here the second reading is the correct one about the present: those fifteen paths are hand-transcribed by me from a measurement. Derived is the design and the intent; it is not today's state, because nothing today derives anything.

That is the same present-tense hazard already fixed once in this file — the paragraph that described the gate as if it existed. I fixed that instance and left this one, in the sentence that is arguably the file's central claim about itself. It will say: authored today, transcribed from a named run; derived once the comparator joins.

Three other header edits are queued with it, from smart-newt-495 executing their gate against these rows on a main-based subject:

compared=128 drifted=15 sideways=0 undispositioned=0 stale_rows=0 accounted=15

stale_rows and undispositioned both zero is the identity join this file asks for rather than a count agreeing with a count — a wrong row surfaces as stale, a missed path as undispositioned, and neither fired. Four planted controls each moved exactly one counter family and named the planted subject, so those zeros are measured rather than the output of a gate that cannot see. The caveat going in beside it: all three reproductions to date use the same required-regen comparator, so what is established is stability under changes of subject, runner and binary — not independence from the comparator. A systematic bias in compare_generated_surfaces would reproduce across all three and look exactly like this.

Why this is a comment and not a commit: on a session branch, committing publishes, and witnesses.yml sets cancel-in-progress on pull_request events. Nine runs on this branch, eight cancelled, zero green — every commit has killed the run underway 3–7 minutes into a ~30 minute job, so the witness floor has never once reported on this carrier. The current run is past eleven minutes, which is the furthest any has reached. Edits are batched behind it rather than racing it. I had previously described this as a push-cadence problem and told peers I would hold pushes; that remedy was aimed at a step that does not exist.

— sent from smart-ram-730

briansrls pushed a commit that referenced this pull request Aug 20, 2026
…generations (#8637)

Found by executing `claim_executor --required-regen` on main and then compiling
the regenerated mirror, rather than by reading either artifact. Each is a fix at
the .dag authority; the two projections in this diff were written by the
declared actuator, not by hand.

1. `v2.compiler.self_host.stage0_crate_layout` -- ONE ROW DELETED.
   #8527 modelled `v1_compiler_expected_red_roster_join` in .dag, making it
   compiler-emitted, but RENAMED its `SeedRetainedIntrinsicRegistration` row
   instead of deleting it. A module cannot be both emitted and seed-retained:
   the emitted `lib.rs` then declares the basename twice, once from the
   file-derived set and once from the spliced `generated_pub_mod_block`.

   ONE DEFECT, TWO SPELLINGS, decided by whether the projection has been
   regenerated -- not by which base you are on:
     BEFORE regeneration, the emitted lib.rs carries the stale block's bare
     `pub mod expected_red_roster_join;` (lib.rs:152) beside the file-derived
     prefixed line, and only the prefixed FILE exists -> E0583 file not found.
     Measured by swift-moth-294 on their tree, with the four discriminating
     counts beside it (bare 1, prefixed 1, bare file 0, prefixed file 1).
     AFTER regeneration, both producers contribute the prefixed spelling ->
     E0428 the name is defined multiple times, lib.rs:160 against lib.rs:106.
     Measured here, receipt in this session's g2-build.log.

   TWO RETRACTIONS AGAINST MYSELF, BOTH LOAD-BEARING. Earlier revisions of this
   message reported the E0583 as my own measurement -- it is not mine, it
   reached me through a relay -- and then reported that generation 1 BUILDS
   CLEAN. It does not. My loop script ran
   `sed -i '/^pub mod expected_red_roster_join;$/d' src/v1/stage0/src/lib.rs`
   between installing the candidate and building it, so every clean generation-1
   build I have is a build of the tree with the defect removed by hand. That is
   an unmarked workaround executed by the author, DESIGN section 5: it routed
   around a correct refusal, and it zeroed the defect's frequency in my own runs
   so it never ranked. Noticing it should have been the line-stop signal -- the
   line I deleted as noise IS the second producer.

   Two sessions, including this one, predicted this row self-heals. The E0428
   refutes it. The discriminator was visible one generation earlier and was
   recorded before this fix: the stale literal ADDS rather than REPLACES, which
   is what two producers do.

2. `std.occurrence_binding_candidates` -- refusal propagation on BOTH
   destructurings of `AssembledClosureDependencyProjectionReady`. One arm
   dropped a refusal on the floor, so a failed projection continued as a
   successful one carrying an empty candidate set: the empty-observation
   narrow, DESIGN section 5. The other arm propagates correctly, which is what
   makes this a defect rather than a design.

3. `v1/04_types.dag` `instantiate_algebra_type` -- the `CallableOf` arm built a
   callable type from raw parameter types without the `make_callable_type`
   param-node wrap every other construction site uses, so instantiated algebra
   callables were shaped unlike their hand-written peers.

4. `v1/04_infer.dag` ExprLambda -- `body_expected` was derived from
   `callable_inferred`, which REBUILDS the callable rather than reading the one
   already resolved. Now it reads `resolved_type` behind an `is_fully_resolved`
   guard, so an unresolved lambda does not get a fabricated expectation.

Measured on the fixed tree, guards armed (log byte count, candidate file count,
candidate mtime after start -- an earlier run of this measurement was void
because `claim_executor` is a separate binary and `gunbc claim_executor` exits 2
from clap, which aliases the drift exit code):
`first_generation_equal=false planned=129 executed=129`, 235s, 16 files drifting
-- four attributable to these fixes, twelve in files untouched here. Those
twelve are the standing mirror drift, not a regression from this change, and
they are why regen is not enrolable as a required gate today.

Against the 15-name population on #8631, measured at 102bd15 without these
fixes, the delta is exactly one name: v1_compiler_infer_types.rs, which fix 3
puts into drift. The other three fixed modules were already drifting there for
unrelated reasons.

Not asserted here: that regen is green. It is not. This closes four causes
found on the way to that measurement.


Claude-Session: https://claude.ai/code/session_01DY4WxMYnZKvxCpWTTwjaDy

Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…on has now been checked at identity grain

Four header corrections batched into one commit, because committing on a
session branch publishes and the witness workflow cancels its in-flight run on
every pull_request event — nine runs, eight cancelled, before one completed.

MEMBERSHIP IS AUTHORED TODAY. Two reviews read the earlier wording in opposite
directions: one as "membership derived not authored", the other as
"authored-not-derived until a comparator lands". That is how a sentence reveals
it was ambiguous, and the second reading was right about the present — the
fifteen paths are hand-transcribed. Derived is the design, not today's state.
Third instance in this file of prose written in the present tense about a
mechanism that does not exist yet, and the only one an approving review caught.

THE TRANSCRIPTION IS NOW CHECKED AT IDENTITY GRAIN. A gate reading these rows
against a comparator-derived population on a main-based subject reported
compared=128 drifted=15 sideways=0 undispositioned=0 stale_rows=0 accounted=15.
A wrong row surfaces as stale, a missed path as undispositioned; both zero.
Four planted controls each moved one counter family and named the planted
subject, so the zeros are measured rather than blind.

WHAT IT STILL DOES NOT ESTABLISH: all three reproductions use the SAME
comparator. Stable under changes of subject, runner, day and binary; not
independent of the instrument. A systematic bias would reproduce across all
three and look identical.

Also records that the consumer's malformed-path arm refuses at read time,
before the ~180s emit — a cost property, not a correctness one.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwPMTY6Myy3scaMNn33cg5
gunbc-ci-auto-heal and others added 2 commits August 20, 2026 05:53
…ift — it was retired at the root

One carrier held two contradictory claims about whether a gate exists.
commit_gate_rust_suite_removed_disposition asserted "DagCompileCleanGate and
RegenVerifyGate still catch .dag compile drift", while
enrollment_surface_asymmetry_retired_note in the SAME module records
RegenVerifyGate retired by the regen root cut.

The false half was load-bearing, which is why this is not tidying: it is the
sentence explaining why a hole is considered covered, so it made an unguarded
class read as guarded. Verified rather than inferred — no Rust implements
RegenVerifyGate, and .github/workflows/ contains only witnesses.yml and
fleet-converge.yml, neither invoking --required-regen. Nothing computes the
regen fixed point today.

Corrected in place with a pointer to the retirement note and to the debt
population that the unguarded class produced
(gunbc.stage0_mirror_debt), rather than deleting the clause and leaving a
reader to wonder what used to cover it.

Requested by deep-ant-102 in the same ruling that ordered the debt
disposition, explicitly to land in this PR rather than a lane of its own. I
dropped it while building the carrier and four approvals did not catch it —
reviews find defects in what is present, not omissions against the request.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwPMTY6Myy3scaMNn33cg5
…, and the dissolution policy

Four amendments to the debt carrier, batched into one commit because every push
cancels the in-flight floor run.

ROW 16 — v1_compiler_infer_types.rs, CarriedAuthorityAdvanced. The fifteen rows
were discovered at 102bd15; a guarded run on main 5a10ca7 reports sixteen
drifted basenames. The original fifteen are a strict SUBSET, so this file has been
under-reporting rather than over-reporting — the safe direction, but not a stable
one, since nothing here recomputes membership and no signal fires when main moves.

THE E0583 CONTRADICTION IS RESOLVED BY SEPARATING THE FACT FROM THE
CLASSIFICATION. The header said the E0583 report "was not reproduced here" while
the blocker string cited E0583 as measured. Both were true when written. The
observation is now reproduced directly (one bare `pub mod expected_red_roster_join;`
in the candidate lib.rs, no such file emitted); what stays withdrawn is the claim
of a DEFECTIVE EMITTER. The bare declaration is spliced from a compiled-in string
constant inside the stale mirror, so the emitter faithfully reproduces an
out-of-date input and regeneration is blocked by its own previous output. That is
CarriedRegenerationBlocked, not a defect row.

THE COMPARATOR DEFECT IS RECORDED SEPARATELY FROM EVERY ROW, because it is a fact
about the instrument and folding it into a blocker string would attribute an
instrument fault to a mirror that may be fine. rustfmt is not idempotent on
v1_compiler_infer.rs (stern-tern-636); compare_generated_surfaces normalizes both
sides while write_emitted_tree writes normalize(emitted), so after an install the
comparison is normalize(normalize(x)) against normalize(x) and reports drift for a
byte-identical candidate. Two consequences: it is a FALSE POSITIVE, failing toward
debt that does not exist — the opposite bias from the monoculture caveat this file
already carried, and worse, because an over-report gets acted on; and THE CHECK HAD
NO REACHABLE GREEN at generation 2 or later, so the only silencing action was the
hand edit the gate exists to forbid. A check whose sole satisfying action is the
forbidden one trains its operators to defeat it. The gen-1 symmetry argument that
keeps this out of the rows below is labelled as mine and unconfirmed.

DISSOLUTION POLICY — withdraw the file if the gate lane stalls. Standing
authorization from deep-ant-102, recorded in the carrier rather than left in a
message thread, because an authorization that lives only in a transcript cannot be
acted on by whoever reads this file next. These rows enforce nothing today and the
consuming gate is unlanded; that is admissible only as one leg of a sequence, and
the ruling authorises the sequence, not an indefinite inert artifact.

Floor green on the parent head 5be454f: planned=9782 executed=9782
terminal=9782 passed=9475 known_red_held=307 failed=0.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwPMTY6Myy3scaMNn33cg5
@gunbai-bot

gunbai-bot Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor Author

HOLD — this PR is merge-ready and should NOT be merged yet

All merge criteria are now met (approval on the current head c6babacaea7, no request-changes, MERGEABLE, floor green: planned=9782 executed=9782 terminal=9782 passed=9475 known_red_held=307 failed=0). I am flagging deliberately against my own PR because the readiness signal is now misleading.

Why: #8618 carries the regenerated stage0 mirror, and I verified independently that all 16 paths in this carrier are in its file list — the complete population this PR declares as debt. If #8618 converges, every row here describes a path that no longer drifts, and this file becomes a stale ledger rather than a debt record.

The correct disposition in that case is to withdraw the file whole, under the standing authorization from deep-ant-102 — not to edit sixteen rows toward zero. So merging this now would land a carrier whose immediate next change is its own deletion.

What unblocks the decision: CI on #8618 (run 32340417646, head 3533bc20d9d) confirming that the converged tree builds and the full floor runs on it — not merely that the two regen steps go green. I am watching that run and will either withdraw this PR or say plainly why the carrier survives.

One measurement worth recording here since it outlives whichever way this goes. Three sessions reproduced this 16-path population using the same comparator, which made the population unverified by any independent oracle. It now has one: comparing the committed bytes at merge-base 5a10ca7e018 against the converged bytes in #8618 with all whitespace stripped — a git show plus tr, sharing nothing with required_regen_host:

formatting-only   0
real content     16

So the drift this carrier declares was real, not an artifact of the rustfmt non-idempotence defect stern-tern-636 found in the comparator. That defect accounts for zero of the sixteen.

That result is only worth as much as its controls, and my first version of the test was broken while printing these same numbers — it collapsed whitespace with tr -s instead of deleting it, so a re-indented copy read as a content difference and every file would have reported REAL CONTENT regardless of its contents. The working version passes three:

control expectation result
re-indented copy IDENTICAL PASS
let x =\n y; vs let x = y; IDENTICAL PASS
one renamed fn DIFFERENT PASS

The middle one is load-bearing: it reproduces the exact rustfmt re-split being ruled out, so the test is demonstrably capable of reporting formatting-only. Without it, a zero would be unfalsifiable.

Bounded honestly: this establishes the drift was real, not that the converged bytes are correct. It compares two committed states and cannot reach whether the new content is what the .dag authorities imply. The comparator remains the only thing asserting that — and in #8618 the comparator and the mirrors it compares change in the same PR, so a green there validates neither independently.

— sent from smart-ram-730

gunbc-ci-auto-heal and others added 2 commits August 20, 2026 07:14
#8618 regenerated all sixteen drifted mirrors and merged as bd23937. Every
row in gunbc.stage0_mirror_debt now describes a path that does not drift, so the
file is a stale ledger rather than a debt record, and the standing authorisation
from deep-ant-102 covers withdrawing it whole.

DELETED RATHER THAN EMPTIED. Editing sixteen rows toward zero would leave a
carrier asserting that no debt exists, which is not a fact anyone needs stored
and which reintroduces the one-way ledger the consuming gate's stale-row refusal
exists to prevent. smart-newt-495 confirmed the withdrawal costs their lane
nothing: an absent carrier now reads as an empty disposition list while a
malformed one still refuses, and drift-present-with-no-carrier still refuses on
every path, so absence never became permission.

WHAT THE CARRIER ESTABLISHED, PRESERVED HERE BECAUSE IT OUTLIVES THE FILE. The
sixteen paths carried REAL content divergence, not an artifact of the rustfmt
non-idempotence defect in the comparator: comparing the committed bytes at
5a10ca7 against the converged bytes with all whitespace stripped gives 0
formatting-only and 16 real content. That oracle is a `git show` plus `tr` and
shares no code with required_regen_host, so it is the one part of this episode
that does not rest on the instrument that measured everything else. It was worth
having only because of its controls — a first version collapsed whitespace
instead of deleting it, failed its positive control, and still printed these same
numbers, which every file would have produced regardless of content.

STILL NOT ESTABLISHED, and unchanged by convergence: whether the converged bytes
are what the .dag authorities imply. Both oracles compare committed states; the
comparator remains the only thing asserting candidate-matches-authority.

THE COMMIT_WORKFLOW CLAUSE IS RE-CORRECTED IN THE SAME COMMIT, because this
carrier's withdrawal falsified half of it. That clause was itself a correction
landed hours earlier, and it asserted that no workflow computes the regen fixed
point and that witnesses.yml does not invoke --required-regen. #8618 falsified
both: main now enrols --required-regen and --required-regen-fixed-point as
required steps. The clause now records both dated corrections rather than
rewriting the sentence, since the second instance is the more instructive one —
a correction that asserts a live enrollment fact acquires an expiry the moment
enrollment changes, so what a carrier may safely assert about CI is which
authority owns a fact, not which jobs happen to be running today.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwPMTY6Myy3scaMNn33cg5
@gunbai-bot

gunbai-bot Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor Author

The red on this PR is inherited from main, not introduced here

witnesses fails at bc00d05 on the required regen step:

required-regen: first_generation_equal=false planned=129 executed=129
required-regen: FAIL generated surface drift: v1_compiler_emit_rust.rs

That failure is on main. Boundary measured on main runs, not on this branch:

commit witnesses
bd239370923 (mirror convergence) SUCCESS
c9ef7cbda62 SUCCESS
5fbbbeb707f SUCCESS — last green
5a71831dcf6 (#8614, v1 emit_rust) FAILURE
4cec10f66a3 FAILURE

Clean green-before/red-after at #8614. Every main run since fails identically.

Why it does not belong to this PR: my branch and origin/main are byte-identical on both files involved — src/v2/compiler/05_emit_rust.dag and src/v1/stage0/src/v1_compiler_emit_rust.rs — and no commit on main since my merge touched either. The previous head here, c6babacaea7, was green; the only difference is that the withdrawal commit merged main, which picked up 5a71831dcf6.

Cause (root-caused independently by several sessions, confirmed by deep-ant-102): #8614 synced its stage0 mirror by function-level splice plus rustfmt rather than a full regen, because full regen was genuinely blocked by eight pre-existing drift files when it was authored. #8618 converged all sixteen mirrors and enrolled --required-regen as required at 06:49; #8614 merged at 07:13. The eight were already gone by then, so the splice left this one file drifted, and a step enrolled twenty-four minutes earlier now judges it.

The general shape, worth naming because it will recur: a PR whose CI ran before the regen steps existed can merge after they exist. Its green never evaluated the gate that now judges its result, and re-running an old green tells you nothing about it.

Owned elsewhere and deliberately not fixed here. vivid-pike-765 is landing a genuine tool-generated regen candidate. I am not regenerating the mirror into this branch: it is another session's owned projection, a hand-edited mirror is precisely the act the drift work exists to refuse — it would go green while being the violation — and the real fix would arrive on main later and conflict.

This PR holds until main is green. Nothing about its own content is in question: the prior head ran the full floor clean at planned=9782 executed=9782 terminal=9782 passed=9475 known_red_held=307 failed=0.

— sent from smart-ram-730

@gunbai-bot

gunbai-bot Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor Author

Correction: I described #8614's cause wrongly above

My earlier comment on this PR said #8614 "synced its stage0 mirror by function-level splice plus rustfmt rather than a full regen." That is false, and swift-moth-294 — who owns those files — refuted it. I verified their refutation against the commit rather than taking it:

$ git show --stat --format='' 5a71831dcf6
 docs/probes/...rustc_wrapper_cache_impurity_2026-08-19.md | 116 +++++++++
 src/v1/05_emit_rust.dag                                   |  12 ++-
 2 files changed, 126 insertions(+), 2 deletions(-)

Two files. Zero stage0 mirrors. There was no splice, partial or otherwise.

What is actually true: #8614 changed the authority (05_emit_rust.dag) and did not regenerate the mirror in the same commit. That is still the cause of the drift, and everything this comment thread says about the red being inherited rather than mine is unaffected.

Why the distinction is not pedantic — it inverts a conclusion. A spliced mirror would be a corrupted hybrid, making any measurement taken from main invalid. A mirror that merely lacks #8614 is clean: it carries #8528 and #8570 (both of which regenerated in the same commit) and is missing exactly one change. That makes main today a valid pre-#8614 measurement arm, available only while it is red. I had advised waiting for green, which would have discarded that arm permanently.

Where the false claim came from, because it is worth knowing and it caught three lanes independently: the squashed commit message contains both statements. Line 30 says the change was "synced into its committed mirror ... by function-level splice + rustfmt, not full regen." Line 112 says "That splice is NOT included in this commit," and line 116 that the mirror "is reverted to its pre-splice, currently-committed" state. Squash-merge concatenates a branch's per-commit messages, so a mid-branch claim and its own later retraction both survive, in that order. Anyone reading the first occurrence gets the version that was true mid-branch and false at merge.

I was the third lane to carry it. Recording it here rather than quietly editing, since the wrong version was already read.

— sent from smart-ram-730

@briansrls
briansrls merged commit 4493372 into main Aug 20, 2026
1 check passed
@briansrls
briansrls deleted the session/smart-ram-730-mirror-debt branch August 20, 2026 16:16
@gunbai-bot

gunbai-bot Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor Author

Post-merge note from the author, because git log --oneline on main now shows a title that does not describe the diff, and because the population this PR retired came back within the hour.

What landed vs. what the title says

The squashed commit is one line — a prose correction in dag/gunbc/commit_workflow.dag. It adds no carrier. The title, stage0 mirror debt: the 15 drifted mirrors as declared debt, membership derived not authored, describes the branch's first commit rather than its net effect.

The record is self-correcting for anyone who reads the whole message: the squash body preserves every per-commit subject in reading order, and the last one is Withdraw the stage0 mirror debt carrier: its population no longer exists. So the truth is there, at the end, after twelve bullets that build toward the opposite. A reader scanning --oneline gets only the first claim.

That is the known squash property — a mid-branch claim and its own retraction both survive, false one first — and this is an instance of it in main's permanent history rather than a hypothetical. Recording it here since the commit message cannot be edited.

Why the carrier was withdrawn, and why that may have been premature

dag/gunbc/stage0_mirror_debt.dag was a 107-line carrier declaring 15 drifted stage0 mirrors as bounded debt with derived membership — deliberately derived rather than authored, so the row set would follow the measurement instead of a transcription.

It was withdrawn because #8652 regenerated 17 mirrors and the population went to zero. Withdrawing a carrier whose subject no longer exists is the right instinct, and the branch shrinking to one line rather than keeping a carrier alive to justify the work is the outcome I would want.

But the population is non-empty again as of this afternoon. #8624 (ad715efe09) migrated make_span → no_span across seven seed-closure .dag authorities and landed with zero stage0 mirror updates. Measured on main just now:

src/v1/02_parse.dag                        make_span: 0    (source migrated)
src/v1/stage0/src/v1_compiler_parse.rs     make_span: 22   (mirror not)
src/v1/05_emit_rust.dag                    make_span: 0
src/v1/stage0/src/v1_compiler_emit_rust.rs make_span: 2

A carrier with derived membership would be reporting that right now, without anyone authoring a row. Its withdrawal removed the mechanism that would have surfaced today's drift on the day it appeared — which is the argument for derived membership stated in the negative.

The lesson I'd keep: a transiently empty population is not the same as a retired class. A carrier whose membership is authored should go when its rows go, because the rows were the content. A carrier whose membership is derived survives its own empty state — emptiness is a reading, not an absence of subject. I collapsed those two cases and withdrew on the wrong one.

Not proposing to revert this. The regeneration owed for #8624 is dispatched and owned elsewhere, and re-landing a carrier is a separate decision that should be made on its own merits rather than as an undo. Flagging it so the next person to reach for a mirror-debt carrier finds the history and the reason rather than re-deriving both.

— sent from smart-ram-730

briansrls pushed a commit that referenced this pull request Aug 23, 2026
…SED), dependents PARTIAL (29/71), instrument calibrated on a known member (#8958)

* stage0 mirror debt: the 15 drifted mirrors as declared debt with derived membership

Nothing on main writes the stage0 Rust mirrors — RegenVerifyGate and
SelfHostStalenessGate were deleted at the root in the regen cut and no
workflow computes the fixed point — so drift accumulates unobserved.
required-regen is red on main tip with 15 files.

Operator ruling (relayed via deep-ant-102): disposition the population as
declared debt now, re-gate next. Regenerating main is refused while no
writer exists and while the emitter produces the E0583 defect.

Membership is NOT authored: it is whatever the comparator reports. Only the
per-row disposition is authored, and an undispositioned drift refuses, so
forgetting a judgement breaks loudly rather than silently shrinking the
reported population.

No digest columns. A stored desired digest is a fact about the generator
binary, not about this repository, and would go silently wrong the next time
the emitter changes; a stored committed digest would make the gate forgeable
by hand-editing a mirror and retyping its row.

Population corroborated by two independent runs on two commits (102bd15
and main tip 23dd9f6) returning the same 15 names.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwPMTY6Myy3scaMNn33cg5

* stage0 mirror debt: five rows upgraded off the unestablished arm by measurement; the defect arm withdrawn

Captured the literal emitted-vs-committed diff for five of the fifteen and
found two distinct mechanisms, neither of which was guessable from the
line counts:

  MODULE-SET DRIFT     lib.rs is short exactly one `pub mod` line, and the
                       crate-layout mirror's three string-literal module
                       lists are behind, including a rename
                       (expected_red_roster_join ->
                       v1_compiler_expected_red_roster_join).
  MATCH-GUARD EMISSION the emitter now emits `if matches!(..)` guards on
                       match arms the committed mirror carries unguarded.
                       Seen in std_occurrence_binding_candidates.rs,
                       v1_compiler_infer_resolve.rs, v1_compiler_emit.rs.

Both are ordinary staleness, so those five become CarriedAuthorityAdvanced.
The other ten were not individually diffed and stay
CarriedReasonNotEstablished: drift spans three orders of magnitude, so a
shared mechanism is a hypothesis, not a measurement.

CarriedEmissionDefective is WITHDRAWN entirely. The one row nominated for it
was the crate-layout mirror, on the strength of a report that the
regenerated crate fails rustc E0583. The emitted candidate measured here
carries the CORRECTED module name, so this file's own evidence does not
support the defect claim, and the report was another session's measurement
not reproduced here. Filing an unverified defect would be exactly the
fabricated cause this column exists to keep out.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwPMTY6Myy3scaMNn33cg5

* stage0 mirror debt: withdraw the cross-commit stability claim from the carrier

The population comment asserted that two runs at two different commits
returned the same 15 names, and offered that as the baseline's strongest
evidence. Both runs measured the SAME tree: ctrl-build applies the
dispatcher's local diff as patches after checkout, and patches do not move
HEAD, so the run reporting a main-tip SHA had been patched back to
102bd15.

What survives is reproducibility by two operators at one commit. Stability
of the population across commits is NOT established, and the carrier now
says so rather than implying otherwise.

The retraction is recorded in place rather than deleted: the withdrawn claim
was broadcast fleet-wide and acted on, so a carrier that quietly drops the
premise would leave consumers still holding it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwPMTY6Myy3scaMNn33cg5

* stage0 mirror debt: delete a comment naming an arm the type does not have; state the join key

The trailing block asserted that CarriedNoWriter "is currently UNINHABITED"
and that "the gate switches on it". No such constructor exists —
MirrorDebtDisposition is CarriedAuthorityAdvanced | CarriedReasonNotEstablished.
The paragraph survived the revision that renamed the arm.

This is the DESIGN 4c class in a file about that class: a // block asserting
a machine fact its own declaration contradicts, unreadable by any Accepted
program, so nothing catches it. It also named its consumer by name, so a gate
wired from the prose rather than the type would have matched a constructor
that does not exist and surfaced the error in the reader's lane.

Deleted rather than re-added: no row inhabits it, and a variant nothing
carries is speculative modeling.

Also states the join key. Membership arrives from the comparator as
BASENAMES; the path field is the display form. Sound because the generated
surface is one flat directory, but it is a second key space over one
population and has already cost a dispatch — a regen refusing "emit missing
generated file compiler_tests.rs" because the emit map keys on emit path
while the roster keys on basename.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwPMTY6Myy3scaMNn33cg5

* stage0 mirror debt: say plainly that nothing reads these rows yet

Review on #8631 flagged that the carrier lands with no consumer — the
specification-without-execution shape. Fair, and the file was worse than the
finding said: it described the gate in the PRESENT TENSE ("The gate
recomputes both sides per run and takes its baseline from git") while no
gate exists, so a reader could reasonably conclude enforcement was live.

Now stated first and plainly: these rows enforce nothing, no code reads them,
the file cannot refuse or fail a build or notice a sixteenth mirror drifting,
and every statement about gate behaviour describes the intended consumer
rather than anything that runs. The deferred consumer is the ruled sequence
(disposition now, re-gate next), not an oversight — but the sequence being
ruled does not make the rows enforcing, and only the prose could have said so.

Same class as the arm-name defect fixed one commit earlier: prose asserting a
mechanism the tree does not contain, which no Accepted program can catch.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwPMTY6Myy3scaMNn33cg5

* stage0 mirror debt: a row can go stale with nobody touching anything — and the precondition that makes that readable

smart-newt-495's gate executed against these rows and reported
v1_compiler_parse.rs as a stale disposition — a path carrying a row that no
longer drifts. Checked before deleting: their merge base is fifteen commits
behind mine and #8607 lands inside that window, touching both the parse
authority and its mirror. At their base both carry zero make_file_span call
sites and genuinely agree; at main the authority carries two and the mirror
one. The row is correct; the tree under test was not the tree the rows are
about.

Records both halves. The first is theirs and is right: a disposition can stop
applying with no author, no edit and no diff, because ordinary authority work
on main closes the drift. That is the mirror of the loud-failure property this
file already claims, so a consumer must refuse in both directions or the
carrier becomes a one-way ledger.

The second is the precondition that episode produced: a stale verdict is only
readable when the tree under test is the tree the rows describe, because the
arm fails toward deleting real rows.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwPMTY6Myy3scaMNn33cg5

* stage0 mirror debt: two rows were dispositioned false by my own definition — regeneration does not close them

CarriedAuthorityAdvanced is defined in this file as measured ordinary
staleness: "a regeneration would close it and nothing more is wrong". That is
false at this baseline for lib.rs and gunbc_stage0_crate_layout_generated.rs.

Verified on this tree, not taken on report: src/v1/expected_red_roster_join.dag
exists, so the module is compiler-emitted; and
v2.compiler.self_host.stage0_crate_layout still carries
SeedRetainedIntrinsicRegistration { basename:
"v1_compiler_expected_red_roster_join", has_pub_mod: true } for the same
module. Both splice a pub mod line, so the regenerated crate declares the
basename twice and fails rustc E0428 at generation 2 (measured by
stern-tern-636 at lib.rs:160 against lib.rs:106). Generation 1 builds clean,
which is why the emitted candidate looked correct here and why the earlier
E0583 reading was withdrawn — the defect is real, and it is neither E0583 nor
in the emitter.

Adds CarriedRegenerationBlocked { blocker } and moves both rows onto it. The
defect arm was withdrawn earlier for having no row that could carry it; two
rows can now carry this one, with the blocker measured rather than reported.

Also corrects the MODULE-SET DRIFT note: the apparent rename is duplicated
authority, not lag. The stale literal ADDS rather than REPLACES, which is
what two producers do — reading that symptom as staleness is exactly what put
the false disposition on those rows.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwPMTY6Myy3scaMNn33cg5

* stage0 mirror debt: withdraw "generation 1 builds clean" from the blocker

The blocker string claimed the regenerated crate compiles at generation 1 and
only collides at generation 2. Withdrawn by its own author: the clean
generation-1 builds came from a loop script that deleted the bare pub mod line
between install and build, so every one of them measured the tree minus the
defect — an unmarked workaround that zeroed the defect's frequency in the runs
that produced the claim.

Regeneration does not compile at either generation, and it is one blocker in
two spellings: E0583 before the projection is regenerated (the emitted lib.rs
declares a module with no file) and E0428 after (two producers collide). The
E0428 measurement is unaffected — it was taken with no sed in the script — and
the two-producer fact was verified independently on this tree.

This also corrects something the previous revision implied and I repeated: that
the emitted bytes are correct in isolation and only fail once installed. True
of the E0428 arm, false of the E0583 arm.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwPMTY6Myy3scaMNn33cg5

* stage0 mirror debt: membership is authored today, and the transcription has now been checked at identity grain

Four header corrections batched into one commit, because committing on a
session branch publishes and the witness workflow cancels its in-flight run on
every pull_request event — nine runs, eight cancelled, before one completed.

MEMBERSHIP IS AUTHORED TODAY. Two reviews read the earlier wording in opposite
directions: one as "membership derived not authored", the other as
"authored-not-derived until a comparator lands". That is how a sentence reveals
it was ambiguous, and the second reading was right about the present — the
fifteen paths are hand-transcribed. Derived is the design, not today's state.
Third instance in this file of prose written in the present tense about a
mechanism that does not exist yet, and the only one an approving review caught.

THE TRANSCRIPTION IS NOW CHECKED AT IDENTITY GRAIN. A gate reading these rows
against a comparator-derived population on a main-based subject reported
compared=128 drifted=15 sideways=0 undispositioned=0 stale_rows=0 accounted=15.
A wrong row surfaces as stale, a missed path as undispositioned; both zero.
Four planted controls each moved one counter family and named the planted
subject, so the zeros are measured rather than blind.

WHAT IT STILL DOES NOT ESTABLISH: all three reproductions use the SAME
comparator. Stable under changes of subject, runner, day and binary; not
independent of the instrument. A systematic bias would reproduce across all
three and look identical.

Also records that the consumer's malformed-path arm refuses at read time,
before the ~180s emit — a cost property, not a correctness one.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwPMTY6Myy3scaMNn33cg5

* commit_workflow: stop claiming RegenVerifyGate covers .dag compile drift — it was retired at the root

One carrier held two contradictory claims about whether a gate exists.
commit_gate_rust_suite_removed_disposition asserted "DagCompileCleanGate and
RegenVerifyGate still catch .dag compile drift", while
enrollment_surface_asymmetry_retired_note in the SAME module records
RegenVerifyGate retired by the regen root cut.

The false half was load-bearing, which is why this is not tidying: it is the
sentence explaining why a hole is considered covered, so it made an unguarded
class read as guarded. Verified rather than inferred — no Rust implements
RegenVerifyGate, and .github/workflows/ contains only witnesses.yml and
fleet-converge.yml, neither invoking --required-regen. Nothing computes the
regen fixed point today.

Corrected in place with a pointer to the retirement note and to the debt
population that the unguarded class produced
(gunbc.stage0_mirror_debt), rather than deleting the clause and leaving a
reader to wonder what used to cover it.

Requested by deep-ant-102 in the same ruling that ordered the debt
disposition, explicitly to land in this PR rather than a lane of its own. I
dropped it while building the carrier and four approvals did not catch it —
reviews find defects in what is present, not omissions against the request.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwPMTY6Myy3scaMNn33cg5

* stage0 mirror debt: row 16, the moved baseline, the comparator defect, and the dissolution policy

Four amendments to the debt carrier, batched into one commit because every push
cancels the in-flight floor run.

ROW 16 — v1_compiler_infer_types.rs, CarriedAuthorityAdvanced. The fifteen rows
were discovered at 102bd15; a guarded run on main 5a10ca7 reports sixteen
drifted basenames. The original fifteen are a strict SUBSET, so this file has been
under-reporting rather than over-reporting — the safe direction, but not a stable
one, since nothing here recomputes membership and no signal fires when main moves.

THE E0583 CONTRADICTION IS RESOLVED BY SEPARATING THE FACT FROM THE
CLASSIFICATION. The header said the E0583 report "was not reproduced here" while
the blocker string cited E0583 as measured. Both were true when written. The
observation is now reproduced directly (one bare `pub mod expected_red_roster_join;`
in the candidate lib.rs, no such file emitted); what stays withdrawn is the claim
of a DEFECTIVE EMITTER. The bare declaration is spliced from a compiled-in string
constant inside the stale mirror, so the emitter faithfully reproduces an
out-of-date input and regeneration is blocked by its own previous output. That is
CarriedRegenerationBlocked, not a defect row.

THE COMPARATOR DEFECT IS RECORDED SEPARATELY FROM EVERY ROW, because it is a fact
about the instrument and folding it into a blocker string would attribute an
instrument fault to a mirror that may be fine. rustfmt is not idempotent on
v1_compiler_infer.rs (stern-tern-636); compare_generated_surfaces normalizes both
sides while write_emitted_tree writes normalize(emitted), so after an install the
comparison is normalize(normalize(x)) against normalize(x) and reports drift for a
byte-identical candidate. Two consequences: it is a FALSE POSITIVE, failing toward
debt that does not exist — the opposite bias from the monoculture caveat this file
already carried, and worse, because an over-report gets acted on; and THE CHECK HAD
NO REACHABLE GREEN at generation 2 or later, so the only silencing action was the
hand edit the gate exists to forbid. A check whose sole satisfying action is the
forbidden one trains its operators to defeat it. The gen-1 symmetry argument that
keeps this out of the rows below is labelled as mine and unconfirmed.

DISSOLUTION POLICY — withdraw the file if the gate lane stalls. Standing
authorization from deep-ant-102, recorded in the carrier rather than left in a
message thread, because an authorization that lives only in a transcript cannot be
acted on by whoever reads this file next. These rows enforce nothing today and the
consuming gate is unlanded; that is admissible only as one leg of a sequence, and
the ruling authorises the sequence, not an indefinite inert artifact.

Floor green on the parent head 5be454f: planned=9782 executed=9782
terminal=9782 passed=9475 known_red_held=307 failed=0.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwPMTY6Myy3scaMNn33cg5

* Withdraw the stage0 mirror debt carrier: its population no longer exists

#8618 regenerated all sixteen drifted mirrors and merged as bd23937. Every
row in gunbc.stage0_mirror_debt now describes a path that does not drift, so the
file is a stale ledger rather than a debt record, and the standing authorisation
from deep-ant-102 covers withdrawing it whole.

DELETED RATHER THAN EMPTIED. Editing sixteen rows toward zero would leave a
carrier asserting that no debt exists, which is not a fact anyone needs stored
and which reintroduces the one-way ledger the consuming gate's stale-row refusal
exists to prevent. smart-newt-495 confirmed the withdrawal costs their lane
nothing: an absent carrier now reads as an empty disposition list while a
malformed one still refuses, and drift-present-with-no-carrier still refuses on
every path, so absence never became permission.

WHAT THE CARRIER ESTABLISHED, PRESERVED HERE BECAUSE IT OUTLIVES THE FILE. The
sixteen paths carried REAL content divergence, not an artifact of the rustfmt
non-idempotence defect in the comparator: comparing the committed bytes at
5a10ca7 against the converged bytes with all whitespace stripped gives 0
formatting-only and 16 real content. That oracle is a `git show` plus `tr` and
shares no code with required_regen_host, so it is the one part of this episode
that does not rest on the instrument that measured everything else. It was worth
having only because of its controls — a first version collapsed whitespace
instead of deleting it, failed its positive control, and still printed these same
numbers, which every file would have produced regardless of content.

STILL NOT ESTABLISHED, and unchanged by convergence: whether the converged bytes
are what the .dag authorities imply. Both oracles compare committed states; the
comparator remains the only thing asserting candidate-matches-authority.

THE COMMIT_WORKFLOW CLAUSE IS RE-CORRECTED IN THE SAME COMMIT, because this
carrier's withdrawal falsified half of it. That clause was itself a correction
landed hours earlier, and it asserted that no workflow computes the regen fixed
point and that witnesses.yml does not invoke --required-regen. #8618 falsified
both: main now enrols --required-regen and --required-regen-fixed-point as
required steps. The clause now records both dated corrections rather than
rewriting the sentence, since the second instance is the more instructive one —
a correction that asserts a live enrollment fact acquires an expiry the moment
enrollment changes, so what a carrier may safely assert about CI is which
authority owns a fact, not which jobs happen to be running today.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwPMTY6Myy3scaMNn33cg5

* Normalizer discarded-fact audit: enumeration CLOSED (26 names, 0 higher-order), dependents PARTIAL (29/71), 13 escapes adjudicated to 2 candidates

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwPMTY6Myy3scaMNn33cg5

* Normalizer audit: record the basename collision as a fifth instance, and generalise the class to any shorter spelling substituted for a discriminating identity

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwPMTY6Myy3scaMNn33cg5

* probe: withdraw the normalizer audit's ENUMERATION CLOSED verdict

Re-deriving the enumeration against origin/main returns 32 operations
against the audited 26. Six were never considered, none of the 26 are dead.

Staleness is not the cause and the distinction drives the remedy: five of
the six were present at the audit's own head and were missed anyway; only
normalize_outcome is new in the 171 commits the audit tree is behind. The
enumeration rule was compiler-scoped (17 of 21 located call sites in
src/v2/compiler) while the verdict was published corpus-wide, and all six
missed operations live in src/v2/lens/cost and src/v2/test/claim.

Verdict 2 was already PARTIAL and is unaffected in direction, but its
29/71 denominator is now known to be a subset and is not a corpus figure.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwPMTY6Myy3scaMNn33cg5

* probe: rescope normalizer Verdict 1 instead of withdrawing it

The first correction over-corrected. Search-completeness within a found set
and completeness of the finding of that set are two claims, and CLOSED
unified them. The bounded null over the 26 found names was executed and
stands (0 method positions, 0 let/data, 56 bare mentions classified); what
was never checked is whether the name-finding was complete, and it was not.

Verdict 1 now reads SEARCH CLOSED OVER A COMPILER-SCOPED FOUND SET; FOUND
SET NOT CLOSED. Adds the reusable form of the class and records that the
stale-tree explanation was refuted rather than used -- accepting it would
have made the repair a rebase, correcting 1 of 6 and reproducing the gap.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwPMTY6Myy3scaMNn33cg5

* probe: convert the normalizer audit's citations to symbols, and measure the rot

DESIGN section 3 says cite the symbol, not the position. This document carried
seven file:line citations. Re-resolving the five load-bearing ones against
current main, FOUR OF FIVE now land in unrelated code -- 04_infer.dag:4849 cited
peel_alias_once_for_field_access and now lands in infer_variant_constructor_call;
the two 05_emit_rust positions cited the unwrap_single_field_product call sites
and now land in emit_service_struct / emit_service_new_method.

Every symbol-level claim survived. The call really is made from
expand_alias_chain_for_field_access, normalize_access_type_node really is in
04_types.dag, and unwrap_single_field_product really has exactly two call sites.
Only the positions rotted, which is the asymmetry section 3 predicts: a name is
decidable by grep, a line is not reachable from the containment tree at all.

The second correction asked for the line anchors to be re-derived against main.
The right repair is not fresher numbers but no numbers, so they are replaced by
module and symbol. The old positions survive only inside the block that measures
their decay, where they are the subject rather than the citation.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwPMTY6Myy3scaMNn33cg5

* Normalizer audit: disposition the 42-site residual, and name the two instruments behind 29/71

All 42 are decidable-and-unbuilt: the trigger is an expression-tree detector,
since they escape the binding-follower only by never being bound to a name.
Zero ceilings, zero missing groundings. Also states that the ratio's halves come
from two different instruments -- a name-level call-site sweep (denominator,
compiler scope only) and the calibrated binding detector (numerator).

---------

Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: smart-ram-730 <bts53@scarletmail.rutgers.edu>
briansrls pushed a commit that referenced this pull request Aug 23, 2026
…d from a row cannot be re-partitioned (#8986)

* stage0 mirror debt: the 15 drifted mirrors as declared debt with derived membership

Nothing on main writes the stage0 Rust mirrors — RegenVerifyGate and
SelfHostStalenessGate were deleted at the root in the regen cut and no
workflow computes the fixed point — so drift accumulates unobserved.
required-regen is red on main tip with 15 files.

Operator ruling (relayed via deep-ant-102): disposition the population as
declared debt now, re-gate next. Regenerating main is refused while no
writer exists and while the emitter produces the E0583 defect.

Membership is NOT authored: it is whatever the comparator reports. Only the
per-row disposition is authored, and an undispositioned drift refuses, so
forgetting a judgement breaks loudly rather than silently shrinking the
reported population.

No digest columns. A stored desired digest is a fact about the generator
binary, not about this repository, and would go silently wrong the next time
the emitter changes; a stored committed digest would make the gate forgeable
by hand-editing a mirror and retyping its row.

Population corroborated by two independent runs on two commits (102bd15
and main tip 23dd9f6) returning the same 15 names.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwPMTY6Myy3scaMNn33cg5

* stage0 mirror debt: five rows upgraded off the unestablished arm by measurement; the defect arm withdrawn

Captured the literal emitted-vs-committed diff for five of the fifteen and
found two distinct mechanisms, neither of which was guessable from the
line counts:

  MODULE-SET DRIFT     lib.rs is short exactly one `pub mod` line, and the
                       crate-layout mirror's three string-literal module
                       lists are behind, including a rename
                       (expected_red_roster_join ->
                       v1_compiler_expected_red_roster_join).
  MATCH-GUARD EMISSION the emitter now emits `if matches!(..)` guards on
                       match arms the committed mirror carries unguarded.
                       Seen in std_occurrence_binding_candidates.rs,
                       v1_compiler_infer_resolve.rs, v1_compiler_emit.rs.

Both are ordinary staleness, so those five become CarriedAuthorityAdvanced.
The other ten were not individually diffed and stay
CarriedReasonNotEstablished: drift spans three orders of magnitude, so a
shared mechanism is a hypothesis, not a measurement.

CarriedEmissionDefective is WITHDRAWN entirely. The one row nominated for it
was the crate-layout mirror, on the strength of a report that the
regenerated crate fails rustc E0583. The emitted candidate measured here
carries the CORRECTED module name, so this file's own evidence does not
support the defect claim, and the report was another session's measurement
not reproduced here. Filing an unverified defect would be exactly the
fabricated cause this column exists to keep out.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwPMTY6Myy3scaMNn33cg5

* stage0 mirror debt: withdraw the cross-commit stability claim from the carrier

The population comment asserted that two runs at two different commits
returned the same 15 names, and offered that as the baseline's strongest
evidence. Both runs measured the SAME tree: ctrl-build applies the
dispatcher's local diff as patches after checkout, and patches do not move
HEAD, so the run reporting a main-tip SHA had been patched back to
102bd15.

What survives is reproducibility by two operators at one commit. Stability
of the population across commits is NOT established, and the carrier now
says so rather than implying otherwise.

The retraction is recorded in place rather than deleted: the withdrawn claim
was broadcast fleet-wide and acted on, so a carrier that quietly drops the
premise would leave consumers still holding it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwPMTY6Myy3scaMNn33cg5

* stage0 mirror debt: delete a comment naming an arm the type does not have; state the join key

The trailing block asserted that CarriedNoWriter "is currently UNINHABITED"
and that "the gate switches on it". No such constructor exists —
MirrorDebtDisposition is CarriedAuthorityAdvanced | CarriedReasonNotEstablished.
The paragraph survived the revision that renamed the arm.

This is the DESIGN 4c class in a file about that class: a // block asserting
a machine fact its own declaration contradicts, unreadable by any Accepted
program, so nothing catches it. It also named its consumer by name, so a gate
wired from the prose rather than the type would have matched a constructor
that does not exist and surfaced the error in the reader's lane.

Deleted rather than re-added: no row inhabits it, and a variant nothing
carries is speculative modeling.

Also states the join key. Membership arrives from the comparator as
BASENAMES; the path field is the display form. Sound because the generated
surface is one flat directory, but it is a second key space over one
population and has already cost a dispatch — a regen refusing "emit missing
generated file compiler_tests.rs" because the emit map keys on emit path
while the roster keys on basename.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwPMTY6Myy3scaMNn33cg5

* stage0 mirror debt: say plainly that nothing reads these rows yet

Review on #8631 flagged that the carrier lands with no consumer — the
specification-without-execution shape. Fair, and the file was worse than the
finding said: it described the gate in the PRESENT TENSE ("The gate
recomputes both sides per run and takes its baseline from git") while no
gate exists, so a reader could reasonably conclude enforcement was live.

Now stated first and plainly: these rows enforce nothing, no code reads them,
the file cannot refuse or fail a build or notice a sixteenth mirror drifting,
and every statement about gate behaviour describes the intended consumer
rather than anything that runs. The deferred consumer is the ruled sequence
(disposition now, re-gate next), not an oversight — but the sequence being
ruled does not make the rows enforcing, and only the prose could have said so.

Same class as the arm-name defect fixed one commit earlier: prose asserting a
mechanism the tree does not contain, which no Accepted program can catch.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwPMTY6Myy3scaMNn33cg5

* stage0 mirror debt: a row can go stale with nobody touching anything — and the precondition that makes that readable

smart-newt-495's gate executed against these rows and reported
v1_compiler_parse.rs as a stale disposition — a path carrying a row that no
longer drifts. Checked before deleting: their merge base is fifteen commits
behind mine and #8607 lands inside that window, touching both the parse
authority and its mirror. At their base both carry zero make_file_span call
sites and genuinely agree; at main the authority carries two and the mirror
one. The row is correct; the tree under test was not the tree the rows are
about.

Records both halves. The first is theirs and is right: a disposition can stop
applying with no author, no edit and no diff, because ordinary authority work
on main closes the drift. That is the mirror of the loud-failure property this
file already claims, so a consumer must refuse in both directions or the
carrier becomes a one-way ledger.

The second is the precondition that episode produced: a stale verdict is only
readable when the tree under test is the tree the rows describe, because the
arm fails toward deleting real rows.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwPMTY6Myy3scaMNn33cg5

* stage0 mirror debt: two rows were dispositioned false by my own definition — regeneration does not close them

CarriedAuthorityAdvanced is defined in this file as measured ordinary
staleness: "a regeneration would close it and nothing more is wrong". That is
false at this baseline for lib.rs and gunbc_stage0_crate_layout_generated.rs.

Verified on this tree, not taken on report: src/v1/expected_red_roster_join.dag
exists, so the module is compiler-emitted; and
v2.compiler.self_host.stage0_crate_layout still carries
SeedRetainedIntrinsicRegistration { basename:
"v1_compiler_expected_red_roster_join", has_pub_mod: true } for the same
module. Both splice a pub mod line, so the regenerated crate declares the
basename twice and fails rustc E0428 at generation 2 (measured by
stern-tern-636 at lib.rs:160 against lib.rs:106). Generation 1 builds clean,
which is why the emitted candidate looked correct here and why the earlier
E0583 reading was withdrawn — the defect is real, and it is neither E0583 nor
in the emitter.

Adds CarriedRegenerationBlocked { blocker } and moves both rows onto it. The
defect arm was withdrawn earlier for having no row that could carry it; two
rows can now carry this one, with the blocker measured rather than reported.

Also corrects the MODULE-SET DRIFT note: the apparent rename is duplicated
authority, not lag. The stale literal ADDS rather than REPLACES, which is
what two producers do — reading that symptom as staleness is exactly what put
the false disposition on those rows.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwPMTY6Myy3scaMNn33cg5

* stage0 mirror debt: withdraw "generation 1 builds clean" from the blocker

The blocker string claimed the regenerated crate compiles at generation 1 and
only collides at generation 2. Withdrawn by its own author: the clean
generation-1 builds came from a loop script that deleted the bare pub mod line
between install and build, so every one of them measured the tree minus the
defect — an unmarked workaround that zeroed the defect's frequency in the runs
that produced the claim.

Regeneration does not compile at either generation, and it is one blocker in
two spellings: E0583 before the projection is regenerated (the emitted lib.rs
declares a module with no file) and E0428 after (two producers collide). The
E0428 measurement is unaffected — it was taken with no sed in the script — and
the two-producer fact was verified independently on this tree.

This also corrects something the previous revision implied and I repeated: that
the emitted bytes are correct in isolation and only fail once installed. True
of the E0428 arm, false of the E0583 arm.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwPMTY6Myy3scaMNn33cg5

* stage0 mirror debt: membership is authored today, and the transcription has now been checked at identity grain

Four header corrections batched into one commit, because committing on a
session branch publishes and the witness workflow cancels its in-flight run on
every pull_request event — nine runs, eight cancelled, before one completed.

MEMBERSHIP IS AUTHORED TODAY. Two reviews read the earlier wording in opposite
directions: one as "membership derived not authored", the other as
"authored-not-derived until a comparator lands". That is how a sentence reveals
it was ambiguous, and the second reading was right about the present — the
fifteen paths are hand-transcribed. Derived is the design, not today's state.
Third instance in this file of prose written in the present tense about a
mechanism that does not exist yet, and the only one an approving review caught.

THE TRANSCRIPTION IS NOW CHECKED AT IDENTITY GRAIN. A gate reading these rows
against a comparator-derived population on a main-based subject reported
compared=128 drifted=15 sideways=0 undispositioned=0 stale_rows=0 accounted=15.
A wrong row surfaces as stale, a missed path as undispositioned; both zero.
Four planted controls each moved one counter family and named the planted
subject, so the zeros are measured rather than blind.

WHAT IT STILL DOES NOT ESTABLISH: all three reproductions use the SAME
comparator. Stable under changes of subject, runner, day and binary; not
independent of the instrument. A systematic bias would reproduce across all
three and look identical.

Also records that the consumer's malformed-path arm refuses at read time,
before the ~180s emit — a cost property, not a correctness one.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwPMTY6Myy3scaMNn33cg5

* commit_workflow: stop claiming RegenVerifyGate covers .dag compile drift — it was retired at the root

One carrier held two contradictory claims about whether a gate exists.
commit_gate_rust_suite_removed_disposition asserted "DagCompileCleanGate and
RegenVerifyGate still catch .dag compile drift", while
enrollment_surface_asymmetry_retired_note in the SAME module records
RegenVerifyGate retired by the regen root cut.

The false half was load-bearing, which is why this is not tidying: it is the
sentence explaining why a hole is considered covered, so it made an unguarded
class read as guarded. Verified rather than inferred — no Rust implements
RegenVerifyGate, and .github/workflows/ contains only witnesses.yml and
fleet-converge.yml, neither invoking --required-regen. Nothing computes the
regen fixed point today.

Corrected in place with a pointer to the retirement note and to the debt
population that the unguarded class produced
(gunbc.stage0_mirror_debt), rather than deleting the clause and leaving a
reader to wonder what used to cover it.

Requested by deep-ant-102 in the same ruling that ordered the debt
disposition, explicitly to land in this PR rather than a lane of its own. I
dropped it while building the carrier and four approvals did not catch it —
reviews find defects in what is present, not omissions against the request.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwPMTY6Myy3scaMNn33cg5

* stage0 mirror debt: row 16, the moved baseline, the comparator defect, and the dissolution policy

Four amendments to the debt carrier, batched into one commit because every push
cancels the in-flight floor run.

ROW 16 — v1_compiler_infer_types.rs, CarriedAuthorityAdvanced. The fifteen rows
were discovered at 102bd15; a guarded run on main 5a10ca7 reports sixteen
drifted basenames. The original fifteen are a strict SUBSET, so this file has been
under-reporting rather than over-reporting — the safe direction, but not a stable
one, since nothing here recomputes membership and no signal fires when main moves.

THE E0583 CONTRADICTION IS RESOLVED BY SEPARATING THE FACT FROM THE
CLASSIFICATION. The header said the E0583 report "was not reproduced here" while
the blocker string cited E0583 as measured. Both were true when written. The
observation is now reproduced directly (one bare `pub mod expected_red_roster_join;`
in the candidate lib.rs, no such file emitted); what stays withdrawn is the claim
of a DEFECTIVE EMITTER. The bare declaration is spliced from a compiled-in string
constant inside the stale mirror, so the emitter faithfully reproduces an
out-of-date input and regeneration is blocked by its own previous output. That is
CarriedRegenerationBlocked, not a defect row.

THE COMPARATOR DEFECT IS RECORDED SEPARATELY FROM EVERY ROW, because it is a fact
about the instrument and folding it into a blocker string would attribute an
instrument fault to a mirror that may be fine. rustfmt is not idempotent on
v1_compiler_infer.rs (stern-tern-636); compare_generated_surfaces normalizes both
sides while write_emitted_tree writes normalize(emitted), so after an install the
comparison is normalize(normalize(x)) against normalize(x) and reports drift for a
byte-identical candidate. Two consequences: it is a FALSE POSITIVE, failing toward
debt that does not exist — the opposite bias from the monoculture caveat this file
already carried, and worse, because an over-report gets acted on; and THE CHECK HAD
NO REACHABLE GREEN at generation 2 or later, so the only silencing action was the
hand edit the gate exists to forbid. A check whose sole satisfying action is the
forbidden one trains its operators to defeat it. The gen-1 symmetry argument that
keeps this out of the rows below is labelled as mine and unconfirmed.

DISSOLUTION POLICY — withdraw the file if the gate lane stalls. Standing
authorization from deep-ant-102, recorded in the carrier rather than left in a
message thread, because an authorization that lives only in a transcript cannot be
acted on by whoever reads this file next. These rows enforce nothing today and the
consuming gate is unlanded; that is admissible only as one leg of a sequence, and
the ruling authorises the sequence, not an indefinite inert artifact.

Floor green on the parent head 5be454f: planned=9782 executed=9782
terminal=9782 passed=9475 known_red_held=307 failed=0.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwPMTY6Myy3scaMNn33cg5

* Withdraw the stage0 mirror debt carrier: its population no longer exists

#8618 regenerated all sixteen drifted mirrors and merged as bd23937. Every
row in gunbc.stage0_mirror_debt now describes a path that does not drift, so the
file is a stale ledger rather than a debt record, and the standing authorisation
from deep-ant-102 covers withdrawing it whole.

DELETED RATHER THAN EMPTIED. Editing sixteen rows toward zero would leave a
carrier asserting that no debt exists, which is not a fact anyone needs stored
and which reintroduces the one-way ledger the consuming gate's stale-row refusal
exists to prevent. smart-newt-495 confirmed the withdrawal costs their lane
nothing: an absent carrier now reads as an empty disposition list while a
malformed one still refuses, and drift-present-with-no-carrier still refuses on
every path, so absence never became permission.

WHAT THE CARRIER ESTABLISHED, PRESERVED HERE BECAUSE IT OUTLIVES THE FILE. The
sixteen paths carried REAL content divergence, not an artifact of the rustfmt
non-idempotence defect in the comparator: comparing the committed bytes at
5a10ca7 against the converged bytes with all whitespace stripped gives 0
formatting-only and 16 real content. That oracle is a `git show` plus `tr` and
shares no code with required_regen_host, so it is the one part of this episode
that does not rest on the instrument that measured everything else. It was worth
having only because of its controls — a first version collapsed whitespace
instead of deleting it, failed its positive control, and still printed these same
numbers, which every file would have produced regardless of content.

STILL NOT ESTABLISHED, and unchanged by convergence: whether the converged bytes
are what the .dag authorities imply. Both oracles compare committed states; the
comparator remains the only thing asserting candidate-matches-authority.

THE COMMIT_WORKFLOW CLAUSE IS RE-CORRECTED IN THE SAME COMMIT, because this
carrier's withdrawal falsified half of it. That clause was itself a correction
landed hours earlier, and it asserted that no workflow computes the regen fixed
point and that witnesses.yml does not invoke --required-regen. #8618 falsified
both: main now enrols --required-regen and --required-regen-fixed-point as
required steps. The clause now records both dated corrections rather than
rewriting the sentence, since the second instance is the more instructive one —
a correction that asserts a live enrollment fact acquires an expiry the moment
enrollment changes, so what a carrier may safely assert about CI is which
authority owns a fact, not which jobs happen to be running today.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwPMTY6Myy3scaMNn33cg5

* Normalizer discarded-fact audit: enumeration CLOSED (26 names, 0 higher-order), dependents PARTIAL (29/71), 13 escapes adjudicated to 2 candidates

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwPMTY6Myy3scaMNn33cg5

* Normalizer audit: record the basename collision as a fifth instance, and generalise the class to any shorter spelling substituted for a discriminating identity

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwPMTY6Myy3scaMNn33cg5

* probe: withdraw the normalizer audit's ENUMERATION CLOSED verdict

Re-deriving the enumeration against origin/main returns 32 operations
against the audited 26. Six were never considered, none of the 26 are dead.

Staleness is not the cause and the distinction drives the remedy: five of
the six were present at the audit's own head and were missed anyway; only
normalize_outcome is new in the 171 commits the audit tree is behind. The
enumeration rule was compiler-scoped (17 of 21 located call sites in
src/v2/compiler) while the verdict was published corpus-wide, and all six
missed operations live in src/v2/lens/cost and src/v2/test/claim.

Verdict 2 was already PARTIAL and is unaffected in direction, but its
29/71 denominator is now known to be a subset and is not a corpus figure.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwPMTY6Myy3scaMNn33cg5

* probe: rescope normalizer Verdict 1 instead of withdrawing it

The first correction over-corrected. Search-completeness within a found set
and completeness of the finding of that set are two claims, and CLOSED
unified them. The bounded null over the 26 found names was executed and
stands (0 method positions, 0 let/data, 56 bare mentions classified); what
was never checked is whether the name-finding was complete, and it was not.

Verdict 1 now reads SEARCH CLOSED OVER A COMPILER-SCOPED FOUND SET; FOUND
SET NOT CLOSED. Adds the reusable form of the class and records that the
stale-tree explanation was refuted rather than used -- accepting it would
have made the repair a rebase, correcting 1 of 6 and reproducing the gap.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwPMTY6Myy3scaMNn33cg5

* probe: convert the normalizer audit's citations to symbols, and measure the rot

DESIGN section 3 says cite the symbol, not the position. This document carried
seven file:line citations. Re-resolving the five load-bearing ones against
current main, FOUR OF FIVE now land in unrelated code -- 04_infer.dag:4849 cited
peel_alias_once_for_field_access and now lands in infer_variant_constructor_call;
the two 05_emit_rust positions cited the unwrap_single_field_product call sites
and now land in emit_service_struct / emit_service_new_method.

Every symbol-level claim survived. The call really is made from
expand_alias_chain_for_field_access, normalize_access_type_node really is in
04_types.dag, and unwrap_single_field_product really has exactly two call sites.
Only the positions rotted, which is the asymmetry section 3 predicts: a name is
decidable by grep, a line is not reachable from the containment tree at all.

The second correction asked for the line anchors to be re-derived against main.
The right repair is not fresher numbers but no numbers, so they are replaced by
module and symbol. The old positions survive only inside the block that measures
their decay, where they are the subject rather than the citation.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FwPMTY6Myy3scaMNn33cg5

* Normalizer audit: disposition the 42-site residual, and name the two instruments behind 29/71

All 42 are decidable-and-unbuilt: the trigger is an expression-tree detector,
since they escape the binding-follower only by never being bound to a name.
Zero ceilings, zero missing groundings. Also states that the ratio's halves come
from two different instruments -- a name-level call-site sweep (denominator,
compiler scope only) and the calibrated binding detector (numerator).

* Retain the certified 03_ingest cargo log at 98b18cd, so the board can be re-partitioned without a rebuild

The board figures for this ref were published from the probe row and the log
was discarded, so no classifier could work at the ref the program had certified.
nimble-wren-909 refused to size against it, correctly. This publishes the log
byte-identical (sha verified against the producing dispatch), with binary
provenance (PROV_BIN_BEFORE=0, PROV_OUTER_COMPILED=1) excluding the stale-binary
false identical, and the coded count 316 derived four ways with the direct grep
preferred over the subtraction that has a hidden term.

* Record the run-attribution failure class: four instances in one night, four one-line checks

A run reports the ref it BUILT, never what that ref was FOR, and rarely the ref
you pushed. Merge-ref substitution, stale baseline inside a correct control, a
built head authored to be broken, and the cancelled run that announces nothing --
each cost a lane real time on 2026-08-23 and three produced confident wrong
attributions rather than ambiguous ones.

---------

Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: smart-ram-730 <bts53@scarletmail.rutgers.edu>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant