Skip to content

make_span: preserve file information when combining token spans - #8607

Merged
briansrls merged 2 commits into
mainfrom
session/crisp-bat-73
Aug 20, 2026
Merged

briansrls merged 2 commits into
mainfrom
session/crisp-bat-73

Conversation

@gunbai-bot

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

Copy link
Copy Markdown
Contributor

⚠️ DO NOT MERGE — Under stop-the-line on mirror regeneration (proud-crane-845).

REASON: This PR hand-edits src/v1/stage0/src/v1_compiler_parse.rs, a generated projection (line 1: "// Generated by v1 compiler -- do not edit"). The fix is correct and lives in the source authority src/v1/02_parse.dag, but regeneration is blocked on the refinement-coercion fix landing first. The proper merge path is: refinement fix lands → mirror regeneration → this fix auto-applies → PR can merge. Do not attempt to regenerate or repair the mirror.


Summary

Fix a defect where refinement diagnostics went unlocated because file information was discarded when combining byte offsets from multiple source spans. The fix ensures that when creating a span by taking the start from one token and the end from another (e.g., ^ symbol), the file path is preserved from the source span instead of hardcoding to <synthetic>.

Problem

  • make_span hardcodes the file field to "<synthetic>" while carrying correct byte offsets
  • When parsing creates spans by combining positions from multiple tokens (e.g., caret expressions), it discarded file information
  • Approximately 46 refinement diagnostics across the corpus went unlocated and ungreppable
  • Session stern-tern-636 verified the position information was recoverable with a constant offset shift, proving the defect was lossy, not lost-by-design

Solution

Use make_file_span (which accepts a file parameter) instead of make_span (which hardcodes <synthetic>) when combining token spans. The file information is available from the source tokens and should be preserved.

Changes (Source Authority)

  • Modified src/v1/02_parse.dag to use make_file_span in two call sites
  • Import make_file_span in the parse module
  • Add test verifying behavior

Test Coverage

Added refinement_diagnostic_span_file_preservation.rs with tests that:

  1. Verify make_file_span preserves the provided file name (green test)
  2. Verify make_span still correctly hardcodes to <synthetic> (red on regression)
  3. Verify the two functions produce distinguishable results (discriminating test)

All tests pass locally. ✓

🤖 Generated with Claude Code

Brian Searls and others added 2 commits August 20, 2026 00:39
Fix: when combining byte offsets from multiple source spans (e.g., taking
start from one token and end from another), preserve the file path from
the source span instead of hardcoding to "<synthetic>". This ensures
refinement diagnostics created with combined spans are locatable.

This fixes a defect where 46-72 refinement diagnostics across the corpus
went unlocated because file information was discarded even though byte
offsets were correct and positions were recoverable.

Changes:
- Import make_file_span in parse module
- Use make_file_span instead of make_span when combining token spans
  (lines where start/end are extracted from source spans)
- Add test verifying make_file_span preserves file information

The change affects two call sites in parse_caret_expr: ShIdent arm (caret
symbol) and ShLParen arm (caret call).

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
@briansrls
briansrls merged commit b0b0617 into main Aug 20, 2026
1 check passed
@briansrls
briansrls deleted the session/crisp-bat-73 branch August 20, 2026 01:40
gunbai-bot Bot pushed a commit that referenced this pull request Aug 20, 2026
…defect, not a filter

The reporter's selection rule was described correctly and its cause was not.
make_span takes no file parameter and substitutes "<synthetic>" for the argument
it cannot accept, so any diagnostic built from a combined span lost its file while
keeping correct offsets. That is why the split was exactly location-presence and
why every hidden row carried a real file: not a filter selecting, a constructor
destroying.

#8607 repaired it at two parse call sites the evening this row was filed, and
names the same 46-72 population independently.

Consequence recorded rather than the numbers quietly restated: the 72/46/26 split
is a property of the corpus before that merge. A post-fix run showing more located
rows is a fix, not a regression.

The residue is what survives: make_span can still fabricate the sentinel for any
future caller, so the invalid state stays writable, and the count of genuinely
unlocatable rows after the repair has never been measured.

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
… a value

A span with a missing file would have refused somewhere. A span carrying the
string "<synthetic>" is well-formed, flows through every consumer, and renders as
a plausible location — the fabricated-plausible-output failure committed by a span
constructor. That is what let 46 rows reach a reporter and be read as policy.

Also records the routing fact: #8607 was authored and merged by a lane outside
this investigation, naming the same 46-72 population, while this row's instruments
were being built to characterize it. The fleet had no channel that would have
surfaced it, which is the finding rather than anyone's error.

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
…othing reads it

129 of 167 stage0 files open with "Generated by v1 compiler -- do not edit." and a
Source module line. Nothing consumes either. v1_compiler_parse.rs, carrying both,
was hand-edited under #8607, landed applying one of that change's two call sites,
passed every check, and was cited as the fix by three sessions. The running
compiler still fabricates the sentinel on the caret-call arm while the tree reads
as repaired.

Specification-without-execution in its purest form: a machine-checkable claim in a
format designed to be read, that no machine reads.

Records the reusable half of how it was mis-diagnosed: a reflow proves a formatter
ran, not that the emitter ran. rustfmt stands between author and committed bytes,
so the signature two sessions read as a fingerprint is applied by a third party to
both suspects. The discriminator that settled it came from running the generator,
not from reasoning about style.

Notes that the nearest consumer — the convergence model's observe step — repairs
the instance and erases the evidence, leaving the class where it is.

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
…d the null-span constraint

The running binary executes the mirror, so the residue is denominated there, not in
the authority. Authority 56 at origin/main (58 before #8607, already post-fix);
generated mirror 57. The +1 is localized by a per-file join keyed on each mirror's
declared Source module: six of seven pairs exactly zero, the whole delta in
v1_compiler_parse.rs, the file and direction of the unapplied call_span. Three
instruments, no shared step.

A hand-file bucket of 22 was proposed and is withdrawn: 18 are make_span(0, 0), and
a null span has no file to lose, so the fabricated-plausible-location harm does not
apply. The rest are the test asserting the distinction.

What the withdrawal leaves is binding: those 18 callers want a null-span constructor
and reach for the file-losing one because it takes two arguments. The unwritability
change must ship a null-span sibling in the same diff or it is unmergeable on
contact.

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
Four-arm pinned run at main tip: synthetic count zero, all 72 rows located, every
recovered row resolving to src/v2/std/node.dag (52 there, 6 already located plus 46
recovered). The population described as "46-72 refinement diagnostics across the
corpus" was never corpus-wide.

That phrase is #8607's own commit message. The constructor that destroyed the file
field hid the concentration as well as the location, so it misled the one person who
understood the mechanism well enough to fix it — the defect's last damage on its way
out. The remaining repair is one file and 52 sites, not the corpus sweep it was being
scoped as.

Attribution verified four ways rather than assumed: two independently populated
fields agreeing, 52 distinct (start,end) pairs, offsets in range against the file
size, and spacing consistent with consecutive declarations.

#8607 changed locatedness only — type pairs identical count-for-count across all four
arms. With the pin and #8579 arms, all 72 rows are pre-existing and nothing in the
sequence introduced or removed one. A non-zero-residue prediction registered as
falsifiable beforehand was refuted.

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
…ded arm

The arm establishing #8607's effect also contained #8608 and on its face could not
separate them. It separated them without a rerun: #8608 touched zero mirror files,
the diagnostics are constructed in code compiled into the binary, and an
authority-only change cannot alter a binary built from an unchanged mirror. The
confound dissolved on a property of the artifacts rather than on another arm, and
the same run then confirmed it by execution.

Recorded as a technique because the alternative was rerunning a four-arm
measurement to break a confound the file list already answered. Includes the
companion control: a lower-triangular commit-presence matrix retro-validates arm
construction from data already collected.

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
…ind and the class is at 72

Main tip measures 72 constructed with zero <synthetic>. With the filter rule this row
establishes — the reporter shows exactly the rows whose file field is <synthetic> —
the reporter now prints zero while all 72 mismatches exist.

Nothing was repaired. The class went silent because the constructor stopped
destroying the file field, and the reporter only ever displayed what the constructor
had broken: a fail-open wearing the appearance of a fix, discoverable months later as
a class everyone believed closed.

The counts are measured; the reporter's output is inferred from the filter rule, and
a confirming instrument-off run is still owed.

Also states why #8607 does not satisfy this row's next trigger: locating the
diagnostics moved them from reported to censored without changing how many exist, so
reporting an unlocated diagnostic AS unlocated is now the difference between a silent
class and a visible one.

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

* required-regen: the population gate compared two key spaces and refused vacuously on every run

`generated_basenames_from_emit` inserted the full emit key ("src/std_nat.rs") while
`committed_generated_basenames` inserts `file_name()` ("std_nat.rs"), and
`validate_compared_populations` compares the two sets directly. The two key spaces
cannot intersect, so the ENTIRE population mismatched in both directions on every
run since the check was written. Nothing behind that gate was ever checked, and the
real rows were buried under 264 lines of noise.

Both sides now key on `file_name()`. The two hand-maintained predicates already
agreed (`is_hand_maintained_path` takes the basename, same roster), so this was the
only fork.

WHAT THIS CLAIMS. required-regen executes end to end -- parse, typecheck, emit,
candidate write attempted. It still REFUSES, and the refusal is now correct and
readable: 10 real rows instead of 264 noise rows.

  emitted_not_committed = [v1_compiler_trait_bound_witness.rs]
  committed_not_emitted = 9 files absent from HAND_MAINTAINED_STAGE0_FILES

Those 10 are genuine debt and are NOT addressed here. They are not uniform -- two
have live .dag sources, one does not, several are hand-authored with no authority,
one is produced by a different generator -- so they need separate dispositions, not
nine names added to a roster to make the gate green. That would silence the signal
this change exists to expose, and the roster is itself generated ("do not
hand-edit", authority v2.compiler.self_host.stage0_crate_layout).

SCOPE REDUCED SINCE THE FIRST HEAD, AND ONE CLAIM RETRACTED. This branch previously
also carried a change to src/v1/trait_bound_witness.dag, and asserted that a
single-variant coproduct is not expressible in this dialect. THAT ASSERTION WAS
FALSE. #8519 landed the correct form -- `= | Variant`, with a leading pipe, an
established corpus idiom (extdeps.ipc.dpmx, extdeps.npm,
extdeps.advertising.google_ads). I had executed two spellings, seen both refuse, and
generalized to impossibility without grepping for how the corpus already writes one.
Verified after the fact: main's leading-pipe form typechecks, reaching the population
gate with no unresolved-type diagnostic. The .dag half is dropped; #8519 owns it.

Verified remotely with a must-fail control so a no-op cannot read as a pass:
  Applied patch src/v1/stage0/src/required_regen_host.rs cleanly.
  CONTROL_EXIT=101 (cargo check -Z definitely-not-a-real-flag)
  BUILD_EXIT=0  compiling=105
  REGEN_EXIT=1 with the 10-row refusal above

KNOWN AND NOT FIXED HERE (found by snappy-seal-402, confirmed by reading the code):
`write_emitted_tree` iterates every emit key with no `.rs` filter and runs the Rust
normalizer over each, so a non-Rust entry aborts the tree write. Same key-space fork
as this one -- the comparison filters `.rs`, the write does not. Follow-up, with the
10-row disposition.

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

* gap-analysis: file two diagnostic-channel defect rows (no rung authored)

Both opened 2026-08-19 and accepted by deep-ant-102, who ruled the carrier
question directly: the Stage 1 claims carrier does not exist yet, Stage 0
(gunbc.guarantee_measurement) deliberately stores no rung, and a transcribed
rung is the defect whether or not a carrier exists to refuse it. So the rows
record invalid state, harm, distinguishing facts, evidence, ceiling with its
reason, and next trigger — and no rung field. When the claims carrier lands
these rows are consumed as-is rather than re-litigated, because nothing in
them was the carrier's job to derive.

Item 11 — compile_dag_rust_emit_check returns false from three structurally
distinct arms (hard diagnostics / file not emitted / content mismatch) and
discards which fired. Ceiling is structurally impossible rather than merely
detectable: the arm is KNOWN at the return site and thrown away, so a typed
outcome stops an information loss rather than adding a check.

Item 12 — the source_annotation in-body refusal renders a byte span in the
file:START-END shape readers parse as lines (29073 against a 1407-line file;
the truth is line 478). The defect is not the arithmetic but that the compiler
emitted a POSITIONAL citation about its own input when the declaration NAME was
in hand — a machine-side instance of the DESIGN §3 cite-the-symbol rule.
Mechanism marked NOT YET READ rather than guessed.

Plus a closing paragraph naming the three as one class: won't say why, won't
say where, says where and is wrong.

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

* gap-analysis: relocate item 12 to SourceSpan's untyped magnitudes

swift-moth-294 read the formatter as authorized and the defect is one layer
down and much wider than filed. dag/std/source_annotation.dag is CLEAN — its
refusal message returns only the sentence, its variants carry origin:
SourceSpan, and its header already reasons that consumers should ask for the
origin rather than store a second copy. The file:START-END rendering is the
general diagnostic renderer over SourceSpan.

The root: dag/std/types.dag SourceSpan declares start: Int and end: Int, so
byte offsets, char offsets and line numbers are mutually substitutable with no
refusal at any position. The byte-offset-printed-as-a-line symptom is what an
anemic magnitude looks like when it reaches a reader — the §2 deep-decomposition
failure, the same shape as the CpuSocket LGA4926 example where the number is an
Int and the AXIS is the modeling. 17 files construct SourceSpan.

The ceiling is proven attainable in this repo: a4_opacity_test asserts refusal
of ByteOffset-for-CharOffset in both directions with an accepting control. Two
precisions recorded because both are easy to get wrong — it proves the
RECORD-WRAPPER form and not `where brand(..)` (despite one identity being named
same_brand_accepts, which is a misnomer), and it is a witness_deferral_freeze
member under LegacyFrozenPathDeferral, so it does NOT currently execute. Proven
in source, unexercised in the present tree.

The false attribution is kept as a correction note rather than silently
replaced: two readers repeated it before anyone read the formatter.

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

* gap-analysis: file the 4c sweep as UNKNOWN-with-a-reason, not as a gap

The class that fired — an indented comment inside a fold lambda body, which
blocked required-regen corpus-wide and sat on main undetected — is covered by a
controlled zero: the sweep finds 22,429 real comments and detects a planted
violation, and returns 0 on main.

Three other shapes cannot be swept by text grep AT ALL, and the reason is
structural: this corpus's job is to carry other languages' syntax as data.
Greps returned 225 and 75 hits; two sessions independently sampled them at 6
and 8 hits and found not one instance of comment syntax — every hit was inside
a string literal (emitted Rust comments as templates, source-as-fixture
witnesses, generated banners, CodeBlock.code, an rsync glob). A regex for
comment syntax over a corpus built to carry syntax as data measures the wrong
thing by construction, so this is not a filter anyone can improve.

Filed as UNKNOWN with a named reason and a named instrument (a Node lens with
string-literal awareness). Reporting 0 or 225 would both be fabrications in
opposite directions, and 225 is the more expensive one — it manufactures a
sweep of phantom sites. Priority: file, do not staff.

Carries the standing rule that fell out: a zero looks like nothing and invites
a control, a nonzero looks like a finding and does not, and that is backwards.

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

* gap-analysis: item 11 is three arms PLUS a liveness precondition, measured

Establishing the arm on a live red found the row incomplete in two ways, both
by measurement rather than reading.

A compiler CRASH produces the same observable surface as a legitimate arm 2:
compile_exit=101, FILE_FOUND=no, nothing emitted — which reads as a clean
arm-2 result. The real cause was a panic in repo_relative_path_normalized
refusing an out-of-workspace source root. So FILE_FOUND=no is arm 2 only if
the compiler ran, and a typed outcome must separate 'did not emit this file'
from 'did not run' or it rebuilds the conflation one level in.

And the arm was right while the mechanism inside it was wrong: the predicted
tripwire (EXCLUDE on the bounded item header) PASSES — the header was already
bare. Three other assertions fail, and the missing mechanism is hand-written
impls. A per-assertion verdict caught that; a per-arm verdict would not have.

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

* gap-analysis: item 12's class is growing — a second instance landed the same day

review 53871 on gunbc#8527 flags BudgetExceeded { elapsed_ms: Int, budget_ms: Int }
in a NEW module — Duration-semantic fields as bare Int, ported from hand-Rust
u64/u128, at the exact moment std.measure.Duration was available.

Same untyped-magnitude shape as SourceSpan one domain over. It changes how the
row is priced: the 17 SourceSpan sites are inherited debt, but new modules are
still extending the class, so this is not a fixed backlog awaiting a sweep and a
fix grounding only existing sites leaves the authoring path open.

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

* gap-analysis: file the emptied-fixture class beside the diagnostic-channel rows

Found on the namespace-cut branch, filed here rather than with that incident
because the class is the same subject as items 11-13: a channel reporting
something other than what it appears to report.

A scripted rename rewrote 51 string literals, 46 of them bare-to-qualified and
so invisible to any check comparing strings that already contain dots. A bulk
edit transforms code, where names are checked and a bad one is loud, and it
transforms string literals, which are data and emit nothing. One rewrite moved
a roster identity to a homonym (executable test fn -> unexecutable lens fn of
the same name) with the count unchanged at 306 on both sides.

The class itself is broader than the codemod: a fixture emptied of the thing it
exists to exhibit still passes, because every defense watches what a test
ASSERTS and none watches whether the fixture still CONTAINS its subject. Same
end state is reachable by shrinking a witness to fit a budget.

Ceiling stated as mechanically preventable now (a positive control on the
specimen, not the outcome) with a route to structurally impossible (derive the
fixture from the construct) explicitly NOT claimed. No rung authored.

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

* gap analysis: name rows 11-15 as one class, and file the inverted reporting filter

The four diagnostic-channel defects opened over one night's auditing read as
unrelated until the fourth arrived. They share a property rather than a
subsystem: each is a channel that reports something other than what it appears
to report, silently and plausibly, with no shape difference between the true
output and the false one.

Stated above the rows because the family is the finding — this is the channel
by which every other guarantee in the document is observed, so a defect here
discounts the evidence for all of them, and §4b's derive-the-rung obligation
assumes a faithful measurement channel.

Row 15 (new) is the inverted reporting filter: 72 constructed / 46 reported /
26 hidden, the reported set exactly the <synthetic>-file rows and the hidden
set exactly those carrying a real file and byte span. It differs in kind from
11-13 — those degrade information, this inverts the selection, so it cannot be
compensated by a careful reader. Receipt: a no-tail conclusion correct on the
shown data and wrong about the corpus.

Counts carry their provenance explicitly (construction-site count plus one
independent corpus-wide control; not verified here, since verification needs
the regen path the mirror hold forbids).

The narrower three-class note is subsumed rather than left beside this, so the
document carries one account of the class.

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

* gap analysis: row 16 — the regen refusal receipt reports not-computed as measured-and-clean

The population gate in run_required_regen returns early, so compare_generated_surfaces
never runs. The receipt written on that path asserts five values nothing computed:
two digests as the literal "refused:population", changed_paths as an actually-empty
Vec, and first_generation_equal / fixed_point_equal as false — a Bool whose false
reads as measured-and-unequal, never as not-measured.

Measured consequence: the mirror's infer_method_args_with_fold was carrying six
parameters against the authority's seven, in the emitted set and comparable, and was
simply never compared — masked behind an unrelated two-file population mismatch.

Filed as a distinct member of the 11-16 class: those are reporting channels, this is
a receipt, the artifact whose whole purpose is to be believed by a reader who did not
watch the run. DESIGN already names the shape — the empty-observation narrow, the
absorbing fallback's mirror, and the strictly worse direction of the two.

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

* gap analysis: row 16 — lead with the Bool, and name the compounding

The five fabricated receipt fields are not equally bad. Two digests carry a
self-describing sentinel and changed_paths is visibly empty; a careful reader can
catch those. first_generation_equal and fixed_point_equal are Bools, and a Bool has
no arm for not-measured, so false reads as measured-and-unequal — the receipt
asserts a negative result for a comparison that never ran.

The compounding is the harm worth stating: this receipt shape was live while the
population gate was masking content drift, so a reader held a receipt asserting
fixed_point_equal=false, produced by a run that compared nothing.

Trigger extended: under the convergence model the operator ruled for, the
computed/refused split is not optional — a converged verdict and a
could-not-determine must not inhabit one Bool, the same hazard as deriving
convergence from the staged candidate rather than the committed tree.

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

* gap analysis: row 15 — the 46 unlocated rows are a fixed constructor defect, not a filter

The reporter's selection rule was described correctly and its cause was not.
make_span takes no file parameter and substitutes "<synthetic>" for the argument
it cannot accept, so any diagnostic built from a combined span lost its file while
keeping correct offsets. That is why the split was exactly location-presence and
why every hidden row carried a real file: not a filter selecting, a constructor
destroying.

#8607 repaired it at two parse call sites the evening this row was filed, and
names the same 46-72 population independently.

Consequence recorded rather than the numbers quietly restated: the 72/46/26 split
is a property of the corpus before that merge. A post-fix run showing more located
rows is a fix, not a regression.

The residue is what survives: make_span can still fabricate the sentinel for any
future caller, so the invalid state stays writable, and the count of genuinely
unlocatable rows after the repair has never been measured.

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

* gap analysis: row 15 — the sentinel is absence wearing the costume of a value

A span with a missing file would have refused somewhere. A span carrying the
string "<synthetic>" is well-formed, flows through every consumer, and renders as
a plausible location — the fabricated-plausible-output failure committed by a span
constructor. That is what let 46 rows reach a reporter and be read as policy.

Also records the routing fact: #8607 was authored and merged by a lane outside
this investigation, naming the same 46-72 population, while this row's instruments
were being built to characterize it. The fleet had no channel that would have
surfaced it, which is the finding rather than anyone's error.

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

* gap analysis: row 17 — a generated file declares its provenance and nothing reads it

129 of 167 stage0 files open with "Generated by v1 compiler -- do not edit." and a
Source module line. Nothing consumes either. v1_compiler_parse.rs, carrying both,
was hand-edited under #8607, landed applying one of that change's two call sites,
passed every check, and was cited as the fix by three sessions. The running
compiler still fabricates the sentinel on the caret-call arm while the tree reads
as repaired.

Specification-without-execution in its purest form: a machine-checkable claim in a
format designed to be read, that no machine reads.

Records the reusable half of how it was mis-diagnosed: a reflow proves a formatter
ran, not that the emitter ran. rustfmt stands between author and committed bytes,
so the signature two sessions read as a fingerprint is applied by a third party to
both suspects. The discriminator that settled it came from running the generator,
not from reasoning about style.

Notes that the nearest consumer — the convergence model's observe step — repairs
the instance and erases the evidence, leaving the class where it is.

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

* gap analysis: row 15 — the type-pair split censuses evidence shapes, not failure classes

The ten pairs group by formal-from-actual. The failure class is which branch of
where_refinement_diags_for_predicate the value lands in, and that axis was already
in the data: WhereRefinementUnenforced carries a reason field that its own scaffold
note declares a closed sum of five deferral strings. The diagnostic names its class
and the census grouped on the subject.

Not a relabelling: #8608 edits the literal-extraction arm, and the 21 remaining rows
are non-literal expressions that never reach it, so a per-arm fallback chain would
have been inert for five of six arms.

Same error shape this row already records, in a second place — a property of the
subject read as a property of the failure, twice in one night by lanes with no
contact.

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

* gap analysis: row 15 — size the residue against the mirror, and record the null-span constraint

The running binary executes the mirror, so the residue is denominated there, not in
the authority. Authority 56 at origin/main (58 before #8607, already post-fix);
generated mirror 57. The +1 is localized by a per-file join keyed on each mirror's
declared Source module: six of seven pairs exactly zero, the whole delta in
v1_compiler_parse.rs, the file and direction of the unapplied call_span. Three
instruments, no shared step.

A hand-file bucket of 22 was proposed and is withdrawn: 18 are make_span(0, 0), and
a null span has no file to lose, so the fabricated-plausible-location harm does not
apply. The rest are the test asserting the distinction.

What the withdrawal leaves is binding: those 18 callers want a null-span constructor
and reach for the file-losing one because it takes two arguments. The unwritability
change must ship a null-span sibling in the same diff or it is unmergeable on
contact.

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

* gap analysis: row 15 — measured after the repair, the 46 were ONE FILE

Four-arm pinned run at main tip: synthetic count zero, all 72 rows located, every
recovered row resolving to src/v2/std/node.dag (52 there, 6 already located plus 46
recovered). The population described as "46-72 refinement diagnostics across the
corpus" was never corpus-wide.

That phrase is #8607's own commit message. The constructor that destroyed the file
field hid the concentration as well as the location, so it misled the one person who
understood the mechanism well enough to fix it — the defect's last damage on its way
out. The remaining repair is one file and 52 sites, not the corpus sweep it was being
scoped as.

Attribution verified four ways rather than assumed: two independently populated
fields agreeing, 52 distinct (start,end) pairs, offsets in range against the file
size, and spacing consistent with consecutive declarations.

#8607 changed locatedness only — type pairs identical count-for-count across all four
arms. With the pin and #8579 arms, all 72 rows are pre-existing and nothing in the
sequence introduced or removed one. A non-zero-residue prediction registered as
falsifiable beforehand was refuted.

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

* gap analysis: row 17 — record attribution-by-mechanism from a confounded arm

The arm establishing #8607's effect also contained #8608 and on its face could not
separate them. It separated them without a rerun: #8608 touched zero mirror files,
the diagnostics are constructed in code compiled into the binary, and an
authority-only change cannot alter a binary built from an unchanged mirror. The
confound dissolved on a property of the artifacts rather than on another arm, and
the same run then confirmed it by execution.

Recorded as a technique because the alternative was rerunning a four-arm
measurement to break a confound the file list already answered. Includes the
companion control: a lower-triangular commit-presence matrix retro-validates arm
construction from data already collected.

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

* gap analysis: row 15 — mark the arm-D figures provisional, and record the roots-vs-diagnostics correction

The post-repair numbers come from a run whose compile-step exit status was never
printed. A sibling whole-root compile was Killed at 137 on the same infrastructure
while its dispatch reported 0. A process killed partway through a corpus compile
does not produce zero — it produces a truncated population indistinguishable from a
complete one, and residue of exactly zero against three independent predictions of
non-zero is consistent with either.

Adopts the rule: any command reporting a count prints the exit status of the process
that produced the count, not the dispatch's.

Also records a second correction to the framing: a source partition shows 46 of the
52 are the #8608 class, already fixed in authority and inert only because unmirrored.
The file is not the unit of repair; the regen is. Both the corpus-sweep and one-file
framings counted diagnostics, which distribute by where values flow rather than where
the defect lives.

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

* gap analysis: row 15 — retract two supporting legs, establish the denominator, name its subject

Two of the three legs this document cited for the half-applied finding are
retracted, including the one it called strongest. An aggregate symbol count and a
per-file join across the emission boundary are not drift tests: emission need not
preserve occurrence counts, and the single file showing a delta is the one file
where emission is provably non-1:1, so the +1 is what emission arithmetic produces
there. Seven rows of an unsound test is one unsound test.

The method survives — pair a mirror to the authority its own header declares — and
the finding is unaffected, because it never rested on the counts. Its sound legs are
a site-level observation immune to emission arithmetic, and required-regen refusing
on that file: committed versus regenerated, same representation, one variable.

Arm D's provisional flag is withdrawn: exit=1 on ten completed compiles, 137 and 124
excluded, no pipe in the capture. The subject is now stated beside the figures —
entry-scoped, one import closure, not corpus-wide. Comparing it to a corpus grep
produces a contradiction that is purely a denominator, which is the dated-measurement
trap on the space axis.

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

* gap analysis: row 15 — the partition sums to 51 and the missing row has no location

46 + 3 + 2 = 51 against 52 measured. The unaccounted row is almost certainly the
degenerate-span one, which is findable only by enclosing fn — so acting on the
partition as if it covered all 52 drops it silently and permanently rather than
leaving it to resurface.

What would settle it is a per-file by per-type-pair cross-tab, which nobody holds:
both dimensions were captured as separate aggregates and never joined. Same axis
error this row already records, committed by the instrument that measured it.

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

* gap analysis: row 15 — withdraw the emission-arithmetic explanation; emission IS 1:1 here

The previous revision explained the join's +1 as emission arithmetic on the grounds
that this file's emission is non-1:1. Decomposing the regenerated file refutes that:
3 = 1 pub use + 2 calls against the authority's 2 call sites, so emission is 1:1 for
this symbol and the gap is exactly the missing call_span site.

The join's conclusion was accidentally right. That does not restore the method — an
unsound test agreeing with a sound one is still unsound, and the distinction has to
be held or the method returns the next time it agrees.

Also records that the contested digit was an occurrence count read as a call count:
grep -c on the committed mirror returns 2, of which line 72 is the pub use import.
Committed call sites are 1. A correction reporting 2-vs-2 would have restored the
appearance of doneness on the one file where doneness is the illusion.

Adds the clause: count call sites, never string occurrences, and print the matching
lines.

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

* gap analysis: row 15 — the 52nd row is a different refined position, carried as a named obligation

content_hash_atom( occurs exactly 51 times in node.dag, so the partition is complete
over that call site and the gap is a category difference rather than a missed
member. The candidate is content_hash_combine_structural / combine_hash in the same
file — different function, different formal, invisible to that census however
carefully run.

Records the standing obligation in the terms agreed: the degenerate-span row is
carried keyed by enclosing fn, never as a residual of a count, because a row with no
span identity is findable only that way and no location-keyed sweep will resurface
it.

Names the general shape: two aggregates side by side are not a cross-tab, and the
gap between them is where a row lives undetected. Fourth instance of the axis error
here, first committed by the measuring instrument rather than a reader of it.

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

* gap analysis: row 15 — record the operative state: the reporter is blind and the class is at 72

Main tip measures 72 constructed with zero <synthetic>. With the filter rule this row
establishes — the reporter shows exactly the rows whose file field is <synthetic> —
the reporter now prints zero while all 72 mismatches exist.

Nothing was repaired. The class went silent because the constructor stopped
destroying the file field, and the reporter only ever displayed what the constructor
had broken: a fail-open wearing the appearance of a fix, discoverable months later as
a class everyone believed closed.

The counts are measured; the reporter's output is inferred from the filter rule, and
a confirming instrument-off run is still owed.

Also states why #8607 does not satisfy this row's next trigger: locating the
diagnostics moved them from reported to censored without changing how many exist, so
reporting an unlocated diagnostic AS unlocated is now the difference between a silent
class and a visible one.

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

---------

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>
gunbai-bot Bot pushed a commit that referenced this pull request Aug 20, 2026
…— 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
briansrls pushed a commit that referenced this pull request Aug 20, 2026
…ip derived not authored (#8631)

* 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

---------

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>
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