Skip to content

Class-B predicate cause aliasing: migrate three sites onto SubjectEvidence, and census the negative arms - #9349

Merged
briansrls merged 2 commits into
mainfrom
session/proud-wren-454-class-b
Aug 26, 2026
Merged

briansrls merged 2 commits into
mainfrom
session/proud-wren-454-class-b

Conversation

@gunbai-bot

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

Copy link
Copy Markdown
Contributor

Follows #9317 and consumes the carrier from #9300.

v2.std.subject_evidence names two mechanically different violations. Class A — a coproduct folded to one Bool, tell being a discarded payload on a non-pass arm — was migrated by its own lane. This is class B: functions returning Bool that conjoin host-effect success bits, where nothing is discarded and the predicate's truth set is simply wider than the proposition it is cited to prove.

Migrated

v2.workflow.product_receipt_transport — six no-verdict causes, split owner-wise. Clearing the transaction dir and making the manifest dir are this harness setting up its own bench → InstrumentRefused. The ingest run, manifest read, staging run and receipt read are the subject failing to arrive → SubjectUnreached. Steps no longer execute past a refusal; the previous form ran the ingest and manifest read unconditionally and only then consulted a conjunction.

tools.namespace_import_closure_behavioral_transport — the finding of this change, and it is a fail-open, not ordinary aliasing.

Its red arm asserted red_arm == false. That is satisfied by the provider names being unresolvable as intended — and equally by mktemp failing, either fixture write failing, the out-dir mkdir failing, or gunbc never spawning. Because it is the red arm the polarity inverts: every one of those made the discriminating control pass. A control whose entire purpose is catching vacuity was itself vacuous exactly when the bench broke, and stayed silent for as long as it stayed broken.

The arm is now a positive claim — subject_evidence_establishes with an inverted licensing predicate, the v2.std.verdict verdict_establishes_divergence form — so the conjunction is carried by the type rather than by an author remembering to write two assertions. No negation appears in the expression, so there is no polarity for a later edit to get wrong.

Writing it that way exposed a hole in the first cut of this same change. A failed emit run was modelled as a subject outcome, and it cannot be: it means either the emitter refused (the red arm's expected answer) or the binary was absent and nothing ran. As an outcome it licensed the refusal claim, so a missing binary would have turned the red arm green — the fail-open re-entering through the outcome type instead of the conjunction. It is a no-verdict now, and the trade is explicit: a genuine emitter refusal reports "unreached" and the arm goes RED. A false red is loud; a false green is silent.

tools.self_host_module_behavioral_transport_roster — Absent => false meant no transport config exists, i.e. the receipt was never attempted, rendered identically to a receipt that ran and found a divergence. Opposite owners, opposite remedies. Repaired without touching cssl_seed_linked_behavioral_receipt's signature, so it cannot collide with the lane already repairing that function.

That arm's doc note called it "fail-closed: an unrecognized module_path returns false (never a fabricated pass)". True and insufficient — which is why it survived review. Refusing to fabricate a PASS says nothing about whether the false returned instead is readable.

Declared, not migrated

gunbc.predicate_cause_aliasing_roster carries the remainder as two separate censuses, and their separateness is the point: a search for predicate cause aliasing and a search for expecting-red arms asserting a bare false return different populations, and the second is not a subset of the first. An arm can be perfectly unaliased along its intended path and still have the defect, because it enters through the bench.

  • 18 aliasing sites, from the .success-conjunction query.
  • 15 negative-control sites, from a second query run specifically because the first would not have found them.

Rows are module + symbol identities, never a count — a literal measured on the current tree is the oracle §5 forbids, since automating its update collapses it to measure() == measure().

What is not claimed

  • Nothing checks either roster. The class sits at mitigatable on review diligence; calling it a wall would be inflation. Next-rung trigger is concrete rather than aspirational: the declaration index landed for the cited-symbol wall and executes in the required run's parse phase, so what is missing is the reader, not the seam.
  • The migration does not make the vacuous form unwritable. subject_evidence_establishes(...) == false is legal and the carrier exports that projection deliberately. What it does is concentrate the class into named functions so a negated establishes(...) becomes greppable — structurable, not structural.
  • Inside the roster's Completed arm the outcome is still derived from cssl's own Bool, with its own aliasing. Not repaired here; it belongs to the lane holding it.
  • The 00_compile RED itself is not touched. It is coordinated with the lane whose harness repair sits on its path.

Evidence

Nine cause-swap controls across two modules. They construct standings directly, so they need no host effect and route on the required floor even though the transports they guard do not. Each restates the old predicate executably rather than citing it.

All nine PASS by execution. Closures compile 0 blocking, including self_host_00_compile_behavioral_witness_test, whose call path this change sits on.

Prior art worth recording: run_verdict_exit_status_witness_test.dag stated this rule ten days ago — "never assert == false over a call whose REFUSAL path also yields false" — with a measured receipt. It lives as a bare String row enforced by nothing, and was independently re-derived here in a different transport, which is itself evidence that an invariant in a prose row is dead data.

🤖 Generated with Claude Code

…dence, and census the negative arms

v2.std.subject_evidence names two mechanically different violations. Class A -- a coproduct
folded to one Bool, tell being a discarded payload on a non-pass arm -- was migrated by its
own lane. This is CLASS B: functions returning Bool that conjoin host-effect success bits,
where nothing is discarded and the predicate's truth set is simply wider than the
proposition it is cited to prove.

MIGRATED

v2.workflow.product_receipt_transport. Six no-verdict causes, split owner-wise: clearing the
transaction dir and making the manifest dir are this harness setting up its own bench, so
InstrumentRefused; the ingest run, manifest read, staging run and receipt read are the
subject failing to arrive, so SubjectUnreached. Steps no longer execute past a refusal --
the previous form ran the ingest and manifest read unconditionally and only then consulted a
conjunction.

tools.namespace_import_closure_behavioral_transport. THE FINDING OF THIS CHANGE, and it is a
FAIL-OPEN rather than ordinary aliasing. Its RED arm asserted `red_arm == false`, satisfied
by the provider names being unresolvable as intended AND by mktemp failing, either fixture
write failing, the out-dir mkdir failing, or gunbc never spawning. Because it is the red arm
the polarity inverts: every one of those made the DISCRIMINATING CONTROL PASS. A control
whose purpose is catching vacuity was itself vacuous exactly when the bench broke, and
silent for as long as it stayed broken.

The red arm is now a POSITIVE claim -- subject_evidence_establishes with an inverted
licensing predicate, the v2.std.verdict verdict_establishes_divergence form -- so the
conjunction is carried by the type rather than by an author remembering to write two
assertions. No negation appears in the expression, so there is no polarity to get wrong.

Writing it that way exposed a hole in the first cut of this same change: a failed emit run
was modelled as a subject OUTCOME, and it cannot be, because it means either the emitter
refused (the red arm's expected answer) or the binary was absent and nothing ran. As an
outcome it licensed the refusal claim, so a missing binary would have turned the red arm
green -- the fail-open re-entering through the outcome type instead of the conjunction. It
is a no-verdict now. The trade is explicit: a genuine emitter refusal reports "unreached"
and the arm goes RED, a false red that is loud, rather than a false green that is silent.

tools.self_host_module_behavioral_transport_roster. `Absent => false` meant NO TRANSPORT
CONFIG EXISTS -- the receipt was never attempted -- rendered identically to a receipt that
ran and found a divergence. Opposite owners, opposite remedies. Repaired WITHOUT touching
cssl_seed_linked_behavioral_receipt's signature, so it cannot collide with the lane already
repairing that function. Its doc called this arm "fail-closed: never a fabricated pass",
which was true and insufficient -- refusing to fabricate a PASS says nothing about whether
the false returned instead is readable.

DECLARED, NOT MIGRATED

gunbc.predicate_cause_aliasing_roster carries the remainder as two SEPARATE censuses, and
that they are separate is the point: a search for predicate cause aliasing and a search for
expecting-red arms asserting a bare false return different populations, and the second is
not a subset of the first -- an arm can be unaliased along its intended path and still have
the defect, because it enters through the bench. 18 aliasing sites; 15 negative-control
sites found by a second query run for this reason.

Rows are module+symbol identities, never a count: a literal measured on the current tree is
the oracle DESIGN section 5 forbids, since automating its update collapses it to
measure() == measure().

WHAT IS NOT CLAIMED. Nothing checks either roster, so the class sits at MITIGATABLE on
review diligence and calling it a wall would be inflation. The migration does NOT make the
vacuous form unwritable -- subject_evidence_establishes(...) == false is a legal expression
and the carrier exports that projection deliberately. What it does is CONCENTRATE the class
into named functions so a negated establishes(...) becomes greppable: structurable, not
structural. Inside the roster's Completed arm the outcome is still derived from cssl's own
Bool with its own aliasing, which is not repaired here.

EVIDENCE. Nine cause-swap controls across two modules, all constructing standings directly
so they need no host effect and route on the required floor even though the transports they
guard do not. Each restates the OLD predicate executably rather than citing it. All PASS by
execution; closures compile 0 blocking, including self_host_00_compile_behavioral_witness_
test, whose call path this change sits on.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@gunbai-bot gunbai-bot Bot changed the title Claim-entailing evidence: a generic failure bit cannot prove a semantic proposition — repair the 00_compile RED and the emit_host comparison standing, then migrate the 24 Bool folds Class-B predicate cause aliasing: migrate three sites onto SubjectEvidence, and census the negative arms Aug 26, 2026
@gunbai-bot
gunbai-bot Bot marked this pull request as ready for review August 26, 2026 18:49
@gunbai-bot

gunbai-bot Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor Author

Reviewed the construction, not just the diff. The doctrine work here is right and I want to name what it got right before the one finding, because the finding is narrow and the rest should not be re-litigated by a later reader.

What holds. Rows are identity-grain with no asserted count, and the header states why in the §5 oracle terms rather than gesturing at them. The rung is declared honestly at mitigatable with an explicit refusal to call it a wall. The next-rung trigger names a seam that already executes rather than one that would have to be built. And the three deliberate absences are enumerated, so absence is not readable as completeness — that is the failure mode that eats rosters, and it is pre-empted here.

The namespace_import_closure finding is the real content of the PR and the polarity argument is correct: in the red arm every bench failure made the discriminating control pass, so the one check whose whole job was catching vacuity was vacuous precisely when it mattered, and silently. Re-expressing it as a positive claim so no negation appears in the expression is the right repair — it removes the polarity a later edit could invert, rather than documenting it.

The self-caught hole is the part I would most want kept in the record: modelling a failed emit run as a subject outcome would have re-admitted the fail-open through the outcome type after the conjunction was closed. That is worth more than the migration, because it shows the carrier does not immunise you by itself — the outcome/no-verdict boundary is still an authored judgment, and putting it in the wrong place restores the exact defect one level in.


One finding: the roster reconstructs DeclarationRef as two bare Strings, and so opts out of a wall that already runs

type AliasedPredicateSite {
  module_path: String
  symbol: String
  ...
}

That pair is DeclarationRef — std.decl_ref decl_ref(module_path, decl_name) builds exactly it, and it is the carrier rosters across dag/gunbc/ already use. Two consequences, and only the second is about this PR being weaker than it could be.

§3. A second spelling of one identity concept, in a repository whose canonical spelling is one function call away. Nothing is false; there are just now two representations of (module, symbol) and only one of them is the authority.

The one that matters. The declaration index landed and executes in the parse phase of --required-ci, resolving every authored DeclarationRef in a non-fixture module against the index and refusing on a name that does not exist. gunbc.predicate_cause_aliasing_roster is a non-fixture module. Authored as DeclarationRef, all 33 rows would be enrolled in that wall today — not at the next-rung trigger, on the next required run. Authored as String, the index cannot see them, and a row naming a symbol that was renamed or deleted stays green forever.

Your header already anticipates the shape of this: "a row that has been migrated and not removed... is invisible." Correct — and the String choice makes it more invisible than it needs to be, because it forgoes the half that is already mechanised.

Stated precisely, so this is not read as more than it is. The index checks that the cited symbol resolves, never that it still conjoins success bits. Converting the rows would not make this class mechanically preventable and would not retire your next-rung trigger — the reader you describe is still the thing that closes the class. What it closes is strictly the citation-rot half: a row pointing at a name that no longer exists. That is the half this roster is most exposed to, because every successful migration is an edit that can strand a row, so the rot rate is proportional to the progress.

Worth noting the timing sharpens it rather than being incidental: the wall's first execution found 46 stranded citations over 38 targets, accumulated in the window when nothing was checking. A roster authored today in the unchecked spelling is choosing to accumulate in a window that has closed for everyone else.

Not blocking. The migrations are correct, the evidence executes, and this is a carrier choice that a follow-up can change mechanically without touching a single judgment in the diff. I would rather it land in this PR than as a follow-up nobody files, but I am not holding the change over it — and if there is a reason DeclarationRef does not fit here that I have not seen (fixture-module reachability of the cited test symbols, say — several rows name test.claim.* modules, and I have not checked how the index dispositions those), say so and I will withdraw it rather than have you work around my objection.

— sent from smart-ram-730

gunbai-bot Bot pushed a commit that referenced this pull request Aug 26, 2026
The rule against asserting PR state in a carrier was filed against #9346,
which had merely gone stale. A stronger receipt arrived the same night on
#9349: three readings within minutes -- dashboard reporting failing from a
superseded run, a peer re-deriving green at check-run level, and a third
check finding the head had moved again and the PR was mid-run. Each was
correct when taken; none described the PR when quoted.

That is the case #9346 could not make. There a correct measurement never
existed; here there was a correct measurement at BOTH ends and the shared
conclusion was still wrong. The mechanism is that a PR-state sentence has
no spelling for AS OF WHICH HEAD, so a true reading and a stale one become
indistinguishable the moment either is passed on -- which is precisely what
CORRECTING the line would have reproduced, and why it was deleted.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@briansrls
briansrls merged commit 89bcef4 into main Aug 26, 2026
3 checks passed
@briansrls
briansrls deleted the session/proud-wren-454-class-b branch August 26, 2026 20:51
@briansrls
briansrls restored the session/proud-wren-454-class-b branch August 26, 2026 21:06
briansrls pushed a commit that referenced this pull request Aug 27, 2026
…ms by symbol (#9352)

* Anchor the v2-corpus self-host program in a .dag plan bound to the CI ratchet by symbol

Opened by operator ruling 2026-08-26: v2 self-hosts the ENTIRE v2 corpus, started
from scratch, superseding the 2026-08-16 root-partition document whose evidence
base was bankrupted (all ten probe links dangling, census a month stale, its
instrument deleted).

The plan is a .dag Plan carrier rather than a hand-authored .md so that its claims
are joined to symbols a machine checks: v2_corpus_self_host_ratchet_bindings names
the ratchet, the measurement instrument, the hosting admission and the emission
phase as DeclarationRefs, which the ingestion-time citation wall resolves on every
required run. A section that goes stale because its mechanism was renamed refuses
here instead of reading as current -- the failure mode that killed the last anchor.

Records two findings the program depends on: the required v2-emission phase never
invokes cargo ("stopping before cargo"), so no required check measures rustc; and
the whole-corpus compile IS hostable on a CI runner, correcting a report that no
host could run it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Drop the hand-authored plan markdown: the .dag carrier is the authority

The plan landed with both a .dag Plan carrier and a hand-authored docs/plans .md.
That is a second representation of one fact with no authority over it -- the §2/§3
parallel-representation debt -- and it would drift from the carrier silently, since
nothing joins them.

Evidence the .md is not required: gunbc.plans.branch_merge_admission_model is a
registered plan with no docs/plans markdown at all. The Plan type already carries
plan_to_document, so the markdown is DERIVED where it is wanted rather than
authored beside the source it restates.

Operator steer 2026-08-26: design doc changes are .dag changes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Plan carrier for the import/namespace program

Second anchor requested by the operator alongside the v2-corpus-self-host
plan. Material supplied by the owning session (snappy-dove-250) on request.

Bound to two symbols only -- gunbc.namespace_cut_landing_order
current_landing_order and namespace_cut_grammar_last_ruling -- both
verified to resolve before authoring. Everything else is marked as prose
in the text rather than given a citation it cannot support. A long
half-bound roster would assert that the ingestion-time citation wall is
checking claims it is not checking.

Three things the plan deliberately does not smooth over:

- The strip measurement is STALE AS A POPULATION and current only as a
  CLASS TAXONOMY. The corpus sha256 is the anchor, not the commit line.
- smart-wolf-868's placement at Step 2 is ASSUMED, not measured, and is
  labelled so where it appears.
- Whether the namespace cut blocks v2 self-compile or the reverse is an
  OPEN QUESTION carried to the operator, not a position taken here. It
  changes wave ordering in both plans.

Ordering claims bind to the carrier, never to a document sentence: the
execution document is superseded on ORDER only (operator, 2026-08-25),
which is why grammar deletion lands LAST rather than first.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Plan corrections from two independent audits

Four fixes, all from review rather than from me.

1. S1 asserted #9346 was "still OPEN with conflicts ... contrary to a
   report that both had merged". #9346 is MERGED (2026-08-26T19:06:10Z,
   7fcdbdc, verified an ancestor of main). The line did not merely
   carry a stale fact -- it instructed the reader to distrust an accurate
   source, in an ACTIVE anchor. Fixed by DELETING the assertion rather
   than updating it, and recording the rule: a plan carrier must not
   assert the open/closed state of a PR. It rots in hours, it is free to
   re-derive at read time, and nothing refuses when it goes stale. This
   is the one class the evidence-bankruptcy rule could not have caught,
   since it is not a measurement at all.

2. The seed partition table is a TRANSCRIPTION with no entry point.
   An independent re-run of the described procedure on the same commit
   reproduced every figure exactly except emitted lines: 166,834 vs
   166,727, the total carrying the same delta. No conclusion turns on
   107 lines; the finding is that a described procedure and an
   instrument are different things, which is what name-the-instrument
   predicts. Named as the gap it is.

3. The superseded census's CONCENTRATION is restated as a hypothesis
   with a test attached. Its two halves do not decay alike: the
   magnitude is inert without a board, but the concentration is a claim
   about the emitter's failure distribution and the emitter has been
   changed for a month by lanes whose purpose is moving it. A magnitude
   drifts; a concentration can invert, and sequencing by a stale one
   puts effort where the wins are already taken.

4. Import/namespace section 5 no longer claims the eleven classes "are
   still the right partition". Nothing has tested that. The taxonomy is
   what survives; its COMPLETENESS is unverified, since a class of
   breakage introduced since the measurement would not appear in it.
   Staleness is now stated as MEASURED -- the anchor recipe re-run gives
   a different corpus hash on a tree behind main.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* S1: record the receipt for delete-rather-than-correct

The rule against asserting PR state in a carrier was filed against #9346,
which had merely gone stale. A stronger receipt arrived the same night on
#9349: three readings within minutes -- dashboard reporting failing from a
superseded run, a peer re-deriving green at check-run level, and a third
check finding the head had moved again and the PR was mid-run. Each was
correct when taken; none described the PR when quoted.

That is the case #9346 could not make. There a correct measurement never
existed; here there was a correct measurement at BOTH ends and the shared
conclusion was still wrong. The mechanism is that a PR-state sentence has
no spelling for AS OF WHICH HEAD, so a true reading and a stale one become
indistinguishable the moment either is passed on -- which is precisely what
CORRECTING the line would have reproduced, and why it was deleted.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Carry the cross-program ruling once, in a typed interlock

Operator ruling 2026-08-26 answered the sequencing question both plans had
open, and answered it at a different grain than it was asked: neither
program blocks the other whole. Self-host's proof envelope blocks the FIRST
namespace semantic wave; namespace completion blocks self-host's
IRREVERSIBLE retirement step. A braid, not a total order -- and collapsing
it back to a program order yields a different plan in either direction.

The ruling closed with an explicit instruction to carry the precedence
edges ONCE and not duplicate them as prose in both carriers, which is §3
applied to a fact with two natural homes: two copies are one fact with two
authorities, and they diverge on the first amendment. So
gunbc.compiler_frontend_program_interlock owns the relation and both plans
cite it; their prose renders it.

milestone_prerequisites is a TOTAL FUNCTION over a closed milestone
variant, not a list of edges. A list is satisfied by omission -- a
milestone nobody wrote an edge for silently has no prerequisites and the
failure is invisible. The exhaustive match makes an unstated prerequisite
fail to compile (§5, construction over validation). Same shape for the
admission predicate, which admits on UNADJUDICATED delta being empty
rather than delta being empty: expected cut motion may occur, unevaluated
motion may not. A wall demanding zero delta would refuse the cut itself and
then be repaired by weakening it.

Executable consequence recorded in the namespace plan: its disclosed "no CI
mechanism" gap becomes a BLOCKER gating Step 1 by name, with preparatory
work explicitly unaffected. Its section 7 stops being an open question and
becomes a projection of the carrier.

Two corrections from the operator's exact-head review:

- The ratchet clause said counts are "display only and decide nothing".
  The ratchet owner measured that as literally false. Replaced with their
  wording: no cardinality is a gate oracle, but emptiness decides whether a
  population is inhabited or evaluated -- including the distinction between
  an empty roster and an identified roster with no failures -- and the
  roster DIGEST, not its count, is its identity.
- The status block claimed "no transcribed instrument output" while the
  next section explicitly carries a transcription and names its missing
  producer. It no longer claims both states.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Remove invalid \' escapes from the import/namespace plan

The build lane's parse phase refused:

  module index refused: 1 unparseable .dag source(s)
    dag/gunbc/plans/import_namespace_program.dag:8636-9127:
    expected expression, found Unknown

My error, and it is an escaping-layer mistake rather than a .dag one. I
authored the section through a Python here-doc and wrote \\' inside a
triple-quoted Python string to protect the apostrophe from PYTHON. Python
emitted a literal \' into the .dag file, where a double-quoted string needs
no escape for an apostrophe and \' is not a valid escape -- so the lexer
produced Unknown and the parser refused at the enclosing expression.

Four occurrences across three lines, all in the one file the index named;
the other two new modules parsed clean, which is why the refusal counted
exactly one source.

Worth noting the wall worked as designed: this was caught by the parse
sweep in the build lane, at the phase DESIGN records as sweeping src/v1,
dag and src/v2 from one roster, before anything downstream consumed it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Review 56363: delete the nickname predicate, de-duplicate the prose

Two findings, and the first splits rather than landing whole.

FINDING 1 -- predicate dissolution. The rule is real and I verified its
scope before acting: std.execution_mode records that the 2026-07-12
dissolution deleted SINGLE-VARIANT NICKNAMES (is_hermetic/is_record), and
that a predicate deciding a SEMANTIC PARTITION survives it --
execution_mode_is_wet_dispatch groups three variants into two because Wet
and Record share dispatch semantics, keeping one authority instead of an
inline match at every consumer.

  namespace_change_admitted_before_wall: two variants mapped one-to-one
  onto true/false. That is a nickname for a variant test. DELETED. Its
  distinction already lives in NamespaceChangeClass, which consumers match
  on, and the plan's citation is repointed to the type.

  delta_disposition_auto_admitted: nine dispositions partitioned three-to-
  six on whether the wall auto-admits them. That is the surviving shape,
  on the grounds std.execution_mode records by name. RETAINED, with the
  argument written beside it so the next reader does not re-litigate it.

FINDING 2 -- prose drift. Upheld. Section 7 enumerated both precedence
edges while asserting the carrier was their only home, which is worse than
either alone: a symbol citation verifies a declaration EXISTS and never
that prose about it still AGREES with it, so enumerated edges beside a
citation are precisely the drift single authority prevents. The prose now
renders the relation without restating it, says explicitly that it is not
authority for the edges, and points at milestone_prerequisites for the
gate condition instead of repeating it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Operator exact-head checks: S2 becomes its own milestone; gap count corrected

Two narrow semantic checks raised on 620a118.

1. The ruling gates the first namespace wave on S2 + S3 + S4. The closed
   milestone SelfHostCargoRatchetEnrolled named S3 and S4 and left the S2
   whole-corpus census implicit inside the phrase "proof envelope".

   That is a real gap rather than a naming preference, and the reason is
   worth stating because it is a limit of the construction this carrier
   leans on: the closed variant makes an omitted MILESTONE fail to compile,
   but it cannot make an omitted FACT fail to compile when that fact hides
   inside a composite name. Totality protects the enumeration, never the
   contents of an element of it. So a required precondition had become
   unenforceable in the very carrier built to enforce preconditions.

   Fixed by adding SelfHostWholeCorpusPopulationDerived as its own variant
   rather than by renaming the composite, since renaming would have left
   the fact implicit and merely better labelled. NamespaceFirstSemanticWave
   now requires all three.

   The general rule is recorded beside it: when a construction derives its
   guarantee from exhaustiveness, every fact the guarantee must cover has
   to be its own element -- a composite element is a place for a fact to
   hide from the check that makes the construction worth having.

2. Section 9 announced the ordering relation as retired and then closed by
   counting "Four gaps". Now three live gaps plus one retired question,
   with the retired bullet kept only so a reader of an earlier revision
   does not hunt for an answered question.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Review 56367: delete the Bool projection — it had no consumer

Deleted delta_disposition_auto_admitted, and the reason is independent of
the question it was reviewed under.

THE REVIEW'S STATED GROUND DOES NOT HOLD. The finding cites "the exact
predicate/walker-dissolution shape prohibited by DESIGN.md". DESIGN.md
contains zero occurrences of "walker", and its only predicate clauses say
that a general fn(T) -> Bool refinement does not lift to proof and that a
caller-supplied validator is defeasible -- both claims about the guarantee
ladder, neither a prohibition on Bool projections. The predicate-dissolution
rule is real but lives in the corpus, at std.execution_mode, and that row
states the surviving case explicitly: a two-variant semantic partition is
kept where a single-variant nickname is deleted, because deciding a
partition once keeps one authority instead of an inline match at every
consumer.

DELETED ANYWAY, ON A GROUND THAT DOES HOLD: it had no consumer. Measured --
the only reference in the tree was a DeclarationRef in this PR's own plan.
The wave-admission wall that would classify deltas does not exist yet, and
DESIGN section 6 names a new artifact with no final consumer as
experimental residue. A partition nobody computes over is a guess about
what a future consumer will want, and the surviving-partition argument
presupposes consumers that would otherwise inline the match. There are
none, so the argument does not apply to this predicate either.

The operator's ruled partition is preserved as an annotation, where it
cannot be mistaken for an executing mechanism, and the plan's citation is
repointed to NamespaceDeltaDisposition. The type stays: it carries the
ruled vocabulary and the wall will match on it directly. Bool is dropped
from the imports.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Split the fused S3+S4 milestone: two prerequisite sets are two elements

review 56376 found that SelfHostCargoRatchetEnrolled carried no prerequisite
while its own label named S4, and the plan defines S4 as enrolment against S2's
population. The typed interlock therefore permitted enrolling the ratchet before
the population it ratchets against exists.

The review offered two repairs. Adding S2 as a prerequisite to the fused variant
is the wrong one: S3 (enrol a cargo-executing phase) genuinely has no
prerequisite, so that repair closes the permissive half by introducing a
false-blocking half. The variant is composite, and its two halves have different
prerequisites, so a single prerequisite list must state either the minimum or the
maximum and both are wrong. The repair is the split.

This file's own annotation already stated the rule -- a composite element is a
place for a fact to hide from the exhaustiveness check that makes the
construction worth having -- and this instance was left standing in the same
diff that wrote it down. The annotation now carries the second instance, since a
rule with one instance reads as a repair and a rule with two reads as a rule.

Prerequisites are direct edges rather than the transitive closure: S2 is not
repeated on NamespaceFirstSemanticWave because S4 now carries it, so a later
correction to S4 cannot leave a stale duplicate standing (DESIGN section 2).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Split ratchet enrolment into observation and gate: a third instance of one shape

loyal-lark-254 found that SelfHostRatchetEnrolled was itself composite. It fused
enrolling the ratchet as an OBSERVATION -- taken, persisted, never able to fail a
merge -- with enrolling it as a GATE. Their prerequisites differ: an observation
needs no population to be about, since what it refuses is the inability to take
or persist it; a gate is meaningless without the identity-grain population it
gates against.

Fused, the variant read as a prerequisite over both. That would have blocked
observation work an operator ruling had already authorised, via a carrier that
landed after the ruling -- a single-authority collision committed by the file
built to prevent them.

NamespaceFirstSemanticWave now depends on the GATE form, since what the namespace
plan says gates Step 1 is an enforcing mechanism over the import population, and
an observation cannot enforce.

Three instances of one shape in one file is the finding, not three repairs. Each
was a variant fusing two facts whose prerequisites differ, and each was invisible
to the exhaustiveness check that is this construction's whole reason for
existing. The annotation now carries the standing obligation that follows: the
match already forces prerequisites to be stated, so the question a new milestone
must answer is whether it carries two facts that would state DIFFERENT
prerequisites if separated.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* A fourth fused variant, found by census rather than by report

loyal-lark-254 pointed out that a review reports one instance because it found
one instance -- a property of the reviewer's attention, never a census -- and
that the standing obligation this file had just written down should be RUN over
every variant rather than applied at the reported site.

Running it found NamespaceTerminalEndState fusing Steps 1-5 into one "terminal
end state". The namespace plan marks Step 5, the grammar and parse deletion, as
LAST, and gives the reason: deleting the grammar first makes every unrepaired
module unparseable at once, converting a fix-forward program into a flag day. So
the fused variant erased its own ordering constraint, and the constraint it
erased is the one that keeps the program survivable.

Split into NamespaceFixForwardComplete (Steps 2-4) and NamespaceGrammarRetired
(Step 5, downstream of it). Seed retirement is now downstream of the grammar
deletion rather than of a composite.

Four instances of one shape in one file, and only the last was found by census.
The first three were each reported by someone who had run into them. That is the
difference between a repair and a wall: repairing reported sites converges on
reviewer attention, enumerating the shape converges on the corpus.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* The missing milestone: Step 0.5, and the limit it exposes in this construction

snappy-dove-250 measured what crisp-crab-430 is actually building rather than
reading its session title, and it is a PRE-DELETION BASELINE INSTRUMENT: a
content-addressed, past-tense record of what the legacy resolver actually
selected over one exact base. It must precede Step 1, because once the cut lands
that record is unrecoverable.

That is the strongest kind of ordering constraint there is -- violating it
destroys evidence rather than merely reordering work -- and it was not in this
carrier at all. The graph therefore showed an active, ungated session as blocked
on prerequisites its work does not have.

The four earlier findings in this file were FUSIONS, and a census over the
declared variants found the last of them. This one is an OMISSION and no such
census could have found it. Exhaustiveness forces prerequisites to be stated for
every milestone declared; it cannot force a milestone to be declared. So the
match makes an unstated prerequisite unwritable and leaves an unstated MILESTONE
invisible -- totality protecting the enumeration and not its completeness, one
level up from the rule this file already records.

The annotation states plainly that finding a missing variant requires joining
this file against the programs it claims to describe, that no mechanism performs
that join today, and that the annotation is not one.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Hoist eight in-body annotations to module-item grain

Both lanes failed on ONE cause. The floor lane reported it as `FAILED PHASE
parse (8 error(s))` against the two plan carriers; the build lane reported it as
`v2-emission EmissionRefused ... produced 8 hard diagnostic(s)` against
src/v2/compiler/00_compile.dag. They are the same eight §4c violations, addressed
by line in one and by byte offset in the other.

The annotations sat inside `data ... = [ ... ]` list literals, labelling groups of
decl_ref rows. §4c admits only standalone leading `//` blocks attached to
module-scope declarations, so an annotation inside a declaration body refuses.
Each group label is hoisted into the leading block above its declaration, which
keeps the grouping legible without inventing a grain the realization does not
model.

The build lane's attribution is worth knowing before anyone chases it: an
annotation defect in dag/gunbc/plans/ surfaces as an emission refusal naming the
v2 compiler entry, because that entry's census sweeps the corpus. The named
subject is the entry, not the offending file; the offending file appears only in
the diagnostic payload.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* The irreversible step was gated on strictly weaker conditions than its own plan

review 56390 joined this carrier against the self-host plan and found that
SelfHostSeedRetirement depended on NamespaceGrammarRetired ALONE. The plan
requires two further conditions before S6: that the emitted Rust compiles, and
that behavioral equivalence to the seed is re-established. Neither existed as a
milestone, so the authoritative carrier permitted the one irreversible step in
either program on weaker conditions than the plan it claims to sequence.

Added as two milestones, not one, on the plan's own distinction: a rustc-clean
corpus permits S6 to be PLANNED, it does not AUTHORIZE it. Compiling is a
property of the emitted text; equivalence is a property of what that text does.
Fusing them would have been this file's characteristic defect committed while
repairing its mirror image.

This is the sixth defect of the same family and the second OMISSION. It is also
the first one found by the join the file's own annotation says nothing performs
-- a reviewer performed it. That is evidence for the stated limit rather than
against it: no census of this file could have surfaced this, because there was no
variant to enumerate.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Emitter capability is a milestone: installing the emitter's output would delete the CLI

emit_main_rs produces 552 lines against the committed 1318. Absent from the
emitted form: the whole Ci subcommand, Converge, Serve, and --entry on compile.
Measured by execution 2026-08-21 and accepted then as a program-level correction.
No number of regenerations closes it.

It is a distinct milestone because it is invisible to both milestones beside it.
It never appears in a rustc error count, so SelfHostCorpusEmitsCleanly can be
fully satisfied while it stands -- errors-to-zero is necessary and not sufficient
-- and it is not a behavioral difference between two producers, so equivalence
does not reach it either. It is the absence of a producer, and neither of the
other two can express that.

Its executable home already exists: EmitterProducedDivergentRegistration in
v2.compiler.self_host.stage0_crate_layout, enforced in three directions so a row
cannot outlive its producer. The milestone is that no such row remains.

This is the seventh defect of one family in this file and the third omission, and
it indicts the method rather than extending the list: it was not discovered. It
was already known, recorded, and accepted as a correction to this very program a
week before this carrier was authored, and the carrier was still written without
it. The join that finds omissions is not merely unmechanized -- it is not
reliably performed even by someone holding the fact. None of the three omissions
was found by reading this file.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

---------

Co-authored-by: Brian Searls <bts53@scarletmail.rutgers.edu>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Brian Searls <briansearls1@gmail.com>
briansrls pushed a commit that referenced this pull request Aug 27, 2026
…inding deltas before a namespace change merges (#9365)

* Anchor the v2-corpus self-host program in a .dag plan bound to the CI ratchet by symbol

Opened by operator ruling 2026-08-26: v2 self-hosts the ENTIRE v2 corpus, started
from scratch, superseding the 2026-08-16 root-partition document whose evidence
base was bankrupted (all ten probe links dangling, census a month stale, its
instrument deleted).

The plan is a .dag Plan carrier rather than a hand-authored .md so that its claims
are joined to symbols a machine checks: v2_corpus_self_host_ratchet_bindings names
the ratchet, the measurement instrument, the hosting admission and the emission
phase as DeclarationRefs, which the ingestion-time citation wall resolves on every
required run. A section that goes stale because its mechanism was renamed refuses
here instead of reading as current -- the failure mode that killed the last anchor.

Records two findings the program depends on: the required v2-emission phase never
invokes cargo ("stopping before cargo"), so no required check measures rustc; and
the whole-corpus compile IS hostable on a CI runner, correcting a report that no
host could run it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Drop the hand-authored plan markdown: the .dag carrier is the authority

The plan landed with both a .dag Plan carrier and a hand-authored docs/plans .md.
That is a second representation of one fact with no authority over it -- the §2/§3
parallel-representation debt -- and it would drift from the carrier silently, since
nothing joins them.

Evidence the .md is not required: gunbc.plans.branch_merge_admission_model is a
registered plan with no docs/plans markdown at all. The Plan type already carries
plan_to_document, so the markdown is DERIVED where it is wanted rather than
authored beside the source it restates.

Operator steer 2026-08-26: design doc changes are .dag changes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Plan carrier for the import/namespace program

Second anchor requested by the operator alongside the v2-corpus-self-host
plan. Material supplied by the owning session (snappy-dove-250) on request.

Bound to two symbols only -- gunbc.namespace_cut_landing_order
current_landing_order and namespace_cut_grammar_last_ruling -- both
verified to resolve before authoring. Everything else is marked as prose
in the text rather than given a citation it cannot support. A long
half-bound roster would assert that the ingestion-time citation wall is
checking claims it is not checking.

Three things the plan deliberately does not smooth over:

- The strip measurement is STALE AS A POPULATION and current only as a
  CLASS TAXONOMY. The corpus sha256 is the anchor, not the commit line.
- smart-wolf-868's placement at Step 2 is ASSUMED, not measured, and is
  labelled so where it appears.
- Whether the namespace cut blocks v2 self-compile or the reverse is an
  OPEN QUESTION carried to the operator, not a position taken here. It
  changes wave ordering in both plans.

Ordering claims bind to the carrier, never to a document sentence: the
execution document is superseded on ORDER only (operator, 2026-08-25),
which is why grammar deletion lands LAST rather than first.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Plan corrections from two independent audits

Four fixes, all from review rather than from me.

1. S1 asserted #9346 was "still OPEN with conflicts ... contrary to a
   report that both had merged". #9346 is MERGED (2026-08-26T19:06:10Z,
   7fcdbdc, verified an ancestor of main). The line did not merely
   carry a stale fact -- it instructed the reader to distrust an accurate
   source, in an ACTIVE anchor. Fixed by DELETING the assertion rather
   than updating it, and recording the rule: a plan carrier must not
   assert the open/closed state of a PR. It rots in hours, it is free to
   re-derive at read time, and nothing refuses when it goes stale. This
   is the one class the evidence-bankruptcy rule could not have caught,
   since it is not a measurement at all.

2. The seed partition table is a TRANSCRIPTION with no entry point.
   An independent re-run of the described procedure on the same commit
   reproduced every figure exactly except emitted lines: 166,834 vs
   166,727, the total carrying the same delta. No conclusion turns on
   107 lines; the finding is that a described procedure and an
   instrument are different things, which is what name-the-instrument
   predicts. Named as the gap it is.

3. The superseded census's CONCENTRATION is restated as a hypothesis
   with a test attached. Its two halves do not decay alike: the
   magnitude is inert without a board, but the concentration is a claim
   about the emitter's failure distribution and the emitter has been
   changed for a month by lanes whose purpose is moving it. A magnitude
   drifts; a concentration can invert, and sequencing by a stale one
   puts effort where the wins are already taken.

4. Import/namespace section 5 no longer claims the eleven classes "are
   still the right partition". Nothing has tested that. The taxonomy is
   what survives; its COMPLETENESS is unverified, since a class of
   breakage introduced since the measurement would not appear in it.
   Staleness is now stated as MEASURED -- the anchor recipe re-run gives
   a different corpus hash on a tree behind main.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* S1: record the receipt for delete-rather-than-correct

The rule against asserting PR state in a carrier was filed against #9346,
which had merely gone stale. A stronger receipt arrived the same night on
#9349: three readings within minutes -- dashboard reporting failing from a
superseded run, a peer re-deriving green at check-run level, and a third
check finding the head had moved again and the PR was mid-run. Each was
correct when taken; none described the PR when quoted.

That is the case #9346 could not make. There a correct measurement never
existed; here there was a correct measurement at BOTH ends and the shared
conclusion was still wrong. The mechanism is that a PR-state sentence has
no spelling for AS OF WHICH HEAD, so a true reading and a stale one become
indistinguishable the moment either is passed on -- which is precisely what
CORRECTING the line would have reproduced, and why it was deleted.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Carry the cross-program ruling once, in a typed interlock

Operator ruling 2026-08-26 answered the sequencing question both plans had
open, and answered it at a different grain than it was asked: neither
program blocks the other whole. Self-host's proof envelope blocks the FIRST
namespace semantic wave; namespace completion blocks self-host's
IRREVERSIBLE retirement step. A braid, not a total order -- and collapsing
it back to a program order yields a different plan in either direction.

The ruling closed with an explicit instruction to carry the precedence
edges ONCE and not duplicate them as prose in both carriers, which is §3
applied to a fact with two natural homes: two copies are one fact with two
authorities, and they diverge on the first amendment. So
gunbc.compiler_frontend_program_interlock owns the relation and both plans
cite it; their prose renders it.

milestone_prerequisites is a TOTAL FUNCTION over a closed milestone
variant, not a list of edges. A list is satisfied by omission -- a
milestone nobody wrote an edge for silently has no prerequisites and the
failure is invisible. The exhaustive match makes an unstated prerequisite
fail to compile (§5, construction over validation). Same shape for the
admission predicate, which admits on UNADJUDICATED delta being empty
rather than delta being empty: expected cut motion may occur, unevaluated
motion may not. A wall demanding zero delta would refuse the cut itself and
then be repaired by weakening it.

Executable consequence recorded in the namespace plan: its disclosed "no CI
mechanism" gap becomes a BLOCKER gating Step 1 by name, with preparatory
work explicitly unaffected. Its section 7 stops being an open question and
becomes a projection of the carrier.

Two corrections from the operator's exact-head review:

- The ratchet clause said counts are "display only and decide nothing".
  The ratchet owner measured that as literally false. Replaced with their
  wording: no cardinality is a gate oracle, but emptiness decides whether a
  population is inhabited or evaluated -- including the distinction between
  an empty roster and an identified roster with no failures -- and the
  roster DIGEST, not its count, is its identity.
- The status block claimed "no transcribed instrument output" while the
  next section explicitly carries a transcription and names its missing
  producer. It no longer claims both states.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Remove invalid \' escapes from the import/namespace plan

The build lane's parse phase refused:

  module index refused: 1 unparseable .dag source(s)
    dag/gunbc/plans/import_namespace_program.dag:8636-9127:
    expected expression, found Unknown

My error, and it is an escaping-layer mistake rather than a .dag one. I
authored the section through a Python here-doc and wrote \\' inside a
triple-quoted Python string to protect the apostrophe from PYTHON. Python
emitted a literal \' into the .dag file, where a double-quoted string needs
no escape for an apostrophe and \' is not a valid escape -- so the lexer
produced Unknown and the parser refused at the enclosing expression.

Four occurrences across three lines, all in the one file the index named;
the other two new modules parsed clean, which is why the refusal counted
exactly one source.

Worth noting the wall worked as designed: this was caught by the parse
sweep in the build lane, at the phase DESIGN records as sweeping src/v1,
dag and src/v2 from one roster, before anything downstream consumed it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Review 56363: delete the nickname predicate, de-duplicate the prose

Two findings, and the first splits rather than landing whole.

FINDING 1 -- predicate dissolution. The rule is real and I verified its
scope before acting: std.execution_mode records that the 2026-07-12
dissolution deleted SINGLE-VARIANT NICKNAMES (is_hermetic/is_record), and
that a predicate deciding a SEMANTIC PARTITION survives it --
execution_mode_is_wet_dispatch groups three variants into two because Wet
and Record share dispatch semantics, keeping one authority instead of an
inline match at every consumer.

  namespace_change_admitted_before_wall: two variants mapped one-to-one
  onto true/false. That is a nickname for a variant test. DELETED. Its
  distinction already lives in NamespaceChangeClass, which consumers match
  on, and the plan's citation is repointed to the type.

  delta_disposition_auto_admitted: nine dispositions partitioned three-to-
  six on whether the wall auto-admits them. That is the surviving shape,
  on the grounds std.execution_mode records by name. RETAINED, with the
  argument written beside it so the next reader does not re-litigate it.

FINDING 2 -- prose drift. Upheld. Section 7 enumerated both precedence
edges while asserting the carrier was their only home, which is worse than
either alone: a symbol citation verifies a declaration EXISTS and never
that prose about it still AGREES with it, so enumerated edges beside a
citation are precisely the drift single authority prevents. The prose now
renders the relation without restating it, says explicitly that it is not
authority for the edges, and points at milestone_prerequisites for the
gate condition instead of repeating it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Operator exact-head checks: S2 becomes its own milestone; gap count corrected

Two narrow semantic checks raised on 620a118.

1. The ruling gates the first namespace wave on S2 + S3 + S4. The closed
   milestone SelfHostCargoRatchetEnrolled named S3 and S4 and left the S2
   whole-corpus census implicit inside the phrase "proof envelope".

   That is a real gap rather than a naming preference, and the reason is
   worth stating because it is a limit of the construction this carrier
   leans on: the closed variant makes an omitted MILESTONE fail to compile,
   but it cannot make an omitted FACT fail to compile when that fact hides
   inside a composite name. Totality protects the enumeration, never the
   contents of an element of it. So a required precondition had become
   unenforceable in the very carrier built to enforce preconditions.

   Fixed by adding SelfHostWholeCorpusPopulationDerived as its own variant
   rather than by renaming the composite, since renaming would have left
   the fact implicit and merely better labelled. NamespaceFirstSemanticWave
   now requires all three.

   The general rule is recorded beside it: when a construction derives its
   guarantee from exhaustiveness, every fact the guarantee must cover has
   to be its own element -- a composite element is a place for a fact to
   hide from the check that makes the construction worth having.

2. Section 9 announced the ordering relation as retired and then closed by
   counting "Four gaps". Now three live gaps plus one retired question,
   with the retired bullet kept only so a reader of an earlier revision
   does not hunt for an answered question.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Review 56367: delete the Bool projection — it had no consumer

Deleted delta_disposition_auto_admitted, and the reason is independent of
the question it was reviewed under.

THE REVIEW'S STATED GROUND DOES NOT HOLD. The finding cites "the exact
predicate/walker-dissolution shape prohibited by DESIGN.md". DESIGN.md
contains zero occurrences of "walker", and its only predicate clauses say
that a general fn(T) -> Bool refinement does not lift to proof and that a
caller-supplied validator is defeasible -- both claims about the guarantee
ladder, neither a prohibition on Bool projections. The predicate-dissolution
rule is real but lives in the corpus, at std.execution_mode, and that row
states the surviving case explicitly: a two-variant semantic partition is
kept where a single-variant nickname is deleted, because deciding a
partition once keeps one authority instead of an inline match at every
consumer.

DELETED ANYWAY, ON A GROUND THAT DOES HOLD: it had no consumer. Measured --
the only reference in the tree was a DeclarationRef in this PR's own plan.
The wave-admission wall that would classify deltas does not exist yet, and
DESIGN section 6 names a new artifact with no final consumer as
experimental residue. A partition nobody computes over is a guess about
what a future consumer will want, and the surviving-partition argument
presupposes consumers that would otherwise inline the match. There are
none, so the argument does not apply to this predicate either.

The operator's ruled partition is preserved as an annotation, where it
cannot be mistaken for an executing mechanism, and the plan's citation is
repointed to NamespaceDeltaDisposition. The type stays: it carries the
ruled vocabulary and the wall will match on it directly. Bool is dropped
from the imports.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Split the fused S3+S4 milestone: two prerequisite sets are two elements

review 56376 found that SelfHostCargoRatchetEnrolled carried no prerequisite
while its own label named S4, and the plan defines S4 as enrolment against S2's
population. The typed interlock therefore permitted enrolling the ratchet before
the population it ratchets against exists.

The review offered two repairs. Adding S2 as a prerequisite to the fused variant
is the wrong one: S3 (enrol a cargo-executing phase) genuinely has no
prerequisite, so that repair closes the permissive half by introducing a
false-blocking half. The variant is composite, and its two halves have different
prerequisites, so a single prerequisite list must state either the minimum or the
maximum and both are wrong. The repair is the split.

This file's own annotation already stated the rule -- a composite element is a
place for a fact to hide from the exhaustiveness check that makes the
construction worth having -- and this instance was left standing in the same
diff that wrote it down. The annotation now carries the second instance, since a
rule with one instance reads as a repair and a rule with two reads as a rule.

Prerequisites are direct edges rather than the transitive closure: S2 is not
repeated on NamespaceFirstSemanticWave because S4 now carries it, so a later
correction to S4 cannot leave a stale duplicate standing (DESIGN section 2).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Split ratchet enrolment into observation and gate: a third instance of one shape

loyal-lark-254 found that SelfHostRatchetEnrolled was itself composite. It fused
enrolling the ratchet as an OBSERVATION -- taken, persisted, never able to fail a
merge -- with enrolling it as a GATE. Their prerequisites differ: an observation
needs no population to be about, since what it refuses is the inability to take
or persist it; a gate is meaningless without the identity-grain population it
gates against.

Fused, the variant read as a prerequisite over both. That would have blocked
observation work an operator ruling had already authorised, via a carrier that
landed after the ruling -- a single-authority collision committed by the file
built to prevent them.

NamespaceFirstSemanticWave now depends on the GATE form, since what the namespace
plan says gates Step 1 is an enforcing mechanism over the import population, and
an observation cannot enforce.

Three instances of one shape in one file is the finding, not three repairs. Each
was a variant fusing two facts whose prerequisites differ, and each was invisible
to the exhaustiveness check that is this construction's whole reason for
existing. The annotation now carries the standing obligation that follows: the
match already forces prerequisites to be stated, so the question a new milestone
must answer is whether it carries two facts that would state DIFFERENT
prerequisites if separated.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* A fourth fused variant, found by census rather than by report

loyal-lark-254 pointed out that a review reports one instance because it found
one instance -- a property of the reviewer's attention, never a census -- and
that the standing obligation this file had just written down should be RUN over
every variant rather than applied at the reported site.

Running it found NamespaceTerminalEndState fusing Steps 1-5 into one "terminal
end state". The namespace plan marks Step 5, the grammar and parse deletion, as
LAST, and gives the reason: deleting the grammar first makes every unrepaired
module unparseable at once, converting a fix-forward program into a flag day. So
the fused variant erased its own ordering constraint, and the constraint it
erased is the one that keeps the program survivable.

Split into NamespaceFixForwardComplete (Steps 2-4) and NamespaceGrammarRetired
(Step 5, downstream of it). Seed retirement is now downstream of the grammar
deletion rather than of a composite.

Four instances of one shape in one file, and only the last was found by census.
The first three were each reported by someone who had run into them. That is the
difference between a repair and a wall: repairing reported sites converges on
reviewer attention, enumerating the shape converges on the corpus.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* The missing milestone: Step 0.5, and the limit it exposes in this construction

snappy-dove-250 measured what crisp-crab-430 is actually building rather than
reading its session title, and it is a PRE-DELETION BASELINE INSTRUMENT: a
content-addressed, past-tense record of what the legacy resolver actually
selected over one exact base. It must precede Step 1, because once the cut lands
that record is unrecoverable.

That is the strongest kind of ordering constraint there is -- violating it
destroys evidence rather than merely reordering work -- and it was not in this
carrier at all. The graph therefore showed an active, ungated session as blocked
on prerequisites its work does not have.

The four earlier findings in this file were FUSIONS, and a census over the
declared variants found the last of them. This one is an OMISSION and no such
census could have found it. Exhaustiveness forces prerequisites to be stated for
every milestone declared; it cannot force a milestone to be declared. So the
match makes an unstated prerequisite unwritable and leaves an unstated MILESTONE
invisible -- totality protecting the enumeration and not its completeness, one
level up from the rule this file already records.

The annotation states plainly that finding a missing variant requires joining
this file against the programs it claims to describe, that no mechanism performs
that join today, and that the annotation is not one.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Hoist eight in-body annotations to module-item grain

Both lanes failed on ONE cause. The floor lane reported it as `FAILED PHASE
parse (8 error(s))` against the two plan carriers; the build lane reported it as
`v2-emission EmissionRefused ... produced 8 hard diagnostic(s)` against
src/v2/compiler/00_compile.dag. They are the same eight §4c violations, addressed
by line in one and by byte offset in the other.

The annotations sat inside `data ... = [ ... ]` list literals, labelling groups of
decl_ref rows. §4c admits only standalone leading `//` blocks attached to
module-scope declarations, so an annotation inside a declaration body refuses.
Each group label is hoisted into the leading block above its declaration, which
keeps the grouping legible without inventing a grain the realization does not
model.

The build lane's attribution is worth knowing before anyone chases it: an
annotation defect in dag/gunbc/plans/ surfaces as an emission refusal naming the
v2 compiler entry, because that entry's census sweeps the corpus. The named
subject is the entry, not the offending file; the offending file appears only in
the diagnostic payload.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* The irreversible step was gated on strictly weaker conditions than its own plan

review 56390 joined this carrier against the self-host plan and found that
SelfHostSeedRetirement depended on NamespaceGrammarRetired ALONE. The plan
requires two further conditions before S6: that the emitted Rust compiles, and
that behavioral equivalence to the seed is re-established. Neither existed as a
milestone, so the authoritative carrier permitted the one irreversible step in
either program on weaker conditions than the plan it claims to sequence.

Added as two milestones, not one, on the plan's own distinction: a rustc-clean
corpus permits S6 to be PLANNED, it does not AUTHORIZE it. Compiling is a
property of the emitted text; equivalence is a property of what that text does.
Fusing them would have been this file's characteristic defect committed while
repairing its mirror image.

This is the sixth defect of the same family and the second OMISSION. It is also
the first one found by the join the file's own annotation says nothing performs
-- a reviewer performed it. That is evidence for the stated limit rather than
against it: no census of this file could have surfaced this, because there was no
variant to enumerate.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* The wave-admission wall: adjudicate closure, subject-membership and binding deltas before a namespace change merges

gunbc.plans.import_namespace_program section 9 records that no CI mechanism
enforces any of it, and the 2026-08-26 ruling at
gunbc.compiler_frontend_program_interlock makes that a BLOCKER gating
NamespaceFirstSemanticWave on NamespaceWaveAdmissionEnrolled by name. This is
that milestone: a required namespace-wave-admission phase in
claim_executor --required-ci, witnesses lane, riding the parse sweep that
already runs.

The base index is the head index with the diff applied in reverse at file
grain, so only changed files are parsed twice while closure and bindings are
recomputed over both whole graphs. The change class is DERIVED from the
measured delta rather than declared by an author. The wall admits when the
UNADJUDICATED delta is empty, never when the delta is empty.

Closure is a pure function of membership, so an arm for "closure moved and
membership did not" would be permanently green by construction. It is measured
and attributed to its generators instead -- each delta names its blast radius.

The grain is authored containment identity (module, enclosing declaration,
LEAF segment), because v2.workflow.legacy_binding_delta establishes that no
admissible cross-compile occurrence key exists without a transformation to emit
one, and there is none between a merge base and a head. Row values are candidate
SETS, so shadowing widens a set rather than picking a winner. The leaf rather
than the whole spelling is a fixture finding: keyed on spellings, requalifying a
reference reads as NewUnresolvedness, and requalification is the namespace
program's own core motion.

The binding channel reads every authored name occurrence from the parse tree
rather than import members, so it does not go blind on the cut it gates.

Evidence: 14 fixture-boundary arms in tests/namespace_wave_admission.rs, every
refusing arm one mutation of the auto-admitted control, plus a two-directional
vocabulary join between the host enum and the .dag coproduct it realizes, whose
absent-authority arm refuses.

The admission roster is empty, which is the correct landing state; the coarse
class-admission carrier is deliberately not built, and the constraint on its
shape -- bounded by enumerated identity, never by predicate -- is recorded in
gunbc.namespace_wave_admission.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Emitter capability is a milestone: installing the emitter's output would delete the CLI

emit_main_rs produces 552 lines against the committed 1318. Absent from the
emitted form: the whole Ci subcommand, Converge, Serve, and --entry on compile.
Measured by execution 2026-08-21 and accepted then as a program-level correction.
No number of regenerations closes it.

It is a distinct milestone because it is invisible to both milestones beside it.
It never appears in a rustc error count, so SelfHostCorpusEmitsCleanly can be
fully satisfied while it stands -- errors-to-zero is necessary and not sufficient
-- and it is not a behavioral difference between two producers, so equivalence
does not reach it either. It is the absence of a producer, and neither of the
other two can express that.

Its executable home already exists: EmitterProducedDivergentRegistration in
v2.compiler.self_host.stage0_crate_layout, enforced in three directions so a row
cannot outlive its producer. The milestone is that no such row remains.

This is the seventh defect of one family in this file and the third omission, and
it indicts the method rather than extending the list: it was not discovered. It
was already known, recorded, and accepted as a correction to this very program a
week before this carrier was authored, and the carrier was still written without
it. The join that finds omissions is not merely unmechanized -- it is not
reliably performed even by someone holding the fact. None of the three omissions
was found by reading this file.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* The stall row owed its next-rung trigger: GuaranteeStall carries six fields and this one carried five

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* The occurrence-grain ceiling belongs in the carrier, not only in a PR body: a body is not an authority

Records what the milestone delivers -- two adjudicated walls, a measured
closure blast radius attributed to its generators, and one declared stall --
so a reader of NamespaceWaveAdmissionEnrolled cannot take it for a third wall
over closure or for occurrence grain.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* The leaf key is an invariant of the cut, not a fixture accident — and the class admission arrives one grain down

Three facts measured against the carriers by the owning program's session
rather than against intent (snappy-dove-250, 2026-08-26):

A requalification wave prepends the declarer's path and leaves the declarer
fixed, so it changes the authored spelling and leaves the last segment
invariant BY CONSTRUCTION. This wall's key is therefore invariant under
exactly the operation the cut performs, and the reduction has a named
authority already: v1.05_emit_rust rust_fn_sig_leaf_name_dotted_note names
qualified_last_segment. Recorded as an invariant rather than as a finding,
because a finding invites re-litigation.

TargetChanged firing on a symbol move is signal, not tax: the owning program
splits requalification and relocation into separate diffs, so that refusal
reports a mis-shaped wave. No exemption, threshold or allowance is admitted.

LegacyBindingObservationRow carries only an occurrence identity and an
outcome, so a class admission must project down to this wall's key -- through
an authored_name that carries dots and reduces only through
qualified_last_segment, a trap that fails silently because on an unqualified
reference the spelling and the leaf are identical.

The grain note also said 'spelling' where the implementation keys on the
leaf; that is corrected here rather than left to drift.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Pay for the hand Rust this wall adds: delete a fork, delete a duplicate, and argue the residue per declaration

The operator ruled that a request to add hand Rust is the occasion to migrate or
delete hand Rust. This change answers at DECLARATION grain rather than as a count,
and it does not buy the count down by shrinking the wall.

DELETED, measured rather than argued:

- `leaf_of` was a NICKNAME for `v1.00_core` `qualified_last_segment`, which
  `v1.05_emit_rust` `rust_fn_sig_leaf_name_dotted_note` names as the single
  authority for taking an authored spelling to its last segment. The wall now
  calls that mirror. This is the stronger construction as well as the smaller
  one: the reduction the wall keys its rows on is now the corpus authority
  instead of a local respelling of it.
- `render_set`, inlined at its two call sites.
- `claim_executor` carried a BYTE-IDENTICAL PRIVATE COPY of `git_stdout`. The
  wall needed the same helper, so rather than land a third spelling the lib owns
  the one copy and the bin's is deleted. Net minus one PRE-EXISTING hand
  declaration.

Four inherent methods became free functions, because `std.decl_ref` offers only
`WholeDeclaration` and `NamedField` -- a method on an impl block is UNCITABLE, so
as methods they were items the seed-growth roster structurally could not
enumerate. The module now carries no impl block.

The roster went 25 -> 33 rows, which is the honest direction: it was JOINED
against the module's actual declaration population instead of listed from
memory, and six declarations were missing from the first draft. `gunbc.seed_growth`
already warns that `hand_authored_declarations` is an authored obligation roster
rather than a derived denominator; this is that warning firing on its own first use.

The residue is argued per class, not asserted as irreducible. Class A (28
declarations) is a pure fold whose INPUT TYPE is host-only: `ModuleDeclarationRecord`
and `DeclarationIndex` have no `.dag` carrier, and authoring one here would be the
second representation `gunbc.declaration_index_seed_growth` already owns -- so this
roster follows that carrier's first step rather than forking it. Class B (4
declarations) is blocked on a typed repository-read transport, which is the scm
lane's subject.

Verified: `cargo check -p v1-compiler --bin claim_executor` clean, 14/14 fixture
arms pass, `cargo fmt --all --check` clean.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Drop the import the git_stdout deduplication left unused

`claim_executor` imported `std::path::Path` for its own copy of `git_stdout`, which
the previous commit deleted in favour of the lib's. Bare `Path` was then reachable
only from one `#[cfg(test)]` site, and the build lane runs with `-D warnings`, so
`unused_imports` is an ERROR there and both lanes refused.

The import is narrowed to `PathBuf` and the single test site spells the type in full,
matching the ten other `std::path::Path` uses already in the file.

WHY MY OWN CHECK DID NOT SEE IT, recorded because the check was not wrong, it
answered a different question: I verified with `cargo check -p v1-compiler --bin
claim_executor` and no RUSTFLAGS. The gate runs `cargo build --release -p v1-compiler
--bins` with `-D warnings` -- more targets AND warnings promoted -- so a green check
under weaker flags is not evidence about the gate. Any DELETION of host Rust can
strand an import, so the deletion half of the operator's directive is exactly where
this class fires.

Verified: RUSTFLAGS="-D warnings" cargo check -p v1-compiler --bins, fmt clean.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Say what git_stdout actually trims, and why the asymmetry is load-bearing

Review 56411 (non-blocking) noticed that folding the two copies together left the
function on `trim_end` where the private copy used `trim`. The behaviour is right;
the doc comment above it still said "trimmed stdout", which is the sentence a future
caller reads before choosing this helper.

The asymmetry is deliberate and now says so: one caller asks for the CONTENT OF A FILE
at a ref, and a `.dag` module whose first line is indented would arrive with that
indentation eaten -- a different file from the committed one, compared against a head
side read from disk intact.

Checked per caller rather than asserted: `rev-parse`, `merge-base` and
`diff --name-only` carry no leading whitespace; `status --porcelain` re-trims at both
of its use sites AND is the one worth noticing, because its lines BEGIN with the
two-column XY code -- a leading `trim` would have corrupted a status read rather than
tidied it. So the pre-existing caller is not merely unharmed by the change, it is
better served by it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* An unobservable baseline refuses instead of reading as empty

Both findings in review 56449 are confirmed by reading the code, and my own
doc comment on `base_records` carried the erroneous rationale verbatim -- "that
is the conservative direction: it can only make the wall quieter" -- which is
exactly the empty-observation narrow DESIGN names: bottom-as-answer conflated
with bottom-as-ignorance, strictly worse than the widen section 5 forbids,
because a widen is merely expensive and a narrow is silently uncovered.

Two fixes, one per finding:

`base_records` returns `Result<Vec<ModuleDeclarationRecord>, String>` and
refuses when the base-side parse produced any diagnostic. A source that does
not parse at the base revision has no readable declarations; it does not have
zero of them. Reading it as empty made every declaration in the head revision
look new, so the wall adjudicated a baseline it had never observed.

The base-side loop establishes absence from `git ls-tree -r --name-only <base>`
-- an authoritative listing of what the base revision contains -- rather than
inferring it from a `git show` failure. A path missing from that listing was
genuinely added by this change; a path present in it whose content cannot be
read, or whose content does not parse, now returns `NotEvaluated` with the
reason, so "could not compare" can never render as "nothing changed".

Mutation receipt, one mutation, restored between: baseline 15/15 green;
revert `base_records` to `Ok(Vec::new())` on the diagnostic arm; 14 passed,
1 failed, and the one red is
`a_base_side_source_that_does_not_parse_refuses_instead_of_reading_as_empty`
-- it fails alone. Restored, 15/15 green, `--bins` clean under `-D warnings`
with `forwarding env: RUSTFLAGS` confirmed on the dispatch. The new arm carries
its own positive control on the same function: a well-formed baseline still
reads a non-empty record set, so the arm cannot pass by refusing everything.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* Repair a line-wrap artifact inside the NOT RUN message

Review 56459 (non-blocking) found a 26-space run mid-string in the
namespace-wave-admission NOT RUN message. It was a line-wrap artifact rather
than deliberate spacing, and it reaches the operator's terminal verbatim, so
the one diagnostic a reader sees when the phase declines to adjudicate was
the least legible line the phase can print. Repaired with a `\` continuation
so the rendered text reads `did not produce an index`; the wording, the
`phase_failures` push and the fail-closed behaviour are untouched.

Checked with the build lane's own flags: `cargo check -p v1-compiler --bins`
under `-D warnings`, with `forwarding env: RUSTFLAGS` confirmed on the
dispatch, since a check weaker than the gate on either the target set or the
warning level carries no information about the gate.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* A rename has two sides and the diff names only one of them

Review 56471 is correct. `run_required_wave_admission` read
`git diff --name-only` as BOTH sides of the comparison, and rename detection
is on by default, so a detected rename is reported as its destination alone.
The source path therefore never entered the base-side re-read -- it is not in
the list -- and the destination is absent from the base tree, so the module's
entire baseline vanished: every declaration in it read as newly added, and a
required wall could refuse an ordinary `.dag` rename over a delta it had
invented. That is the same class as the two defects review 56449 found, one
level out: an observation that could not express what happened rendered as a
verdict about what happened.

`diff_sides` reads `git diff --name-status -z -M` and routes each entry to the
two sides SEPARATELY: a rename contributes its destination to the head-touched
set and its source to the base side, an addition contributes only a head path,
a deletion only a base path, and an ordinary modification the same path to
both. Scope is applied per side, because a rename can cross the sweep boundary
in either direction and the two sides must be measured by one instrument.

The parse is a pure function over the diff text, so the RED is authorable at
the fixture boundary and is authored there rather than argued in a comment.
Mutation receipt, one mutation, restored between: baseline 16/16 green; revert
the rename arm to push the destination onto both sides -- exactly the shape
`--name-only` forced on the old code -- and the result is 15 passed, 1 failed,
the single red being the rename arm. It fails alone, and the A/D/M controls
beside it stay green under that mutation, so the arm discriminates the one
distinction the review named rather than asserting the parse's shape.
Restored: 16/16 green, fmt clean, `--bins` clean under `-D warnings` with
`forwarding env: RUSTFLAGS` confirmed on the dispatch.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Brian Searls <bts53@scarletmail.rutgers.edu>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>
briansrls pushed a commit that referenced this pull request Aug 27, 2026
…nd report it — never a hand-ticked ledger, because a status carrier claiming DONE is the rung inflation DESIGN 4b names as worse than sitting low (#9388)

* Anchor the v2-corpus self-host program in a .dag plan bound to the CI ratchet by symbol

Opened by operator ruling 2026-08-26: v2 self-hosts the ENTIRE v2 corpus, started
from scratch, superseding the 2026-08-16 root-partition document whose evidence
base was bankrupted (all ten probe links dangling, census a month stale, its
instrument deleted).

The plan is a .dag Plan carrier rather than a hand-authored .md so that its claims
are joined to symbols a machine checks: v2_corpus_self_host_ratchet_bindings names
the ratchet, the measurement instrument, the hosting admission and the emission
phase as DeclarationRefs, which the ingestion-time citation wall resolves on every
required run. A section that goes stale because its mechanism was renamed refuses
here instead of reading as current -- the failure mode that killed the last anchor.

Records two findings the program depends on: the required v2-emission phase never
invokes cargo ("stopping before cargo"), so no required check measures rustc; and
the whole-corpus compile IS hostable on a CI runner, correcting a report that no
host could run it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Drop the hand-authored plan markdown: the .dag carrier is the authority

The plan landed with both a .dag Plan carrier and a hand-authored docs/plans .md.
That is a second representation of one fact with no authority over it -- the §2/§3
parallel-representation debt -- and it would drift from the carrier silently, since
nothing joins them.

Evidence the .md is not required: gunbc.plans.branch_merge_admission_model is a
registered plan with no docs/plans markdown at all. The Plan type already carries
plan_to_document, so the markdown is DERIVED where it is wanted rather than
authored beside the source it restates.

Operator steer 2026-08-26: design doc changes are .dag changes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Plan carrier for the import/namespace program

Second anchor requested by the operator alongside the v2-corpus-self-host
plan. Material supplied by the owning session (snappy-dove-250) on request.

Bound to two symbols only -- gunbc.namespace_cut_landing_order
current_landing_order and namespace_cut_grammar_last_ruling -- both
verified to resolve before authoring. Everything else is marked as prose
in the text rather than given a citation it cannot support. A long
half-bound roster would assert that the ingestion-time citation wall is
checking claims it is not checking.

Three things the plan deliberately does not smooth over:

- The strip measurement is STALE AS A POPULATION and current only as a
  CLASS TAXONOMY. The corpus sha256 is the anchor, not the commit line.
- smart-wolf-868's placement at Step 2 is ASSUMED, not measured, and is
  labelled so where it appears.
- Whether the namespace cut blocks v2 self-compile or the reverse is an
  OPEN QUESTION carried to the operator, not a position taken here. It
  changes wave ordering in both plans.

Ordering claims bind to the carrier, never to a document sentence: the
execution document is superseded on ORDER only (operator, 2026-08-25),
which is why grammar deletion lands LAST rather than first.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Plan corrections from two independent audits

Four fixes, all from review rather than from me.

1. S1 asserted #9346 was "still OPEN with conflicts ... contrary to a
   report that both had merged". #9346 is MERGED (2026-08-26T19:06:10Z,
   7fcdbdc, verified an ancestor of main). The line did not merely
   carry a stale fact -- it instructed the reader to distrust an accurate
   source, in an ACTIVE anchor. Fixed by DELETING the assertion rather
   than updating it, and recording the rule: a plan carrier must not
   assert the open/closed state of a PR. It rots in hours, it is free to
   re-derive at read time, and nothing refuses when it goes stale. This
   is the one class the evidence-bankruptcy rule could not have caught,
   since it is not a measurement at all.

2. The seed partition table is a TRANSCRIPTION with no entry point.
   An independent re-run of the described procedure on the same commit
   reproduced every figure exactly except emitted lines: 166,834 vs
   166,727, the total carrying the same delta. No conclusion turns on
   107 lines; the finding is that a described procedure and an
   instrument are different things, which is what name-the-instrument
   predicts. Named as the gap it is.

3. The superseded census's CONCENTRATION is restated as a hypothesis
   with a test attached. Its two halves do not decay alike: the
   magnitude is inert without a board, but the concentration is a claim
   about the emitter's failure distribution and the emitter has been
   changed for a month by lanes whose purpose is moving it. A magnitude
   drifts; a concentration can invert, and sequencing by a stale one
   puts effort where the wins are already taken.

4. Import/namespace section 5 no longer claims the eleven classes "are
   still the right partition". Nothing has tested that. The taxonomy is
   what survives; its COMPLETENESS is unverified, since a class of
   breakage introduced since the measurement would not appear in it.
   Staleness is now stated as MEASURED -- the anchor recipe re-run gives
   a different corpus hash on a tree behind main.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* S1: record the receipt for delete-rather-than-correct

The rule against asserting PR state in a carrier was filed against #9346,
which had merely gone stale. A stronger receipt arrived the same night on
#9349: three readings within minutes -- dashboard reporting failing from a
superseded run, a peer re-deriving green at check-run level, and a third
check finding the head had moved again and the PR was mid-run. Each was
correct when taken; none described the PR when quoted.

That is the case #9346 could not make. There a correct measurement never
existed; here there was a correct measurement at BOTH ends and the shared
conclusion was still wrong. The mechanism is that a PR-state sentence has
no spelling for AS OF WHICH HEAD, so a true reading and a stale one become
indistinguishable the moment either is passed on -- which is precisely what
CORRECTING the line would have reproduced, and why it was deleted.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Carry the cross-program ruling once, in a typed interlock

Operator ruling 2026-08-26 answered the sequencing question both plans had
open, and answered it at a different grain than it was asked: neither
program blocks the other whole. Self-host's proof envelope blocks the FIRST
namespace semantic wave; namespace completion blocks self-host's
IRREVERSIBLE retirement step. A braid, not a total order -- and collapsing
it back to a program order yields a different plan in either direction.

The ruling closed with an explicit instruction to carry the precedence
edges ONCE and not duplicate them as prose in both carriers, which is §3
applied to a fact with two natural homes: two copies are one fact with two
authorities, and they diverge on the first amendment. So
gunbc.compiler_frontend_program_interlock owns the relation and both plans
cite it; their prose renders it.

milestone_prerequisites is a TOTAL FUNCTION over a closed milestone
variant, not a list of edges. A list is satisfied by omission -- a
milestone nobody wrote an edge for silently has no prerequisites and the
failure is invisible. The exhaustive match makes an unstated prerequisite
fail to compile (§5, construction over validation). Same shape for the
admission predicate, which admits on UNADJUDICATED delta being empty
rather than delta being empty: expected cut motion may occur, unevaluated
motion may not. A wall demanding zero delta would refuse the cut itself and
then be repaired by weakening it.

Executable consequence recorded in the namespace plan: its disclosed "no CI
mechanism" gap becomes a BLOCKER gating Step 1 by name, with preparatory
work explicitly unaffected. Its section 7 stops being an open question and
becomes a projection of the carrier.

Two corrections from the operator's exact-head review:

- The ratchet clause said counts are "display only and decide nothing".
  The ratchet owner measured that as literally false. Replaced with their
  wording: no cardinality is a gate oracle, but emptiness decides whether a
  population is inhabited or evaluated -- including the distinction between
  an empty roster and an identified roster with no failures -- and the
  roster DIGEST, not its count, is its identity.
- The status block claimed "no transcribed instrument output" while the
  next section explicitly carries a transcription and names its missing
  producer. It no longer claims both states.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Remove invalid \' escapes from the import/namespace plan

The build lane's parse phase refused:

  module index refused: 1 unparseable .dag source(s)
    dag/gunbc/plans/import_namespace_program.dag:8636-9127:
    expected expression, found Unknown

My error, and it is an escaping-layer mistake rather than a .dag one. I
authored the section through a Python here-doc and wrote \\' inside a
triple-quoted Python string to protect the apostrophe from PYTHON. Python
emitted a literal \' into the .dag file, where a double-quoted string needs
no escape for an apostrophe and \' is not a valid escape -- so the lexer
produced Unknown and the parser refused at the enclosing expression.

Four occurrences across three lines, all in the one file the index named;
the other two new modules parsed clean, which is why the refusal counted
exactly one source.

Worth noting the wall worked as designed: this was caught by the parse
sweep in the build lane, at the phase DESIGN records as sweeping src/v1,
dag and src/v2 from one roster, before anything downstream consumed it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Review 56363: delete the nickname predicate, de-duplicate the prose

Two findings, and the first splits rather than landing whole.

FINDING 1 -- predicate dissolution. The rule is real and I verified its
scope before acting: std.execution_mode records that the 2026-07-12
dissolution deleted SINGLE-VARIANT NICKNAMES (is_hermetic/is_record), and
that a predicate deciding a SEMANTIC PARTITION survives it --
execution_mode_is_wet_dispatch groups three variants into two because Wet
and Record share dispatch semantics, keeping one authority instead of an
inline match at every consumer.

  namespace_change_admitted_before_wall: two variants mapped one-to-one
  onto true/false. That is a nickname for a variant test. DELETED. Its
  distinction already lives in NamespaceChangeClass, which consumers match
  on, and the plan's citation is repointed to the type.

  delta_disposition_auto_admitted: nine dispositions partitioned three-to-
  six on whether the wall auto-admits them. That is the surviving shape,
  on the grounds std.execution_mode records by name. RETAINED, with the
  argument written beside it so the next reader does not re-litigate it.

FINDING 2 -- prose drift. Upheld. Section 7 enumerated both precedence
edges while asserting the carrier was their only home, which is worse than
either alone: a symbol citation verifies a declaration EXISTS and never
that prose about it still AGREES with it, so enumerated edges beside a
citation are precisely the drift single authority prevents. The prose now
renders the relation without restating it, says explicitly that it is not
authority for the edges, and points at milestone_prerequisites for the
gate condition instead of repeating it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Operator exact-head checks: S2 becomes its own milestone; gap count corrected

Two narrow semantic checks raised on 620a118.

1. The ruling gates the first namespace wave on S2 + S3 + S4. The closed
   milestone SelfHostCargoRatchetEnrolled named S3 and S4 and left the S2
   whole-corpus census implicit inside the phrase "proof envelope".

   That is a real gap rather than a naming preference, and the reason is
   worth stating because it is a limit of the construction this carrier
   leans on: the closed variant makes an omitted MILESTONE fail to compile,
   but it cannot make an omitted FACT fail to compile when that fact hides
   inside a composite name. Totality protects the enumeration, never the
   contents of an element of it. So a required precondition had become
   unenforceable in the very carrier built to enforce preconditions.

   Fixed by adding SelfHostWholeCorpusPopulationDerived as its own variant
   rather than by renaming the composite, since renaming would have left
   the fact implicit and merely better labelled. NamespaceFirstSemanticWave
   now requires all three.

   The general rule is recorded beside it: when a construction derives its
   guarantee from exhaustiveness, every fact the guarantee must cover has
   to be its own element -- a composite element is a place for a fact to
   hide from the check that makes the construction worth having.

2. Section 9 announced the ordering relation as retired and then closed by
   counting "Four gaps". Now three live gaps plus one retired question,
   with the retired bullet kept only so a reader of an earlier revision
   does not hunt for an answered question.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Review 56367: delete the Bool projection — it had no consumer

Deleted delta_disposition_auto_admitted, and the reason is independent of
the question it was reviewed under.

THE REVIEW'S STATED GROUND DOES NOT HOLD. The finding cites "the exact
predicate/walker-dissolution shape prohibited by DESIGN.md". DESIGN.md
contains zero occurrences of "walker", and its only predicate clauses say
that a general fn(T) -> Bool refinement does not lift to proof and that a
caller-supplied validator is defeasible -- both claims about the guarantee
ladder, neither a prohibition on Bool projections. The predicate-dissolution
rule is real but lives in the corpus, at std.execution_mode, and that row
states the surviving case explicitly: a two-variant semantic partition is
kept where a single-variant nickname is deleted, because deciding a
partition once keeps one authority instead of an inline match at every
consumer.

DELETED ANYWAY, ON A GROUND THAT DOES HOLD: it had no consumer. Measured --
the only reference in the tree was a DeclarationRef in this PR's own plan.
The wave-admission wall that would classify deltas does not exist yet, and
DESIGN section 6 names a new artifact with no final consumer as
experimental residue. A partition nobody computes over is a guess about
what a future consumer will want, and the surviving-partition argument
presupposes consumers that would otherwise inline the match. There are
none, so the argument does not apply to this predicate either.

The operator's ruled partition is preserved as an annotation, where it
cannot be mistaken for an executing mechanism, and the plan's citation is
repointed to NamespaceDeltaDisposition. The type stays: it carries the
ruled vocabulary and the wall will match on it directly. Bool is dropped
from the imports.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Split the fused S3+S4 milestone: two prerequisite sets are two elements

review 56376 found that SelfHostCargoRatchetEnrolled carried no prerequisite
while its own label named S4, and the plan defines S4 as enrolment against S2's
population. The typed interlock therefore permitted enrolling the ratchet before
the population it ratchets against exists.

The review offered two repairs. Adding S2 as a prerequisite to the fused variant
is the wrong one: S3 (enrol a cargo-executing phase) genuinely has no
prerequisite, so that repair closes the permissive half by introducing a
false-blocking half. The variant is composite, and its two halves have different
prerequisites, so a single prerequisite list must state either the minimum or the
maximum and both are wrong. The repair is the split.

This file's own annotation already stated the rule -- a composite element is a
place for a fact to hide from the exhaustiveness check that makes the
construction worth having -- and this instance was left standing in the same
diff that wrote it down. The annotation now carries the second instance, since a
rule with one instance reads as a repair and a rule with two reads as a rule.

Prerequisites are direct edges rather than the transitive closure: S2 is not
repeated on NamespaceFirstSemanticWave because S4 now carries it, so a later
correction to S4 cannot leave a stale duplicate standing (DESIGN section 2).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Split ratchet enrolment into observation and gate: a third instance of one shape

loyal-lark-254 found that SelfHostRatchetEnrolled was itself composite. It fused
enrolling the ratchet as an OBSERVATION -- taken, persisted, never able to fail a
merge -- with enrolling it as a GATE. Their prerequisites differ: an observation
needs no population to be about, since what it refuses is the inability to take
or persist it; a gate is meaningless without the identity-grain population it
gates against.

Fused, the variant read as a prerequisite over both. That would have blocked
observation work an operator ruling had already authorised, via a carrier that
landed after the ruling -- a single-authority collision committed by the file
built to prevent them.

NamespaceFirstSemanticWave now depends on the GATE form, since what the namespace
plan says gates Step 1 is an enforcing mechanism over the import population, and
an observation cannot enforce.

Three instances of one shape in one file is the finding, not three repairs. Each
was a variant fusing two facts whose prerequisites differ, and each was invisible
to the exhaustiveness check that is this construction's whole reason for
existing. The annotation now carries the standing obligation that follows: the
match already forces prerequisites to be stated, so the question a new milestone
must answer is whether it carries two facts that would state DIFFERENT
prerequisites if separated.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* A fourth fused variant, found by census rather than by report

loyal-lark-254 pointed out that a review reports one instance because it found
one instance -- a property of the reviewer's attention, never a census -- and
that the standing obligation this file had just written down should be RUN over
every variant rather than applied at the reported site.

Running it found NamespaceTerminalEndState fusing Steps 1-5 into one "terminal
end state". The namespace plan marks Step 5, the grammar and parse deletion, as
LAST, and gives the reason: deleting the grammar first makes every unrepaired
module unparseable at once, converting a fix-forward program into a flag day. So
the fused variant erased its own ordering constraint, and the constraint it
erased is the one that keeps the program survivable.

Split into NamespaceFixForwardComplete (Steps 2-4) and NamespaceGrammarRetired
(Step 5, downstream of it). Seed retirement is now downstream of the grammar
deletion rather than of a composite.

Four instances of one shape in one file, and only the last was found by census.
The first three were each reported by someone who had run into them. That is the
difference between a repair and a wall: repairing reported sites converges on
reviewer attention, enumerating the shape converges on the corpus.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* The missing milestone: Step 0.5, and the limit it exposes in this construction

snappy-dove-250 measured what crisp-crab-430 is actually building rather than
reading its session title, and it is a PRE-DELETION BASELINE INSTRUMENT: a
content-addressed, past-tense record of what the legacy resolver actually
selected over one exact base. It must precede Step 1, because once the cut lands
that record is unrecoverable.

That is the strongest kind of ordering constraint there is -- violating it
destroys evidence rather than merely reordering work -- and it was not in this
carrier at all. The graph therefore showed an active, ungated session as blocked
on prerequisites its work does not have.

The four earlier findings in this file were FUSIONS, and a census over the
declared variants found the last of them. This one is an OMISSION and no such
census could have found it. Exhaustiveness forces prerequisites to be stated for
every milestone declared; it cannot force a milestone to be declared. So the
match makes an unstated prerequisite unwritable and leaves an unstated MILESTONE
invisible -- totality protecting the enumeration and not its completeness, one
level up from the rule this file already records.

The annotation states plainly that finding a missing variant requires joining
this file against the programs it claims to describe, that no mechanism performs
that join today, and that the annotation is not one.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Hoist eight in-body annotations to module-item grain

Both lanes failed on ONE cause. The floor lane reported it as `FAILED PHASE
parse (8 error(s))` against the two plan carriers; the build lane reported it as
`v2-emission EmissionRefused ... produced 8 hard diagnostic(s)` against
src/v2/compiler/00_compile.dag. They are the same eight §4c violations, addressed
by line in one and by byte offset in the other.

The annotations sat inside `data ... = [ ... ]` list literals, labelling groups of
decl_ref rows. §4c admits only standalone leading `//` blocks attached to
module-scope declarations, so an annotation inside a declaration body refuses.
Each group label is hoisted into the leading block above its declaration, which
keeps the grouping legible without inventing a grain the realization does not
model.

The build lane's attribution is worth knowing before anyone chases it: an
annotation defect in dag/gunbc/plans/ surfaces as an emission refusal naming the
v2 compiler entry, because that entry's census sweeps the corpus. The named
subject is the entry, not the offending file; the offending file appears only in
the diagnostic payload.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* The irreversible step was gated on strictly weaker conditions than its own plan

review 56390 joined this carrier against the self-host plan and found that
SelfHostSeedRetirement depended on NamespaceGrammarRetired ALONE. The plan
requires two further conditions before S6: that the emitted Rust compiles, and
that behavioral equivalence to the seed is re-established. Neither existed as a
milestone, so the authoritative carrier permitted the one irreversible step in
either program on weaker conditions than the plan it claims to sequence.

Added as two milestones, not one, on the plan's own distinction: a rustc-clean
corpus permits S6 to be PLANNED, it does not AUTHORIZE it. Compiling is a
property of the emitted text; equivalence is a property of what that text does.
Fusing them would have been this file's characteristic defect committed while
repairing its mirror image.

This is the sixth defect of the same family and the second OMISSION. It is also
the first one found by the join the file's own annotation says nothing performs
-- a reviewer performed it. That is evidence for the stated limit rather than
against it: no census of this file could have surfaced this, because there was no
variant to enumerate.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Emitter capability is a milestone: installing the emitter's output would delete the CLI

emit_main_rs produces 552 lines against the committed 1318. Absent from the
emitted form: the whole Ci subcommand, Converge, Serve, and --entry on compile.
Measured by execution 2026-08-21 and accepted then as a program-level correction.
No number of regenerations closes it.

It is a distinct milestone because it is invisible to both milestones beside it.
It never appears in a rustc error count, so SelfHostCorpusEmitsCleanly can be
fully satisfied while it stands -- errors-to-zero is necessary and not sufficient
-- and it is not a behavioral difference between two producers, so equivalence
does not reach it either. It is the absence of a producer, and neither of the
other two can express that.

Its executable home already exists: EmitterProducedDivergentRegistration in
v2.compiler.self_host.stage0_crate_layout, enforced in three directions so a row
cannot outlive its producer. The milestone is that no such row remains.

This is the seventh defect of one family in this file and the third omission, and
it indicts the method rather than extending the list: it was not discovered. It
was already known, recorded, and accepted as a correction to this very program a
week before this carrier was authored, and the carrier was still written without
it. The join that finds omissions is not merely unmechanized -- it is not
reliably performed even by someone holding the fact. None of the three omissions
was found by reading this file.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

* Derive milestone standing from populations the corpus carries, and report it — a milestone is never ticked

gunbc.compiler_frontend_program_status answers milestone_status(m) for every
ProgramMilestone the interlock declares. Two arms DERIVE a standing from a
population the corpus itself carries; eleven return NotDerivable naming the
exact missing instrument, which is the report nobody can currently obtain.

Clear has one route: a fold over a sole_constructor MilestoneEvidence minted
from an observed list. There is no spelling of a bare tick, and no arm consults
a merged pull request.

Also corrects NamespaceWaveAdmissionEnrolled's label, which asserted a wall over
a delta that is unauthorable and so could only ever be a decoration.

* Add the successor-promotion milestone: the graph authorized the irreversible step without ever requiring a v2-built compiler be admitted as a successor

The three conditions in front of S6 are all about the emitted TEXT. None asks
whether what that text becomes can go on producing compilers, and
admit_promotion -- built for exactly that -- was reachable from no milestone.

The milestone is the ADMISSION over a real candidate, not the existence of the
procedure: the second reading is satisfied today by a function nothing has
called.

* Add the runnable entry point: where_are_we writes the derived standing, and its exit status answers whether the instrument worked rather than whether the program is done

* Group the unanswerable milestones by the instrument that would answer them: twelve NotDerivable rows are EIGHT problems, and the report now says so

A missing instrument is a shared fact, so it gets a shared carrier instead of a
sentence per milestone. Twelve prose rows cannot tell a reader whether the
program is waiting on one measurement or twelve; the closed vocabulary plus a
derived join can, and the answer moves when the arms move.

Measured: two instruments answer three milestones each, six answer one each.
Nothing answers five, which is the less convenient of the two possible worlds
and the one a planner needs.

Also splits the empty-instrument-list conflation: 'needs nothing of its own' and
'we did not work out what it needs' were one spelling, and only the first is a
real answer.

* Split absence from refusal: the top instrument is not unbuilt, it is refused by a named authority on host memory

'Missing instrument' read as absence — go and build it. The highest-leverage row
on the list is not absent: a whole-corpus compile is refused ON MEMORY by
gunbc.whole_corpus_compile_admission, cited as a DeclarationRef so the ingestion
wall resolves it. Build-it and make-it-affordable are different remedies and no
amount of the first produces the second.

A first cut of this arm blamed a per-entry wall-clock cost shape another lane had
measured. That was authority substitution — the timing fact and the admission
live in different carriers and neither claims a relation. The admission compares
host memory against a measured peak and its receipts are SIGKILLs; the arrow may
even run the other way, since sharing a closure holds more resident at once. The
word 'budget' carried two resources. Retracted before it shipped, by the lane
that took the timing measurement.

The row states the honest scope: refused on a small runner, never attempted on a
large one, and admission means not-provably-doomed rather than will-fit.

* Drop the routing explanation from the refusal row: it was true of consumer sessions and false inside this repo

A prior revision said remote is the default route, so a memory-bound job is sent
automatically to the smallest machine. The gunbc shim carries an explicit
gunbc-checkout guard that execs the real local binary instead, because in a
gunbc-dev session gunbc is the subject under development rather than a pinned
tool. So a whole-corpus compile started from this repository was never being
routed away, and the row was explaining something that is not happening.

This arm has now been wrong twice for one underlying reason: it kept EXPLAINING
a refusal rather than REPORTING it. It now states only what the predicate is a
function of, that admission is not fit, and what would settle it -- and adds the
half that decides whether the falsification is worth anything: exit status and
peak resident set must be recorded TOGETHER, because a SIGKILL and a clean empty
population are the same bytes to a harness that greps output.

How the authority's SIGKILL receipts came to be taken is unestablished and this
row does not guess.

* Make the report denominate itself: it printed rows and left the counting to the reader, and the reader got it wrong three times

The standings were derived, the witnesses green, the carrier correct -- and its
own author eyeballed the output and reported 'five startable, nine not
derivable' to three audiences when every run this session produced read six and
eight. A downstream planner had already acted on the figures.

Nothing in the construction could have caught that, because the defect sat one
layer ABOVE it: in the prose that reports a derived carrier, the one channel a
derived carrier does not cover. So the remedy is not care. The report now states
the counts it derives, and a reader quoting a figure quotes a derived one.

The census fold is parameterized on its population so it is checkable against a
controlled fixture with independently authored expected counts -- folded only
over the live roster, its sole available oracle would be a transcription of that
roster. The live arm asserts the PARTITION LAW rather than today's figures, so
it reds on a milestone that falls out of every class or is counted twice, and
not on the program legitimately moving.

* The startability fold computed the known blockers and threw them away, so the carrier asserted that nothing waits on work in flight

`milestone_startability` bound both prerequisite populations and then discarded
the OUTSTANDING one whenever an unanswerable prerequisite sat beside it:

    let unanswerable = prerequisite_names_by_class(m: m, want: ClassNotDerivable)
    let blocking     = prerequisite_names_by_class(m: m, want: ClassOutstanding)
    if count(unanswerable) > 0 { StartabilityNotDerivable { unanswerable } }

The admission PRIORITY was right and stays right -- unknown evidence fails closed,
so a mixed milestone is not authorized to start. What was wrong was letting an
admission verdict serve as a PLANNING REPORT. `blocked == 0` meant only "zero
outstanding-ONLY cases"; it never meant zero outstanding dependencies.

So the sentence this program put in a PR body and relayed to three audiences --
"nothing here waits on work someone is doing" -- was FALSE, and the carrier's own
headline number was cited as the evidence for it. Three of the fourteen milestones
are mixed today: SelfHostRatchetGateEnrolled, SelfHostSuccessorPromotionAdmitted
and SelfHostSeedRetirement each have a known, observed blocker sitting beside an
unanswerable one. The report now says so, on S4b:

    startability not derivable -- unanswerable prerequisite: S2; S3;
      AND ALREADY BLOCKED ON: self-host S4a

WHAT THE PLANTED RED ESTABLISHED, and it is the part worth keeping. Re-inserting
the original defect (`blocking: []`) reds exactly three arms -- the four-state
exhibit, the mixed-identity control, and the live mixed-population join -- while
the OTHER TWENTY PASS. Those twenty are the arms that were already here. They were
blind to this, which is precisely why it shipped green with three approvals and a
review that read the fold and called it correct. A green witness set is evidence
about the arms that exist, never about the ones nobody wrote.

The four-way partition replaces the three-way one, because a summary printing
"not derivable 8" hides that three of the eight are already blocked and only five
are genuinely unknown -- the same information loss, one layer out, in the very
line added to stop readers from counting rows by eye:

    direct prerequisites
      startable 6
      blocked, all blockers known 0
      startability not derivable, no known blocker 5
      BLOCKED AND blocker set not fully derivable 3

`startability_from_populations` is split out so all four states are authorable at
FIXTURE grain. This is not decomposition for its own sake: BLOCKED-KNOWN-ONLY is
inhabited by no milestone in the live graph, so over the roster alone its control
could never be written, and a check whose RED cannot be produced is the decoration
DESIGN 4b rules worse than absent (4b names the fixture boundary as the one that
decides, and it decides here).

The instrument relation is renamed `unblocks` -> `awaited by`. It tests membership
in a required-instrument list, and SelfHostRatchetGateEnrolled requires the
whole-corpus board AND the gate-enrolment fact: neither alone makes it derivable.
Calling that "unblocks" would let a leverage count direct dispatch at an instrument
that, delivered alone, moves nothing -- the board independently answers two and is
co-required for a third; the gate-enrolment fact independently answers NONE.
Deriving singleton sufficiency is a stronger carrier and is NOT claimed here.

Also: the whole-corpus join now asserts all three identities rather than a count
plus one anchor (a two-way substitution passed before), with a disjointness control
over the two three-milestone instruments; and two stale prose counts corrected --
"eleven" missing instruments where there are twelve, and a witness annotation
naming a "fourteenth variant" that this program had already added.

Found by review on #9388. It was an APPROVE.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* The anti-inflation witness was itself a ledger: a live snapshot whose only closing move on real progress was to hand-tick it

Review 56456 raised three findings against the status witness. All three are
correct against the current code and all three are fixed here.

1. `no_milestone_reads_clear_today` is DELETED. It asserted count(clear) == 0 over
the LIVE roster against a bare literal, with none of the four groundings DESIGN
section 5 allows: not a controlled fixture, not an external or versioned authority,
not a policy budget, and as a monotone debt contract it ran BACKWARD -- it ratcheted
against the program making progress. The day a milestone legitimately became Clear,
CI reds and the only closing move is to hand-edit the expectation. That is
hand-ticking a ledger, reintroduced one layer out inside the check that was supposed
to guard against it, and it is the laundering shape this repository already recorded
for the rustfmt gate: a gate whose sole closing move is the forbidden action is not
strict.

Its annotation defended it as "written to RED on a genuine climb rather than to
survive one". That described the behaviour accurately and mistook it for a virtue.
The deletion loses nothing, and that is checkable rather than asserted: Clear has
exactly one route -- a fold over an observed population minted through
sole_constructor -- and two fixture arms exercise that fold in both directions. The
guarantee was always the construction; the snapshot restated today's output of it.

An earlier APPROVE on this PR praised that arm BY NAME. Two reviewers read the same
code and reached opposite verdicts; the one with section 5's text behind it wins.

2. `count(labels) == 14` is removed from the roster witness -- the same tree-copied
oracle one size smaller, whose closing move on a legitimate fifteenth milestone is
to hand-edit the number. Roster SIZE is not a law. DISTINCTNESS is, and it reds
regardless of how many milestones exist, because a duplicate silently doubles a
report row and inflates every population read off it.

The hand roster itself cannot be fixed here -- `.dag` cannot enumerate a coproduct --
but review 56456 was right that prose left it with no disposition. Now declared:
rung MITIGATABLE; class WALL AFTER GROUNDING (decidable, blocked on one missing
language capability, not a ratchet); next-rung trigger, coproduct enumeration, at
which point `program_milestones` and `all_missing_instruments` are both DERIVED and
both hand rosters are DELETED rather than checked.

3. `standing_is_clear` / `standing_is_outstanding` are replaced by the carrier's own
`standing_class`. They were a second representation of a classification the carrier
already owns, and would have kept answering the old way if a variant were added or
its meaning moved. A test that forks the judgement it is testing checks its copy.

VERIFIED BY EXECUTION, and the plant re-run matters here specifically because
finding 3 replaced the classification path the discriminating arms run through, so
their earlier red was not evidence about this one: 22/22 PASS; re-planting the
startability defect (`blocking: []`) reds exactly the same three arms and no others,
19 PASS / 3 FAIL.

ONE ARM OF THE SAME CLASS IS KEPT DELIBERATELY, named here rather than left for the
next reviewer to find. `the_emitter_artifact_milestone_reports_both_halves_of_its_population`
also reds when the emitter closes its gap. It stays because it is the only executing
evidence that the milestone's population UNIONS two rosters -- reading only the
registrations would report Clear the moment that row is deleted while the CLI surface
stayed unemitted -- so its red on progress is a COST of real structural coverage, not
its content. The deleted snapshot had no such coverage: it asserted a count that the
fixture arms already establish structurally. If that distinction is judged wrong, the
repair is to derive the two-roster union claim at fixture grain, not to keep a
snapshot beside it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

* The controlled fixture controlled membership and read state from the live tree, so it was the deleted ledger wearing a fixture's clothes

Exact-head review of #9388 found four residues. All four are real and fixed here.

1. THE CENSUS FIXTURE WAS A LIVE SNAPSHOT PIN. `standing_census` accepted a chosen
list of milestones, and every standing still came from `milestone_status` over the
live tree. So parameterizing the SELECTION controlled MEMBERSHIP and never STATE:
an arm naming two real milestones and asserting one OUTSTANDING and one
NOT-DERIVABLE reds the day the emitter or the CI phase roster legitimately moves,
and its closing move is to edit the expected figures or swap in different live
subjects. That is the identical backward-running contract deleted from
`no_milestone_reads_clear_today` one commit earlier -- surviving inside the arm
this PR had been citing as proof the census HAD an independent oracle.

Split again: `standing_census_from_rows` folds over authored `StandingRow`s,
`milestone_row` is the live mapping, `standing_census` composes them. Fixtures now
author states directly, so no tree state can move them. The live arms assert only
what cannot ratchet: the partition LAW, and a RELATION -- that a milestone's row
carries the same classes its own two folds return, which moves on both sides at
once.

`StartabilityClass` becomes a real coproduct rather than a string label, so the
census counts over a closed vocabulary instead of comparing rendered text.

2. THE CARRIER'S PROSE STILL CARRIED THE OVERCLAIM THE OUTPUT HAD DROPPED. Three
comments survived the `unblocks` -> `awaited by` repair: an instrument awaited by
five milestones called "the highest-leverage item", the program declared "not
labour-constrained" with "the right next dispatch is an instrument", and the join
introduced as "which milestones does this one missing instrument unblock". None
follows from `milestones_awaiting`, which establishes DIRECT REQUIREMENT MEMBERSHIP
and nothing else -- not singleton sufficiency, not comparative leverage, not
dispatch priority, not the absence of simultaneous outstanding work, not ownership.
Narrowed to the output's semantics, with the retracted claims named rather than
quietly deleted, and the live counter-example stated: the gate-enrolment fact is
awaited by a milestone and alone moves nothing.

3. `count(labels) == 8` on the instrument roster is removed -- the same copied-size
oracle as the `== 14` deleted last commit. Eight is tree state, not law; a
legitimate ninth instrument would red it until someone hand-edited the literal.
Distinctness and awaitedness are what the witness actually grounds and both stay.
Completeness against the closed coproduct remains MITIGATABLE pending coproduct
enumeration, and the literal never improved that rung.

4. THE NAMESPACE ROSTER WAS COUNT-PLUS-ONE-ANCHOR while its comment claimed exact
identities. Count three, one named member and disjointness from the board's three
still permitted either remaining namespace identity to be silently replaced by any
non-board milestone. `NamespaceFixForwardComplete` and `NamespaceGrammarRetired`
are now asserted; with all three named the population is exact and the disjointness
arm stays as the negative substitution control.

VERIFIED BY EXECUTION: 23/23 PASS. Report unchanged at 6 / 0 / 5 / 3, which is the
result the refactor had to preserve -- it changed the path, not the answer.
Re-planting the startability defect reds the same three arms and no others,
20 PASS / 3 FAIL. The plant was re-run after this refactor deliberately: it moved
the classification path a second time, and a discriminating control only counts
against the version it ran on.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Brian Searls <bts53@scarletmail.rutgers.edu>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.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