Skip to content

Repair main: the publication witness still imports the ReadSource variants #10934 deleted - #10977

Merged
briansrls merged 2 commits into
mainfrom
fix/fabric-m0-publication-witness-origin-reading
Sep 10, 2026
Merged

briansrls merged 2 commits into
mainfrom
fix/fabric-m0-publication-witness-origin-reading

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

Main's required floor is red for every open PR, and this is the fix.

FAILED PHASE declarations (2 finding(s))
IMPORT-MEMBER-ABSENT dag/test/claim/fabric_m0_publication_witness_test.dag:39, :40

test.claim.fabric_m0_publication_witness imports DurableOriginRead and DisposableCacheRead from gunbc.fabric_m0_commit, which #10934 deleted. Two individually-green PRs from one lane, incompatible only once both were on main: #10933 landed this witness against the old shape while #10934 replaced ManifestRead's digest-plus-provenance-stamp pair with a sealed OriginReading and removed ReadSource with it.

The two imports were the visible half — the file also still built ReadbackConfirmed { observed_digest }, so restoring the imports alone would not have compiled.

The repair inhabits the new construction

Rather than reaching around it. The reading comes from read_origin_staged_file over a committed fixture file; the recorded digest is derived from that reading, so a success arm cannot drift from what was read; the cache arm goes through cache_manifest_read.

Two smaller repairs were available and both were wrong: restoring the deleted variants, or adding this module to witness_origin_reading's admit_callers. Each would have re-opened what #10934 closed.

One line of extdeps.crypto.hash, as a prerequisite not scope creep

crypto.Sha256Sum.File's mock_response interpolated the input path into its canned line — the only interpolation of its kind in any extdeps mock — so it refused NoSuchVariable on every hermetic call and had never once replayed. Without it these witnesses cannot execute hermetically at all, which is what they did here before I applied it. The same one-line change is also in #10972; whichever lands second sees no conflict.

Executed

Hermetically, under --dry-run (the envelope CI uses): all five publication witnesses PASS, including the cache-read refusal and both pending arms.

🤖 Generated with Claude Code

https://claude.ai/code/session_01G6mifUz8YHh4WW3bT4wqDt

…iants #10934 deleted

main's required floor fails the declarations phase with IMPORT-MEMBER-ABSENT at
dag/test/claim/fabric_m0_publication_witness_test.dag:39-40, which blocks the floor for
every open PR in the repo. Two individually-green PRs from one lane, incompatible only
once both were on main: #10933 landed this witness against the old shape while #10934
replaced ManifestRead's digest-plus-provenance-stamp pair with a sealed OriginReading
and deleted ReadSource / DurableOriginRead / DisposableCacheRead with it. The file also
still built ReadbackConfirmed { observed_digest }, so the two imports were the visible
half of a wider skew.

The repair INHABITS the new construction rather than reaching around it: the reading
comes from read_origin_staged_file over a committed fixture file, the recorded digest is
DERIVED from that reading so a success arm cannot drift from what was read, and the
cache arm goes through cache_manifest_read. Restoring the deleted variants, or adding
this module to witness_origin_reading's admit_callers, would both have been smaller and
both would have re-opened what #10934 closed.

CARRIES ONE LINE OF extdeps.crypto.hash, and it is a prerequisite rather than scope
creep: crypto.Sha256Sum.File's mock_response interpolated the input path into its canned
line -- the only interpolation of its kind in any extdeps mock -- so it refused
NoSuchVariable on every hermetic call and had never once replayed. Without that repair
these witnesses cannot execute hermetically at all, which is exactly what they did here
before it was applied. The same one-line change is also in #10972; whichever lands
second sees no conflict.

Executed hermetically (--dry-run, the envelope CI uses): all five publication witnesses
PASS, including the cache-read refusal and the two pending arms.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G6mifUz8YHh4WW3bT4wqDt
gunbai-bot Bot pushed a commit that referenced this pull request Sep 10, 2026
The fabric witness shape is #10977's; the 500ms native_decl_selection interrupts were fleet contention. Receipt at b5cefb6 stands.

Co-authored-by: Cursor <cursoragent@cursor.com>
This witness declared SubstrateInputsOnly and was correct to: it was a pure fold over
authored fixtures. The repair in this PR makes it call read_origin_staged_file over a
committed repository path, which reaches a live-checkout sink, so the stamp became a
declaration asserting something its own body contradicts -- and nothing in the toolchain
compares the two.

Found by review on the sibling PR (#10972, review 63276), which caught the same class in
all three fabric-M0 witness files. It is the stale-evidence class this lane has been
repairing all along, one scale down: a carrier-grain declaration that outlives the body
it describes.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G6mifUz8YHh4WW3bT4wqDt
gunbai-bot Bot pushed a commit that referenced this pull request Sep 10, 2026
…al real, and stop three stamps from lying

Review 63276 (REQUEST_CHANGES) on #10972, both findings verified at source before fixing.

RED 4 WAS UNKEYED, and it was the worst place for that defect to be: it is the permanent
4b(4) regression control for the escape this PR exists to close. It read "any blocking
diagnostic anywhere >= 1", and its own comment claimed the assertion was on the
unresolved-reference class while the code asserted no class and no subject.

MEASURED RATHER THAN GUESSED: dumping the blocking key set of that probe's closure
returns FORTY-FIVE rows -- UnresolvedType on Time, Memory, Frequency and thirty more,
plus an InternalError cascade -- so the control was satisfied by closure noise. If the
wrapper proxy came back AND any unrelated blocking row existed, it would stay green and
report the escape as still closed. The proposition is "the wrapper symbol is gone", the
row that says so is MissingExport on witness_reading, and there is exactly one of it.

THE DIFFERENTIAL IS NOW REAL. Both arms come from one probe_source producer, so module
header, import block and signature are byte-identical and only the constructing
expression differs. The comparison is over the COMPLETE blocking key set of each
compile, not a chosen target key: everything present on both sides cancels, exactly one
key survives on the RED side (SoleConstructorViolation|OriginReading), and nothing
survives on the GREEN side. The previous form compared two hand-written sources whose
imports differed, so the shared closure was ASSUMED to cancel rather than shown to. A
calibration arm carries the CensusNotRunnable sentinel into the key set so a
both-sides-failed census cannot cancel and read as agreement.

EXACT COUNTS where exactly one refusal is the proposition, replacing >= 1, so a second
unintended refusal is visible instead of absorbed.

THE LIVE-TREE STAMPS WERE LYING. All three fabric-M0 witness files declared
SubstrateInputsOnly and were correct to before this PR; deleting the fixture mint makes
them call read_origin_staged_file over a committed repository path, which reaches a
live-checkout sink. Nothing in the toolchain compares a stamp to the body beneath it, so
this is the stale-evidence class this lane keeps finding, one scale down: a
carrier-grain declaration that outlived the body it describes. The publication witness's
stamp is fixed on #10977 as well, since that PR introduces the same call.

Executed: all seven seal arms PASS, including the complete-key differential and its
calibration.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G6mifUz8YHh4WW3bT4wqDt
@briansrls
briansrls merged commit 38fde66 into main Sep 10, 2026
@briansrls
briansrls deleted the fix/fabric-m0-publication-witness-origin-reading branch September 10, 2026 23:35
gunbai-bot Bot pushed a commit that referenced this pull request Sep 10, 2026
briansrls pushed a commit that referenced this pull request Sep 11, 2026
* Admit expression-bodied fn decls as `= expr` on fn_decl only.

Keep fn_body brace-only so if/block/fn-literal stay unchanged, and lower the
eq-rhs through normalize so `fn f(a: Int) -> Int = a` survives graft.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Enrol G predicates as test fn so floor discovery sees the entry.

A *_test.dag with only plain fn leaves universe derivation empty;
claim_batch --functions is not discovery.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Refuse eq-body lowering without an `=` witness.

last_child without eq was an absorbing fallback; eq is token identity
only, matching let navigation. Survives probes now require an arrow
body via find_arrow_body_child.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Type eq-body fold accumulators as Optional, not Absent.

Emission rendered Option<Absent> (E0425) and could not infer the eq-token match binder (E0282). Init with optional_absent() so the emitted crate compiles.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Keep a reduced bare-Absent fold fixture as an open emitter red.

G's optional_absent() repair is source-only. The interpreter still accepts init: Absent where the type is Optional, and emission has rendered Option<Absent>. Cite that shape on accepted_source_emits_uncompilable_target (vii) so ACT realization-fidelity still has a subject.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Give eq-body folds a typed init and typed step.

optional_absent() retired E0425; emitted lambdas still render acc: _ so rustc cannot infer Optional's T (E0282). Init and step are now declared functions. The untyped-lambda shape stays as a second emitter-red fixture.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Unblock required-witnesses-floor on the G merge of #10882.

Declarations refused DurableOriginRead/DisposableCacheRead without their ReadSource parent. The four native_decl_selection test fns each re-ingested the fixture and crossed the 500ms CPU line; one witness still checks all four discriminators.

Co-authored-by: Cursor <cursoragent@cursor.com>

* Revert out-of-scope floor/declarations edits.

The fabric witness shape is #10977's; the 500ms native_decl_selection interrupts were fleet contention. Receipt at b5cefb6 stands.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
briansrls pushed a commit that referenced this pull request Sep 11, 2026
…s.ci_merge_freshness (#10984)

* Record #10933 x #10934 as the next stale-green instance in gunbc.plans.ci_merge_freshness

A deletion (#10934) crossed a new consumer (#10933) in never-jointly-validated
PRs: #10934's green run started before #10933 merged and #10934 merged on that
head without re-running. main went red with 2 IMPORT-MEMBER-ABSENT findings from
this pair until #10977. Records the timeline, the independently established
ReadbackConfirmed construction the run never reached, and the contributing
factor (one manager held both lanes and never compiled the merged pair). No new
mechanism: the instance sits under the record's existing retirement condition.

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

* ci_merge_freshness: record why this deferral is not a 4b(3) rung drop

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

* ci_merge_freshness 7: state the pair's red window from main's runs and what landed inside it

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

---------

Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
briansrls pushed a commit that referenced this pull request Sep 11, 2026
…tructor, so #10934's rung-4 claim was inflated (#10972)

* fabric-M0: origin-readback confirmation becomes a construction, not a stamp

gunbc.fabric_m0_commit carried ManifestRead { observed_digest, source: ReadSource }
-- a digest and a provenance stamp as two peer values -- and refused the
DisposableCacheRead arm in a fold. That check was satisfied by editing the
DECLARATION while the realization still digested a local copy, which is the
review tell for validation standing where construction was available.

gunbc.fabric_m0_origin_readback now owns a sole_constructor RECORD, OriginReading,
pairing a staged path with the digest computed over it by one operation. ManifestRead
and ReadbackConfirmed carry that reading; ReadSource / DurableOriginRead /
DisposableCacheRead are deleted with the fold arm that refused them, and a cache read
reaches cache_manifest_read, whose only product is a located refusal.

The seal is on a RECORD because sole_constructor on a COPRODUCT does not refuse
cross-module variant construction (the hole f13_variant_construction_refuses measures);
sealing the coproduct would have been a permanently green wall.

Executed evidence: test.claim.fabric_m0_origin_readback_seal (three forged-literal REDs,
an unadmitted-mint RED, a green control on the sanctioned route, and a calibration that
the control compiled) and test.claim.fabric_m0_origin_readback_real_execution_witness
(real bytes: two fixture files digest to their own values, an absent path refuses, and
the whole gate publishes only when the readback digests the recorded manifest).

Rung, as the minimum: the sub-class "a confirming readback whose digest was not computed
over the file it names" is structurally impossible on source->dag outside an enumerated
admission. The enclosing class stays mitigatable -- staged_path is still caller-chosen --
with the capability trigger declared once in fabric_m0_origin_readback.

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

* Route the real-bytes half as an instrument: a changed witness is planned regardless of the exclusion frontier

CI floor red on the landing run: five identities in
test.claim.fabric_m0_origin_readback_real_execution_witness errored
`undefined variable: path` and blocked as
changed_witness_planned_without_terminal_verdict.

TWO DEFECTS, and the second is the one worth writing down.

1. The parameter spelled `path` did not bind under whole-corpus preparation, while
   the same source ran green under a scoped entry compile. Renamed to `staged`.

2. The witness_exclusion_frontier row did NOT keep the wet file off the floor, and
   could not have: v2.workflow.required_floor
   required_floor_disposition_with_changed_selection REPLACES the ordinary
   disposition — DeclinedDiscoveryExcluded included — with PlannedAsChangedWitness
   for any identity the change touches. That is deliberate; the rule's own words are
   that the change is the moment its author is present to route it, rename it, or
   remove it. Under the hermetic envelope crypto.Sha256Sum.File replays one constant
   digest for every path, so the discriminating arm is false there by construction.

So the file is routed the third way: it becomes the instrument
tools.fabric_m0_origin_readback_probe with a `probe` entry and its recipe, per DESIGN
§6 (name the producer that re-derives the measurement), and the inert exclusion row is
deleted rather than left standing as coverage. Its standing is stated in the module: no
required lane executes it; the compile-refusal half in
test.claim.fabric_m0_origin_readback_seal is what runs per PR, and that one passed on
the failing run.

`gunbc run --claim-run ... --function probe` PASSes on the real tree.

The remaining floor phases (parse, namespace-wave-admission) are red on main at
0d6b665 with verdict=FloorClean and phases_failed=2 — inherited, not from this branch.

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

* Delete the fixture mint: an admitted wrapper was an unrestricted constructor, so the rung-4 claim was inflated

Three findings from review, all probe-confirmed rather than taken on faith, plus one
found while repairing them.

FINDING 2 (the one that had to be fixed). The seal claimed the invalid state was
unwritable "outside an enumerated admission". It was not. .dag has no module-private,
so witness_origin_reading's admitted caller -- a plain exported
`fn witness_reading(d) -> OriginReading` -- was itself an unrestricted constructor
proxy. A foreign module importing it and passing any digest reached ManifestRead with
0 blocking errors. DESIGN 4b(1): an inflated class never ranks for climbing.

admit_callers on the wrapper would only move the proxy one hop, because every helper
returning a value CARRYING a reading is the same escape (object_reads, confirmed,
reads_with_* were all proxies) and the cascade terminates only at functions that carry
nothing outward. So the fixture route is DELETED, not fenced: both witness files now
obtain readings the only way anything can, by digesting a committed fixture file
through read_origin_staged_file. Mismatch arms move to the RECORDED axis -- an
authority cannot choose what it reads back. The escape's exact source is kept as a
permanent regression control (4b(4)).

PREREQUISITE, and a finding of its own: extdeps.crypto.hash crypto.Sha256Sum.File's
mock_response interpolated the input path into its canned line. It was the only such
interpolation in any extdeps mock, refused NoSuchVariable on every hermetic call, and
had therefore never once replayed -- a mock that cannot execute, reading as hermetic
coverage. Repaired to a literal; verified by running a consumer under --dry-run before
and after.

CORRECTION: that mock, not a parameter name, is what caused the `undefined variable:
path` on run 34441858589. Two changes went in together and the rename got the credit.
Isolated by running a consumer with no identifier `path` in it at all. The false
attribution is corrected in place rather than quietly edited.

FINDING 3. The seal battery counted by diagnostic CLASS alone and accepted >= 1, while
gunbc.compile_diagnostic_census states that CensusObserved carries every diagnostic the
compile produced, the imported closure included. Every count is now keyed
(class, subject_name, blocking) -- subjects measured, not guessed -- and the bare-zero
calibration is replaced by a one-axis differential where the shared closure cancels.

FINDING 1. "A CACHE READ HAS NO ROUTE TO A CONFIRMATION" was stronger than the
implementation: a caller can hand a /var/cache path to read_origin_staged_file and get
an honest confirming reading. cache_manifest_read is a safe helper, not a total
classifier, and the prose now says so. Path provenance stays the mitigatable enclosing
class with its capability trigger; the rung is unchanged.

Executed: six seal arms PASS with exact keys; commit witnesses PASS wet and hermetic,
including the mismatch arm; the wet instrument PASSes end to end.

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

* Retract the merged rung-4 claim explicitly, and file the class the escape belongs to

The wording repairs the previous commit's code changes earn but its text did not say.

RETRACTION, NOT ADJUSTMENT. #10934 merged the claim that the sub-class was
structurally impossible "outside the enumerated admission". That claim was NOT
established at the head that merged it -- the public wrapper route was open -- so an
inflated guarantee stood on main between that merge and this PR. "The rung is
unchanged" was the wrong sentence: the rung was never held. It is withdrawn in the
corpus row and in the module prose, and this PR re-earns it.

THREE PROPOSITIONS, UNBLURRED. (i) the digest was computed over the file the reading
names -- re-earned structural impossibility on the source-to-dag path; (ii) the named
file was the origin operation's own output -- still mitigatable; (iii) a
caller-supplied /var/cache path remains possible and must never be described as an
origin read. Only (i) climbed.

EVIDENCE STANDING, SEPARATED BY INSTRUMENT. The required hermetic witnesses establish
the modeled effect route and the verdict algebra USING THE MOCK; they do not establish
that real bytes were hashed. The repaired mock makes that route executable, not wet.
Only the hand-run instrument shows the live handler computing over real bytes, and no
required lane runs it. The compile-refusal battery shows a third thing and touches
neither.

NARROWER REGRESSION CLAIM. The foreign-wrapper control is evidence that the KNOWN
escape remains deleted, not that every imaginable proxy is absent.

EGRESS ANSWERED, NOT ASSUMED. Enumerated mechanically: every function in either witness
module returning a value that carries an OriginReading requires one as a parameter, so
it propagates and never mints. The only zero-argument egress is the sanctioned read,
whose result a caller cannot aim.

NEW CLASS FILED SEPARATELY: gunbc.recurring_failure_mode
admitted_call_edge_with_unrestricted_value_egress -- an admission list confines the CALL
EDGE and says nothing about where the value goes next, so a sealed constructor with an
admitted caller is sealed only if that caller's egress is closed. Recognition rule: do
not ask who may call it, ask what may leave. It is its own class rather than folded into
the digest row, which is about a value and a summary standing side by side.

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

* Repair main: the publication witness still imports the ReadSource variants #10934 deleted

main's required floor fails the declarations phase with IMPORT-MEMBER-ABSENT at
dag/test/claim/fabric_m0_publication_witness_test.dag:39-40, which blocks the floor for
every open PR in the repo. Two individually-green PRs from one lane, incompatible only
once both were on main: #10933 landed this witness against the old shape while #10934
replaced ManifestRead's digest-plus-provenance-stamp pair with a sealed OriginReading
and deleted ReadSource / DurableOriginRead / DisposableCacheRead with it. The file also
still built ReadbackConfirmed { observed_digest }, so the two imports were the visible
half of a wider skew.

The repair INHABITS the new construction rather than reaching around it: the reading
comes from read_origin_staged_file over a committed fixture file, the recorded digest is
DERIVED from that reading so a success arm cannot drift from what was read, and the
cache arm goes through cache_manifest_read. Restoring the deleted variants, or adding
this module to witness_origin_reading's admit_callers, would both have been smaller and
both would have re-opened what #10934 closed.

CARRIES ONE LINE OF extdeps.crypto.hash, and it is a prerequisite rather than scope
creep: crypto.Sha256Sum.File's mock_response interpolated the input path into its canned
line -- the only interpolation of its kind in any extdeps mock -- so it refused
NoSuchVariable on every hermetic call and had never once replayed. Without that repair
these witnesses cannot execute hermetically at all, which is exactly what they did here
before it was applied. The same one-line change is also in #10972; whichever lands
second sees no conflict.

Executed hermetically (--dry-run, the envelope CI uses): all five publication witnesses
PASS, including the cache-read refusal and the two pending arms.

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

* The live-tree stamp had to change with the body

This witness declared SubstrateInputsOnly and was correct to: it was a pure fold over
authored fixtures. The repair in this PR makes it call read_origin_staged_file over a
committed repository path, which reaches a live-checkout sink, so the stamp became a
declaration asserting something its own body contradicts -- and nothing in the toolchain
compares the two.

Found by review on the sibling PR (#10972, review 63276), which caught the same class in
all three fabric-M0 witness files. It is the stale-evidence class this lane has been
repairing all along, one scale down: a carrier-grain declaration that outlives the body
it describes.

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

* Key the regression control on a measured subject, make the differential real, and stop three stamps from lying

Review 63276 (REQUEST_CHANGES) on #10972, both findings verified at source before fixing.

RED 4 WAS UNKEYED, and it was the worst place for that defect to be: it is the permanent
4b(4) regression control for the escape this PR exists to close. It read "any blocking
diagnostic anywhere >= 1", and its own comment claimed the assertion was on the
unresolved-reference class while the code asserted no class and no subject.

MEASURED RATHER THAN GUESSED: dumping the blocking key set of that probe's closure
returns FORTY-FIVE rows -- UnresolvedType on Time, Memory, Frequency and thirty more,
plus an InternalError cascade -- so the control was satisfied by closure noise. If the
wrapper proxy came back AND any unrelated blocking row existed, it would stay green and
report the escape as still closed. The proposition is "the wrapper symbol is gone", the
row that says so is MissingExport on witness_reading, and there is exactly one of it.

THE DIFFERENTIAL IS NOW REAL. Both arms come from one probe_source producer, so module
header, import block and signature are byte-identical and only the constructing
expression differs. The comparison is over the COMPLETE blocking key set of each
compile, not a chosen target key: everything present on both sides cancels, exactly one
key survives on the RED side (SoleConstructorViolation|OriginReading), and nothing
survives on the GREEN side. The previous form compared two hand-written sources whose
imports differed, so the shared closure was ASSUMED to cancel rather than shown to. A
calibration arm carries the CensusNotRunnable sentinel into the key set so a
both-sides-failed census cannot cancel and read as agreement.

EXACT COUNTS where exactly one refusal is the proposition, replacing >= 1, so a second
unintended refusal is visible instead of absorbed.

THE LIVE-TREE STAMPS WERE LYING. All three fabric-M0 witness files declared
SubstrateInputsOnly and were correct to before this PR; deleting the fixture mint makes
them call read_origin_staged_file over a committed repository path, which reaches a
live-checkout sink. Nothing in the toolchain compares a stamp to the body beneath it, so
this is the stale-evidence class this lane keeps finding, one scale down: a
carrier-grain declaration that outlived the body it describes. The publication witness's
stamp is fixed on #10977 as well, since that PR introduces the same call.

Executed: all seven seal arms PASS, including the complete-key differential and its
calibration.

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

* Delete the unconsumed digest_a_unused_marker residue, and name the diag entries' consumer

Review 63291 (REQUEST_CHANGES), verified at source: `digest_a_unused_marker` had exactly
one occurrence in the tree -- its own definition -- with a stray blank line as its first
body line. It is the authored "aaaa..." digest left over from the deleted fixture-mint
route, surviving as an artifact of the scripted rename that replaced it, under a name
that admits it is unused. DESIGN 3c makes an unconsumed declaration with no declared
frontier the red state and 6 names it experimental residue, doubly so in a PR whose
whole point is that success arms DERIVE their digest from the reading instead of
authoring one. Deleted rather than given a frontier, because there is no later consumer
to name.

SWEPT FOR THE SAME CLASS rather than fixing only the reported instance, since these files
were edited by transform and that is exactly how such residue appears. The first sweep
was useless and worth saying so: counting textual references flagged all 58 `test fn`s,
which the harness consumes without any reference -- a candidate list, not a detector.
Filtered to non-harness declarations, the only survivors are the three `diag_*` printed
diagnostics, which are a real consumption route rather than residue: they are entry
points a person runs when an arm reds, the same shape as the f10_diag_* / f13_diag_*
entries in test.claim.sole_constructor_completeness_audit_probe. Their consumer and the
exact invocation are now stated in the file instead of left to be inferred.

Executed after the deletion: completion witnesses still PASS hermetically, seal battery
compiles clean.

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

* Make the differential genuinely one-axis, and compare it as a multiset

Both findings verified at source before fixing.

TWO AXES CALLED ONE. The pair shared imports and signature prefix but the bodies differed
in RETURN TYPE as well as expression -- OriginReading vs OriginReadingOutcome -- so a
delta attributable to the type change alone was not excluded. That is the same overclaim
class this PR exists to repair, and the second one I have had to correct in this file.

A SAME-RETURN-TYPE PAIR TURNED OUT TO BE AUTHORABLE, so it is built rather than
disclosed: both arms now return OriginReadingOutcome, which works because that is an
ordinary coproduct whose OriginReadingTaken variant CARRIES the sealed record. The forged
arm must still write the forbidden literal and still refuses on it, while the shapes on
either side match exactly.

And the reason a bare-OriginReading pair is NOT authorable is worth stating, because it
is the wall itself: a green arm returning a bare reading would have to unwrap the
Outcome, and the unavailable branch would then need to produce an OriginReading from
nothing -- which is exactly what has no constructor.

SET DIFFERENCE IGNORED MULTIPLICITY. keys_only_in filtered "keys of a absent from b", so
a key occurring twice on the red side and once on green cancelled completely and a second
unintended refusal on an already-shared key was invisible -- the precise failure the == 1
assertions elsewhere in this file exist to close, left open in the comparison meant to be
the strictest thing here. Replaced by a per-key multiset comparison over the distinct key
union: the target key must be exactly one higher on the red side, and EVERY other key must
match in count.

The calibration arm drops its inverted key_only_in trick for a direct count of the
CENSUS-NOT-RUNNABLE sentinel on each side.

Unaffected and unchanged: the three == 1 refusal assertions and MissingExport x
witness_reading == 1.

Executed: all seven arms PASS. The delta check passing is itself the stronger result --
it says the two closures are identical count-for-count on every key except the wall.

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

* Home the keyed comparator in the census module; my copy was a fork and it was the weaker one

Review 63308, both findings verified at source.

A SECOND IMPLEMENTATION OF ONE FACT. My seal battery hand-rolled blocking_keys /
key_count / distinct_keys / key_delta_is_exactly over "class|subject" strings. That
comparator already existed, general and row-typed, in
test.claim.machine_intake.no_fallback_plan_ineligibility_wall_test -- and
gunbc.compile_diagnostic_census names THAT RECEIPT by name as the authority for exactly
these two exact forms. Two sources that can drift for one fact is the DESIGN 3 fork.

AND THE COPY DROPPED count, which is the defect the previous commit claimed to close.
The census module states in its own words that census_total_count sums counts rather than
rows, so a class occurring twice is two occurrences. My key_count tallied ROW ENTRIES, so
a red row with count 2 and a green row with count 1 at one key still cancelled -- the
multiplicity blindness I had just replaced set-difference to remove, reintroduced one
layer down. It also made "one" mean two things in the same file: keyed_count summed
r.count, key_count did not.

THE REPAIR IS THE HOME, NOT A THIRD COPY. census_key_count, census_key_delta and
censuses_differ_by_exactly_the_target_key now live in gunbc.compile_diagnostic_census --
the module that owns the rule -- parameterised by the target key. Naming a receipt as the
authority for a form does not make the form reusable; the function does, and the proof is
that the next battery to need it re-implemented it and got it wrong.

BOTH CONSUMERS MIGRATED, so there is one implementation rather than three: the
machine_intake receipt keeps its target_class / target_subject rows and passes them, and
its local four helpers are deleted.

Executed: the seal battery's seven arms PASS; the machine_intake receipt's four PASS,
including an_equal_cardinality_identity_swap_is_refused_by_the_comparator, which is the
discriminating control for the comparator itself and is what says the migration preserved
its semantics rather than merely compiling.

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

* Import the comparator name I moved: the whole-pool resolver hid a binding change the namespace wave caught

Floor blocker at 5205eca, phase=namespace-wave-admission, 1 unadjudicated delta:
NewUnresolvedness on `census_key_count` in
test.claim.machine_intake.no_fallback_plan_ineligibility_wall_test.

When the comparator moved into gunbc.compile_diagnostic_census to de-fork it, that
receipt's local copy was deleted and the name was never added to its import block, while
line 126 still calls it.

WHY THE ENTRY COMPILE MISSED IT, which is the reusable half: the resolver is whole-pool,
so the bare name resolved from the census module with NO import edge and the compile
reported 0 blocking errors. The namespace wave compares bindings between base and head
and is stricter. Entry-compile closure is not the floor preparation denominator, so a
clean entry compile is not evidence that a declaration move is complete.

Swept rather than spot-fixed: every census_* name called in both touched files is now
checked against its import block, not just the one the log named.

Also renames this battery's probe_source to origin_reading_probe_source. That is
insurance, NOT a diagnosis -- it collided with an existing declaration of the same bare
name in where_refinement_predicate_vocabulary_witness_test, but census_of is declared in
15 files on main, so duplicate bare names across witness modules are evidently tolerated
and this was never the blocker.

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

* Give the homed comparator a fresh spelling, so the move is a deletion and an addition rather than a silent rebind

Floor at da3e66b was down to ONE blocker: namespace-wave-admission, 1 unadjudicated
delta -- TargetChanged on `census_key_count` in
test.claim.machine_intake.no_fallback_plan_ineligibility_wall_test. Base bound that
spelling to the receipt's own local declaration; head bound it to the one I homed in
gunbc.compile_diagnostic_census.

THE WALL IS RIGHT. A spelling that keeps its text and changes which declaration it admits
is invisible to a reader of either side alone, which is exactly what it refuses until
admitted.

THE CHEAP ADMISSION WAS THE WRONG PRICE. NAMESPACE_TRANSITION_ADMISSIONS is hand Rust in
src/v1/stage0, deliberately standing EMPTY, and its own justification carries the operator
ruling that a request to add hand Rust is the occasion to migrate or delete hand Rust.
Buying a one-row permission there to paper over a name I chose would spend a guarded
surface on my own convenience.

SO THE DELTA IS REMOVED RATHER THAN PERMITTED: the homed function is census_count_at_key,
a spelling authored on neither side before. `census_key_count` is now authored nowhere, so
no name rebinds; the change reads as the deletion and addition it actually is. Verified
that this was the ONLY colliding spelling by diffing the receipt's base-local declaration
names against the names homed in the census module -- the other four were already fresh.

It is also the better name for the reason the wall exists: a homed function sharing its
name with the local copy it replaces is precisely what makes the rebind unreadable.

Executed after the rename: all three files compile clean, and both batteries still pass --
including an_equal_cardinality_identity_swap_is_refused_by_the_comparator, the
discriminating control for the comparator, and the seal's complete-key differential.

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

* Name the consumers instead of claiming there are none, and drop a citation to a deleted variant

Review 63698 (REQUEST_CHANGES), both verified at source.

AN ABSENCE CLAIM DECAYED INTO A FALSE ONE. fabric_m0_commit's consumption annotation
read "exercised by the enrolled witnesses and by nothing else: no production route
reaches it". True when written, false now: gunbc.fabric_m0_publication publish_work calls
publish_after_commit, and so does the instrument tools.fabric_m0_origin_readback_probe.

That is exactly the decay DESIGN 3c's instruction prevents -- NAME THE CONSUMER AND THE
ROUTE -- because a named join survives a change that "nothing else" does not. An absence
claim is falsified by anyone adding a caller and tells no one it has gone stale. Both
consumers are now named with their routes, and the frontier is relocated to where it
actually sits: publish_work itself is reached by no JOB-ENDING, which is the missing
capability, not a missing caller one layer down.

AND A CITATION TO A SYMBOL THAT NO LONGER RESOLVES. fabric_m0_publication warned that
wiring the join through would "fabricate DurableOriginRead" -- a variant #10934 deleted
and this PR's own receipts record as deleted. DESIGN 3's cite-the-symbol rule exists to
prevent precisely that. The hazard is real and unchanged, so the sentence keeps it and
loses the stale spelling; the note also records that fabricating a confirming readback is
no longer expressible at all, since one carries an OriginReading that only
read_origin_staged_file can produce. This PR edits the sibling annotation carrying the
same sentence, so it is the place to repair it.

SWEPT FOR THE CLASS rather than the two instances: every name this lane deleted
(ReadSource, DurableOriginRead, DisposableCacheRead, witness_origin_reading,
witness_reading, census_key_count) now resolves nowhere, and each remaining mention in
the touched files is PAST-TENSE narrative in a retraction receipt -- which is what a
receipt is for -- or the regression-control source string, where witness_reading must not
resolve because MissingExport on it is the proposition. Only the publication sentence was
a live-tense claim.

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

* Stop repeating the rotting absence claim one layer up, and apply the rule to the other three

Caught at ad451a8 by keen-dove-322, verified at source: the repair's own text said
"publish_work itself is reached by enrolled witnesses and by no JOB-ENDING" -- the SAME
SHAPE the edit exists to remove, one layer up, in the commit that removes it.

THE RULE, WHICH IS NOT "BAN ABSENCE CLAIMS". A live claim is admissible when every
mutation able to falsify it must also invalidate or recompute it, or when it is bound to
an immutable snapshot. Three legitimate shapes: STRUCTURALLY TRACKED (`A calls B`, derived
from named identities -- adding another caller does not falsify it); COMPLETE-POPULATION
DERIVED (invalidated when the population changes); SNAPSHOT-BOUND (a historical
observation cannot rot). Refused: a live open-world negative with no producer and no
revalidation dependency. Universal negatives are not intrinsically invalid; UNTRACKED
MUTABLE ones are.

FIXED, and applied to every instance in this diff rather than the one reported:

1. publish_work's frontier -- the negative is DROPPED. The paragraph after it already
   states the frontier positively as the capability that closes it, which is the tracked
   shape and carries the whole meaning. Section 3c asks who consumes this and by what
   route, never for the complement of the consumer set. The deleted draft is quoted in
   place so the correction is its own receipt.

2. "read_origin_staged_file is the ONLY constructor" -- KEPT, with why it does not rot.
   OriginReading is sole_constructor, so every out-of-module construction is a compile
   refusal; and the only mutation that could add a second mint is an edit to this very
   file. Tracked on one half, locally falsifiable on the other.

3. The egress claim over the two witness modules -- SNAPSHOT-BOUND. A zero-argument helper
   added to either would falsify it from a different file, so nothing recomputes it.

4. The instrument's "no required lane executes this" -- restated POSITIVELY (its consumer
   is the hand-run recipe) with the complement dated. Enrolling it happens in a CI roster,
   a different file again.

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

* Restore main's consumption paragraph this branch had silently resurrected over, and withdraw a refuted justification

TWO CORRECTIONS, both from keen-dove-322, both verified at source before acting.

1. I DID NOT AUTHOR THE ABSENCE CLAIM I WAS TOLD I HAD REPEATED, and accepting that
characterisation was itself an error. gunbc#10933 corrected fabric_m0_commit's consumption
paragraph IN THE SAME COMMIT that added publish_work -- an atomic, correct edit naming the
join. This branch carried the superseded "exercised by the enrolled witnesses and by
nothing else" text back over it, and I then "fixed" that into a THIRD divergent version.

ROOT CAUSE, and it is mine: the `--ours` resolution I took when gunbc#10934's squash
collided. The check I ran at that moment asked whether main had touched those files AFTER
the squash commit. gunbc#10933 touched this one BEFORE it. A clean merge raises nothing
and a two-dot diff against main is the only thing that would have shown it -- which is why
the receipt is in the file rather than only here.

REPAIRED BY ADOPTING MAIN'S TEXT AS THE BASE, not by keeping my rewrite. Layered on it,
and only this: the instrument is named as the second consumer; the clause "today it is
reached by enrolled witnesses and by no job-ending on a run path" is DROPPED as a live
open-world negative with no producer and no date, since the trigger below already states
the same fact positively; and "fabricating DurableOriginRead" loses a spelling gunbc#10934
deleted, with the note that a confirming readback is no longer fabricable at all.

SWEPT THE REST OF THE BRANCH for the same resurrection signature rather than trusting that
one paragraph was the only one: of the eleven files differing from main, every other
deletion of main-side content is deliberate, and no other file drops gunbc#10933-era text.

2. THE LOCALITY JUSTIFICATION IS WITHDRAWN where I had written it into
fabric_m0_origin_readback. I argued that the only in-module mutation is an edit to that
file, so the claim could not rot under a reader. That is refuted by
gunbc.recurring_failure_mode.stale_claim_survives_its_own_correct_edit, which records an
author retracting a claim at its definition site while leaving a restatement two screens
below in the SAME file and the SAME diff, surviving four review rounds. Co-location makes
the join available; it does not perform it. The negative stays because it is
STRUCTURALLY TRACKED -- sole_constructor makes every out-of-module construction a compile
refusal -- which would hold even if the falsifier lived elsewhere. Falsifier locality is a
recognition heuristic for where to look, never a licence.

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

* Drop the live open-world negative I had just added to the authority module

Review 63733, first finding, verified at source and mine. While dating that same
complement in the probe file, I wrote the LIVE form of it into
fabric_m0_origin_readback: "Only the hand-run instrument ... and no required lane runs
it". Enrolling the probe is a CI-roster edit in another file, so nothing here invalidates
or recomputes the sentence -- the rotting shape, two screens below the paragraph where
this same commit withdraws locality-as-licence for exactly that form.

The positive half was already there and carries the meaning: the instrument is what shows
the live handler computing over real bytes. The complement now lives once, dated, in the
instrument's own annotation, which is where its execution standing belongs.

Also splits a run-on the earlier edit left: "Three instruments, three propositions. It
does NOT close whether..." ran two unrelated claims together, so the seal's residual
boundary now has its own paragraph.

THE SECOND FINDING IS NOT TAKEN, deliberately, and the reason is on the PR: the
publish_work definition-site negative in fabric_m0_publication is gunbc#10933's text, and
keen-dove-322 has routed that lane's instances of this class rather than have this PR
widen into them. I was corrected earlier in this same PR for overwriting that lane's
annotation in this same file family; doing it again unasked is the wrong instinct even
when the edit would be an improvement.

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

* Replace publish_work's live frontier negative with named consumers, a capability, and a dated complement

Review 63733's second finding, now taken: keen-dove-322 confirmed gunbc#10933 was authored
by swift-bat-747, the B1 lane of this milestone, which they briefed and archived when it
merged. There is no other lane's annotation being edited unasked and no author to ask --
the owner is the manager, and they asked for it here.

THE DECLINE WAS RIGHT AS A RULE and is preserved as one: a second parallel version of
someone's text at their own definition site is exactly how this PR's earlier --ours
resurrection began. This instance is an exception because the owner is the person routing
it, which is a fact I could not have known.

REPLACED, in the shape asked for:
  - CONSUMERS NAMED POSITIVELY: test.claim.fabric_m0_publication_witness calls this fold
    across its five publication arms. Verified, not assumed -- those five call sites are
    the only callers of publish_work in the corpus.
  - THE FRONTIER STATED AS THE CAPABILITY THAT CLOSES IT: a job-ending holding a run's
    Work, that attempt's commit transport, and an independent origin readback of the
    commit manifest, deciding the conclusion from the JobPublication this fold returns.
  - WHY THE REQUIRED-CI ENDING IS NOT THAT CAPABILITY is kept verbatim in substance,
    because it is the load-bearing part: that ending never constructs
    CommitTransportOutcome or ManifestReadbackObservation, so wiring the join into it
    would refuse every green job or fabricate a confirming readback.
  - THE COMPLEMENT DATED TO A SHA rather than to a word: measured at gunbc#10972 against
    main 51405ad. "TODAY" is not a binding -- nothing derives that negative, nothing
    recomputes it, and the mutation that falsifies it happens in another file.

SWEPT the whole diff for the class afterwards: the only surviving occurrences are
backtick-quoted historical text inside the two correction receipts, which is what a
receipt is for.

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

* Scope the conflict negative: there WAS a conflict at the squash, and none at the later integrations

The receipt read "No conflict was raised and no merge commit touched the file: the
resurrection came from a --ours resolution taken when the squash of gunbc#10934 collided".
Meant as two facts about two different merges; reads as one self-contradicting sentence,
because an --ours resolution is what you do when there IS a conflict. A reviewer already
took it that way, which is the only evidence that matters about how a sentence reads.

Costly in this paragraph specifically: its whole subject is a claim that did not survive
contact with its evidence, so an ambiguous mechanism here reads as the defect being
described rather than the correction.

SPLIT INTO THE TWO MERGES IT WAS ALWAYS ABOUT, with the negative scoped to the later one:
  - EARLY: gunbc#10934's squash DID collide, which is what the --ours resolution answers,
    and the check run at that moment asked only whether main had touched the file AFTER
    the squash. It had touched it BEFORE, inside the range that question excludes.
  - LATER: by then only one side had touched the file, so git had nothing to conflict
    about and correctly kept the branch text. Merge 542e069 is named as the
    observation, dated by construction: its base already contained gunbc#10933 and its
    result nonetheless carried the superseded paragraph. VERIFIED, not asserted -- that
    merge contains 0db47c5 by ancestry and `git show 542e069:<file>` still has the
    superseded text.

Also states why nobody caught it: a three-dot diff compares against the merge base, so
branch text reverting main reads there as no change at all, and only
`git diff origin/main HEAD` shows it.

No new claim, one paragraph, nothing else on this head touched.

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

---------

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