Skip to content

Enrol the five witness-test cadence recitals in the census that owns them, and correct their prose - #9866

Merged
gunbai-bot[bot] merged 2 commits into
mainfrom
session/eager-hawk-376-cadence
Sep 1, 2026
Merged

gunbai-bot[bot] merged 2 commits into
mainfrom
session/eager-hawk-376-cadence

Conversation

@gunbai-bot

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

Copy link
Copy Markdown
Contributor

Follow-on to #9858. Five annotations asserted that a deleted cadence executes
them; std.witness_admission witness_cadence_has_scheduled_route reports all
three named arms routeless.

SAME SUBJECT, ANSWERED AGAINST THE CENSUS'S OWN DECLARATION RATHER THAN BY
RESEMBLANCE. gunbc.deleted_cadence_reference_census's twelve rows are authority
rows that RELIED on the cadence for a coverage claim; these five are witness
tests whose annotations asserted the cadence EXECUTES them. That is the same
subject reached from the other side — the row's coverage rests on a dark cadence
either way — and the precedent is already in the census:
tools.namespace_import_closure_behavioral_transport nic_doc is a wet-receipt
transport doc censused there, carrying the exact correction these five now
match. So this is enrollment in an existing subject, not a widening of it, and
no new authority is minted.

THE CENSUS'S VOCABULARY CORRECTED MY OWN READING TWICE, which is the argument
for using it rather than editing prose beside it.

  1. NONE OF THE FIVE IS ReboundToExecutingConsumer, INCLUDING THE TWO CARRYING A
    LOCAL RECIPE. I had recorded on XL-0-RECEIPT: delete the floor component receipt pair — a well-built model with no producer, reciting a deleted transport in the present tense #9858 that instrument_sandbox's live half
    genuinely executes via its local recipe and should be corrected rather than
    past-tensed. Too generous: std.witness_admission answers OfflineLocalRecipe
    true, which is a statement about ROUTES, while this census asks the stricter
    question and its own note answers it — a command with no workflow is a local
    recipe, not a scheduled entry point. Two authorities, two questions; reading
    the looser answer into the stricter one would have manufactured coverage.
    The recipes are recorded as MANUAL routes instead.

  2. The site is the DECLARATION THE ANNOTATION IS ATTACHED TO, because §4c
    annotations have no symbol of their own for a DeclarationRef to name.

WHAT LANDS:

  • five PremiseInvalidated rows, plus substrate_long_lane_coverage for the third
    cadence (the other two coverage rows already existed and are reused).
  • the census's own arithmetic brought into agreement with itself: "THE TWELVE
    SITES … two more than the ten" becomes seventeen and fifteen, and the five are
    added to the drop population, because a PremiseInvalidated row IS one a re-add
    restores — which is the distinction that comment already spells out.
  • five prose corrections, one remedy arm each per gunbc.recurring_failure_mode
    unbacked_execution_claim, MATCHING THE TWO EXISTING EXEMPLARS rather than
    inventing a style beside them: nic_doc's "classification is membership, not
    execution" for the two self-host receipts, and ci_layer_roots
    bin_witness_wet_note's "THE JUSTIFYING HALF OF THAT SENTENCE IS PAST TENSE"
    for self_host_logic, which is the strongest instance. The perturb line keeps
    its true "Enrolled on" and loses only the false "nightly".

NOT VERIFIED LOCALLY, DELIBERATELY: the census witness runs
deleted_cadence_reference_census_live_holds over the live rows, so it checks
every new row's cadence is genuinely routeless. Two remote attempts refused
fail-closed with HostBudgetUnreadable — the BuildBuddy runner exposes no cgroup
memory limit, so the corpus resolve cannot bound itself and refuses rather than
defaulting. That is the runner, not this change, and it never reached the
witness. CI's floor job is the executing evidence, as it was for #9858.

gunbc-ci-auto-heal and others added 2 commits September 1, 2026 02:01
…them, and correct their prose

Follow-on to #9858. Five annotations asserted that a deleted cadence executes
them; std.witness_admission witness_cadence_has_scheduled_route reports all
three named arms routeless.

SAME SUBJECT, ANSWERED AGAINST THE CENSUS'S OWN DECLARATION RATHER THAN BY
RESEMBLANCE. gunbc.deleted_cadence_reference_census's twelve rows are authority
rows that RELIED on the cadence for a coverage claim; these five are witness
tests whose annotations asserted the cadence EXECUTES them. That is the same
subject reached from the other side — the row's coverage rests on a dark cadence
either way — and the precedent is already in the census:
tools.namespace_import_closure_behavioral_transport nic_doc is a wet-receipt
transport doc censused there, carrying the exact correction these five now
match. So this is enrollment in an existing subject, not a widening of it, and
no new authority is minted.

THE CENSUS'S VOCABULARY CORRECTED MY OWN READING TWICE, which is the argument
for using it rather than editing prose beside it.

1. NONE OF THE FIVE IS ReboundToExecutingConsumer, INCLUDING THE TWO CARRYING A
   LOCAL RECIPE. I had recorded on #9858 that instrument_sandbox's live half
   genuinely executes via its local recipe and should be corrected rather than
   past-tensed. Too generous: std.witness_admission answers OfflineLocalRecipe
   true, which is a statement about ROUTES, while this census asks the stricter
   question and its own note answers it — a command with no workflow is a local
   recipe, not a scheduled entry point. Two authorities, two questions; reading
   the looser answer into the stricter one would have manufactured coverage.
   The recipes are recorded as MANUAL routes instead.

2. The site is the DECLARATION THE ANNOTATION IS ATTACHED TO, because §4c
   annotations have no symbol of their own for a DeclarationRef to name.

WHAT LANDS:
- five PremiseInvalidated rows, plus substrate_long_lane_coverage for the third
  cadence (the other two coverage rows already existed and are reused).
- the census's own arithmetic brought into agreement with itself: "THE TWELVE
  SITES … two more than the ten" becomes seventeen and fifteen, and the five are
  added to the drop population, because a PremiseInvalidated row IS one a re-add
  restores — which is the distinction that comment already spells out.
- five prose corrections, one remedy arm each per gunbc.recurring_failure_mode
  unbacked_execution_claim, MATCHING THE TWO EXISTING EXEMPLARS rather than
  inventing a style beside them: nic_doc's "classification is membership, not
  execution" for the two self-host receipts, and ci_layer_roots
  bin_witness_wet_note's "THE JUSTIFYING HALF OF THAT SENTENCE IS PAST TENSE"
  for self_host_logic, which is the strongest instance. The perturb line keeps
  its true "Enrolled on" and loses only the false "nightly".

NOT VERIFIED LOCALLY, DELIBERATELY: the census witness runs
deleted_cadence_reference_census_live_holds over the live rows, so it checks
every new row's cadence is genuinely routeless. Two remote attempts refused
fail-closed with HostBudgetUnreadable — the BuildBuddy runner exposes no cgroup
memory limit, so the corpus resolve cannot bound itself and refuses rather than
defaulting. That is the runner, not this change, and it never reached the
witness. CI's floor job is the executing evidence, as it was for #9858.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Li6e7cEDFodeBV7uPi3yTz
…le-item grain only

The parse phase refused 14 times, once per line of a `//` block I placed INSIDE
`deleted_cadence_references()` between the census rows:

  source annotation sits inside a declaration body. Only module-item grain is
  modeled; move it above the declaration.

Moved verbatim to module scope, joining the existing header comment above that
fn, where it reads better anyway because it now sits beside the "THE SEVENTEEN
SITES" arithmetic it elaborates.

WHAT THE FAILING RUN ACTUALLY ESTABLISHED, since it is easy to read a red job as
a red change: the floor was CLEAN — verdict=FloorClean, planned=3349
executed=3349 failed=0, with 19 known-reds held and none newly passing. So
`deleted_cadence_reference_census_live_holds` DID run over the five new rows and
DID pass, which is the executing evidence this PR was waiting on: each new row's
cadence is genuinely routeless. The two failing phases were parse (this defect)
and namespace-wave-admission, which did not run at all because parse produced no
index. One authoring defect, no modeling defect.

Checked the same class across all six files this PR touches with a brace-depth
scan rather than by eye: no `//` inside any body remains.

This is a repeat of a class I had already been bitten by and had written down.
Recording it here rather than only in the commit that fixes it, because the
recurrence is the useful part: annotation grain is a rule the author must apply
at authoring time, and a long explanatory block is exactly where the temptation
to sit it beside the rows it explains is strongest.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Li6e7cEDFodeBV7uPi3yTz
@gunbai-bot
gunbai-bot Bot merged commit 73b585a into main Sep 1, 2026
6 checks passed
@gunbai-bot
gunbai-bot Bot deleted the session/eager-hawk-376-cadence branch September 1, 2026 03:02
@briansrls
briansrls restored the session/eager-hawk-376-cadence branch September 1, 2026 03:06
gunbai-bot Bot pushed a commit that referenced this pull request Sep 1, 2026
… check named to catch them is blind to the whole population

Nine citation sites, six symbols, repointed at the declaration each §4c
annotation is attached to, per the disposition #9866 settled against
gunbc.deleted_cadence_reference_census. Comment and diagnostic text only.

The measurement that motivates them is in the PR body: 0 typed DeclarationRef
citations dangle from the sweep, 468 prose sites over 336 retired symbols do,
and seven of the ten post-sweep sites were authored after it merged — an open
future set, not a bounded population.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WPgQxFX4Cc37W2kEDC8kXS
gunbai-bot Bot added a commit that referenced this pull request Sep 1, 2026
… check named to catch them is blind to the population (#9874)

* DESIGN.md listed a retired rung drop as standing: derive the list from the rows' own standing

DESIGN.md's "The ones standing today" list was projected as an UNFILTERED map over
gunbc.rung_drop rung_drop_roster. Retirement was written only as prose inside each row's
`authored` paragraph, which a projection cannot read. So the list asserted
"Cited-symbol resolution as a required check" as currently standing for six days after
its restoration trigger fired on 2026-08-25 -- in a document loaded in full on every turn
of every session. Two sessions independently built work on that false premise.

The repair is derivation, not a hand-edit: DESIGN.md declares itself a projection that is
never hand-edited, so editing the list would have left the second authority in place to
drift again on the next retirement.

- gunbc.rung_drop gains RungDropStanding (Standing | Retired { trigger_fired }) and a
  `standing` field, so retirement is a fact the row owns rather than prose beside it.
- rung_drop_is_standing / standing_rung_drops derive the list; gunbc.design_document
  projects standing_rung_drops() instead of the whole roster.
- gunbc.design_ledgers still folds the FULL roster: a ledger records retired drops too.
  Two consumers, each asking its own question of one authority.

CENSUS OF THE OTHER SEVEN ROWS, since a list that drifted once may have drifted more: it
had not. Exactly one row is retired. emit_stage_blocking says "NARROWED RATHER THAN
RETIRED" and fabric_evidence_gating says "THIS IS NOT RETIRED BY THE MEMO PR MERGING";
the rest carry no retirement language. DESIGN.md goes 8 rows to 7.

EVIDENCE, executed, not described. test.claim.rung_drop_standing_partition_witness_test
returns true on this tree and false when the retired row is re-marked Standing. Its second
conjunct asserts the roster still HOLDS a retired row: without it, a filter over an
all-Standing roster excludes nothing and the check would be permanently green by
construction -- a decoration, not a wall.

RESIDUE, named rather than left to be discovered: `standing` is authored and nothing
derives it from the paragraph beside it. This change removes the second authority for the
standing LIST; it does not close the gap between a row's prose and its field.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016Fk4zsZLzxJ3zJ3o969vBQ

* XL-0-CITE: the prose sweep's dangling citations are accruing, and the check named to catch them is blind to the whole population

Nine citation sites, six symbols, repointed at the declaration each §4c
annotation is attached to, per the disposition #9866 settled against
gunbc.deleted_cadence_reference_census. Comment and diagnostic text only.

The measurement that motivates them is in the PR body: 0 typed DeclarationRef
citations dangle from the sweep, 468 prose sites over 336 retired symbols do,
and seven of the ten post-sweep sites were authored after it merged — an open
future set, not a bounded population.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WPgQxFX4Cc37W2kEDC8kXS

* Dissolve the RungDropStanding -> Bool accessor into its one consuming filter

review 58038 (codex/gpt-5.6-sol) on #9874: rung_drop_is_standing was a standalone
coproduct-to-Bool predicate beside the variant the row already carries. Deleted;
the standing arm is now matched inline at the single site that consumes it,
which is the shape std.trait_derive_shape already uses.

The witness stopped re-deriving the predicate too, which would only have tested
its own copy of the arm. It now joins on IDENTITY: the retired row is absent from
the derived list and present exactly once in the roster it was retired in place
within. Executed both arms with gunbc run against the whole dag+src/v2 closure:
true as authored, false when cited_symbol_census is flipped back to Standing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WPgQxFX4Cc37W2kEDC8kXS

---------

Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
gunbai-bot Bot added a commit that referenced this pull request Sep 1, 2026
…mber (#9940)

* DESIGN.md listed a retired rung drop as standing: derive the list from the rows' own standing

DESIGN.md's "The ones standing today" list was projected as an UNFILTERED map over
gunbc.rung_drop rung_drop_roster. Retirement was written only as prose inside each row's
`authored` paragraph, which a projection cannot read. So the list asserted
"Cited-symbol resolution as a required check" as currently standing for six days after
its restoration trigger fired on 2026-08-25 -- in a document loaded in full on every turn
of every session. Two sessions independently built work on that false premise.

The repair is derivation, not a hand-edit: DESIGN.md declares itself a projection that is
never hand-edited, so editing the list would have left the second authority in place to
drift again on the next retirement.

- gunbc.rung_drop gains RungDropStanding (Standing | Retired { trigger_fired }) and a
  `standing` field, so retirement is a fact the row owns rather than prose beside it.
- rung_drop_is_standing / standing_rung_drops derive the list; gunbc.design_document
  projects standing_rung_drops() instead of the whole roster.
- gunbc.design_ledgers still folds the FULL roster: a ledger records retired drops too.
  Two consumers, each asking its own question of one authority.

CENSUS OF THE OTHER SEVEN ROWS, since a list that drifted once may have drifted more: it
had not. Exactly one row is retired. emit_stage_blocking says "NARROWED RATHER THAN
RETIRED" and fabric_evidence_gating says "THIS IS NOT RETIRED BY THE MEMO PR MERGING";
the rest carry no retirement language. DESIGN.md goes 8 rows to 7.

EVIDENCE, executed, not described. test.claim.rung_drop_standing_partition_witness_test
returns true on this tree and false when the retired row is re-marked Standing. Its second
conjunct asserts the roster still HOLDS a retired row: without it, a filter over an
all-Standing roster excludes nothing and the check would be permanently green by
construction -- a decoration, not a wall.

RESIDUE, named rather than left to be discovered: `standing` is authored and nothing
derives it from the paragraph beside it. This change removes the second authority for the
standing LIST; it does not close the gap between a row's prose and its field.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016Fk4zsZLzxJ3zJ3o969vBQ

* XL-0-CITE: the prose sweep's dangling citations are accruing, and the check named to catch them is blind to the whole population

Nine citation sites, six symbols, repointed at the declaration each §4c
annotation is attached to, per the disposition #9866 settled against
gunbc.deleted_cadence_reference_census. Comment and diagnostic text only.

The measurement that motivates them is in the PR body: 0 typed DeclarationRef
citations dangle from the sweep, 468 prose sites over 336 retired symbols do,
and seven of the ten post-sweep sites were authored after it merged — an open
future set, not a bounded population.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WPgQxFX4Cc37W2kEDC8kXS

* Dissolve the RungDropStanding -> Bool accessor into its one consuming filter

review 58038 (codex/gpt-5.6-sol) on #9874: rung_drop_is_standing was a standalone
coproduct-to-Bool predicate beside the variant the row already carries. Deleted;
the standing arm is now matched inline at the single site that consumes it,
which is the shape std.trait_derive_shape already uses.

The witness stopped re-deriving the predicate too, which would only have tested
its own copy of the arm. It now joins on IDENTITY: the retired row is absent from
the derived list and present exactly once in the roster it was retired in place
within. Executed both arms with gunbc run against the whole dag+src/v2 closure:
true as authored, false when cited_symbol_census is flipped back to Standing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WPgQxFX4Cc37W2kEDC8kXS

* XL-0-CITE: the dangling-citation population gets a producer, not a number

The 468/336/314 figures from #9874 lived only in a merged PR body, produced by a
scratchpad census that did not survive the session. DESIGN section 6 cites a
measurement by naming the producer that re-derives it, so the deliverable here is
the producer and the numbers are its first output.

tools.prose_citation_census re-derives, on demand and at identity grain, the prose
citation sites naming a prose row that a declared BASELINE REF held and HEAD does
not. Executed against the pre-sweep baseline 2afe322 (the three slices #9751 /
#9753 / #9752 are one commit chain, so one baseline covers the sweep):

  retired-rows=4002 sites=394 names=297 annotation=313 prose-row=81 cross-file=246

The baseline is a PARAMETER, so the slice split is runs of this function rather
than three literals written into it.

NO SWEEP, EVER, and it is in the module as the reason rather than the rule.
Annotation attachment is POSITIONAL, so repointing every site at the declaration
its annotation now sits above is not semantics-preserving: the measured specimen
is host_budget_unreadable_cgroup_receipt_note, whose prose was module-level
rationale about an absorbing-fallback deletion and whose following declaration is
now an unrelated seed-mirror scaffold disposition. A mechanical sweep would
manufacture, once per cross-file site, a citation that RESOLVES AND LIES -- worse
than one that dangles loudly, because a resolving citation is never re-examined.

MEMBERSHIP IS gunbc.prose_row_frontier's AND NOWHERE ELSE. The grep pattern is
deliberately WIDER than the rule -- every `data NAME: String` head -- and
prose_row_decl_name decides. Narrowing the argv to the `_note` suffix would put
the membership rule beside the module that owns it, where the two drift and the
argv wins silently. The stated consequence: a retired `data` row whose name lacks
that suffix is outside this subject, about five percent of what the slices
retired. Named rather than closed by widening a standing wall's recogniser from
inside a measurement lane.

THREE DEFECTS THIS FOUND IN ITSELF, each by execution rather than by review.

1. A three-argument lookup(map, key, default) compiled clean while never returning
   the value. The cross-file control passed FOR THE WRONG REASON -- with the path
   empty, every site reads as cross-file -- and only the same-file arm went red. The
   repair is construction, not a corrected default: the membership test and the read
   are one fold over the Optional, so the unreachable arm has no value to fabricate.

2. The diff producer refused, correctly, at 18 MB against an 8 MB shell output
   limit (13 MB restricted to *.dag). Its size is driven by distance to HEAD, not by
   the retirement measured, so it would refuse for every baseline eventually. Reading
   the baseline's own declarations through the new git.Inspect.GrepMatchesAtRevision
   is 1.06 MB and is the better question besides: the baseline declaring a row is a
   direct observation, where a diff infers it from everything that happened since.

3. The file roster was the union of data_decl_type_facts and decl_facts rel_paths.
   That is not a roster: a source with no `data` row is invisible to the first and
   the second skips test .dag files, so nine citation sites in test modules with zero
   data declarations were lost -- an empty-observation narrow arriving as a smaller
   number. Rebuilt from the tree listing, which is complete by construction. A
   declaration index answers which files declare something; this scan needs which
   files exist.

EVIDENCE. Sixteen controls green by execution under --claim-run, including the
twelve sampled corpus specimens carried verbatim so the precision result is
re-executed rather than remembered, both boundary arms, the semantic-position
negative, the non-prose-row negative, an identity join in both directions, and a
counter pair shown non-constant in its retired index. A deliberately false probe
was run to prove the harness reports red at all, then removed rather than left as
a permanent CI failure. Against an independently written oracle sharing no code:
ZERO sites missed, one extra explained by a main merge mid-session.

WHAT THIS DOES NOT CLAIM. The text acquisition is a declared Scaffold bound to
std.source_annotation SourceAnnotationDebt -- it dissolves when annotation text is
published corpus-wide beside the declaration index. This module does NOT admit it:
a new source-text recogniser is an operator judgment that gunbc.bare_reference_
scanner_admission explicitly does not cover, and a row granting its own admission
is the self-authorized dissolution this corpus names. The census gates nothing,
which is why it can stand unadmitted at all. The section 4c/4b ruling on whether
prose-citation resolution is a compiler capability is recorded as deferred, not
dropped; this module is what makes it decidable against a re-derivable population.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PXd2xwe4GiuVt3rmVt2g4E

* Enrol the prose-citation census witness in the required floor, so its evidence outlives the PR that added it

The floor executed all 18 controls on 4a14b72 and reported them
standing=planned-and-passed disposition=planned_as_changed_witness. That
disposition is the whole finding: they ran because THIS PR CHANGED THEM, not
because the gate selects them. required_gate_prefixes carries 27 prefixes and
none matches test.claim.prose_citation_census_witness, so on the next PR that
does not touch the file every one of those identities is declined SILENTLY and
the floor stays green.

That is evidence with an expiry date. DESIGN section 4b(4) keeps a class's
discriminating controls ENROLLED as the executing evidence that its rung stays
real, and a control that stops executing while the claim it backs still stands
is the inert-lens failure arriving by attrition rather than by deletion. Reporting
"18 identities passed" without this row would have been true of one run and read
as a standing property.

One prefix row, 27 -> 28, verified to match the module. Nothing else changes:
selection is additive, so no existing identity's disposition moves.

COST IS NOT A CONCERN HERE AND WAS CHECKED RATHER THAN ASSUMED. The controls are
pure string recognition over literal specimens -- no corpus walk, no filesystem
read, no git -- and all 18 already executed inside the floor run on 4a14b72
within its budget. v2.workflow.floor_cost_debt exists because the 500ms per-claim
line cannot carry witnesses that read the live tree; these do not.

NO MIRROR REGENERATION IS OWED: the seed decodes this roster from the .dag at run
time via floor_decode_module_prefix_roster, so there is no hand-authored Rust copy
of the list to drift. The row is not annotated because section 4c models
module-item grain only and this is a list element, and because no sibling row
carries one -- the rationale belongs here.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PXd2xwe4GiuVt3rmVt2g4E

* Record the operator scaffold admission in the carrier, with its scope, boundary and dissolution verbatim

OPERATOR DISPOSITION: ScaffoldAdmitted, 2026-09-01, bound to gunbc#9940 at head
4a14b72. Relayed by bright-ram-778; this session cannot read the operator
thread, so the relay is named as the carrier rather than presented as a first-hand
reading.

The verdict is RECORDED in prose_citation_text_acquisition_disposition's annotation
and was not decided there. That distinction is the reason the row previously stood
unadmitted: an author who can write a scaffold can equally write a row claiming it
was approved, so approval has to be external to the diff or it is not approval.

WHAT IS WRITTEN DOWN, all of it verbatim from the ruling rather than paraphrased,
because a paraphrased boundary is a boundary that has already moved once:

  SCOPE -- GrepMatchesAtRevision; the raw-source text acquisition; the pure
  recognizer, join, carrier and report; the current executing witness population;
  manual/on-demand invocation with caller-supplied baseline and report.

  BOUNDARY, each item requiring a NEW disposition -- no required or advisory
  workflow invocation; no merge gate; no automatic source rewrite or citation
  repointing; no widening of gunbc.prose_row_frontier membership; no reuse as a
  general source-language recognizer; no baked baseline or persisted count.

  RENEWAL -- a new workflow consumer, automatic judgment, an additional source-text
  recognizer, or a materially broader scan. A review correction preserving the
  scope is not a renewal.

THE DISSOLUTION IS IN THE RULING'S OWN TERMS BECAUSE THE WORDING IS THE GUARANTEE:
when annotation text AND ITS ATTACHMENT IDENTITY are published corpus-wide beside
the declaration index, the raw-line acquisition DELETES. It does not survive as a
fallback. An acquisition deleted in name that still answers whenever the published
surface is unavailable would leave two authorities for one fact and retire nothing,
which is the failure that sentence exists to forbid.

THE ROW STAYS Scaffold. Being admitted is not being terminal -- the ruling grants
that it may stand, not that it should survive -- and relabelling it Terminal on the
strength of an admission would convert a bounded exception into a permanent
construction, the one move the dissolution sentence forbids. The recogniser half
remains Terminal on its own executed controls, which is a different claim about a
different half.

AND IT IS A NEW DISPOSITION, NOT AN EXTENSION OF AN OLDER ONE. gunbc.bare_reference_
scanner_admission lists "additional source-text recognizers" among what it
explicitly does NOT cover, RESERVING them for a fresh judgment. Without that
sentence a later reader finds two source-text recognizers standing under one
admission and concludes the older one was widened. It was not.

Annotation text only; no declaration, type or behaviour changes. Compile over the
census closure: 0 blocking errors, 301 advisories.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PXd2xwe4GiuVt3rmVt2g4E

---------

Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
gunbai-bot Bot added a commit that referenced this pull request Sep 1, 2026
…ity (review 58234 repairs to merged #9940) (#9958)

* DESIGN.md listed a retired rung drop as standing: derive the list from the rows' own standing

DESIGN.md's "The ones standing today" list was projected as an UNFILTERED map over
gunbc.rung_drop rung_drop_roster. Retirement was written only as prose inside each row's
`authored` paragraph, which a projection cannot read. So the list asserted
"Cited-symbol resolution as a required check" as currently standing for six days after
its restoration trigger fired on 2026-08-25 -- in a document loaded in full on every turn
of every session. Two sessions independently built work on that false premise.

The repair is derivation, not a hand-edit: DESIGN.md declares itself a projection that is
never hand-edited, so editing the list would have left the second authority in place to
drift again on the next retirement.

- gunbc.rung_drop gains RungDropStanding (Standing | Retired { trigger_fired }) and a
  `standing` field, so retirement is a fact the row owns rather than prose beside it.
- rung_drop_is_standing / standing_rung_drops derive the list; gunbc.design_document
  projects standing_rung_drops() instead of the whole roster.
- gunbc.design_ledgers still folds the FULL roster: a ledger records retired drops too.
  Two consumers, each asking its own question of one authority.

CENSUS OF THE OTHER SEVEN ROWS, since a list that drifted once may have drifted more: it
had not. Exactly one row is retired. emit_stage_blocking says "NARROWED RATHER THAN
RETIRED" and fabric_evidence_gating says "THIS IS NOT RETIRED BY THE MEMO PR MERGING";
the rest carry no retirement language. DESIGN.md goes 8 rows to 7.

EVIDENCE, executed, not described. test.claim.rung_drop_standing_partition_witness_test
returns true on this tree and false when the retired row is re-marked Standing. Its second
conjunct asserts the roster still HOLDS a retired row: without it, a filter over an
all-Standing roster excludes nothing and the check would be permanently green by
construction -- a decoration, not a wall.

RESIDUE, named rather than left to be discovered: `standing` is authored and nothing
derives it from the paragraph beside it. This change removes the second authority for the
standing LIST; it does not close the gap between a row's prose and its field.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016Fk4zsZLzxJ3zJ3o969vBQ

* XL-0-CITE: the prose sweep's dangling citations are accruing, and the check named to catch them is blind to the whole population

Nine citation sites, six symbols, repointed at the declaration each §4c
annotation is attached to, per the disposition #9866 settled against
gunbc.deleted_cadence_reference_census. Comment and diagnostic text only.

The measurement that motivates them is in the PR body: 0 typed DeclarationRef
citations dangle from the sweep, 468 prose sites over 336 retired symbols do,
and seven of the ten post-sweep sites were authored after it merged — an open
future set, not a bounded population.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WPgQxFX4Cc37W2kEDC8kXS

* Dissolve the RungDropStanding -> Bool accessor into its one consuming filter

review 58038 (codex/gpt-5.6-sol) on #9874: rung_drop_is_standing was a standalone
coproduct-to-Bool predicate beside the variant the row already carries. Deleted;
the standing arm is now matched inline at the single site that consumes it,
which is the shape std.trait_derive_shape already uses.

The witness stopped re-deriving the predicate too, which would only have tested
its own copy of the arm. It now joins on IDENTITY: the retired row is absent from
the derived list and present exactly once in the roster it was retired in place
within. Executed both arms with gunbc run against the whole dag+src/v2 closure:
true as authored, false when cited_symbol_census is flipped back to Standing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WPgQxFX4Cc37W2kEDC8kXS

* XL-0-CITE: the dangling-citation population gets a producer, not a number

The 468/336/314 figures from #9874 lived only in a merged PR body, produced by a
scratchpad census that did not survive the session. DESIGN section 6 cites a
measurement by naming the producer that re-derives it, so the deliverable here is
the producer and the numbers are its first output.

tools.prose_citation_census re-derives, on demand and at identity grain, the prose
citation sites naming a prose row that a declared BASELINE REF held and HEAD does
not. Executed against the pre-sweep baseline 2afe322 (the three slices #9751 /
#9753 / #9752 are one commit chain, so one baseline covers the sweep):

  retired-rows=4002 sites=394 names=297 annotation=313 prose-row=81 cross-file=246

The baseline is a PARAMETER, so the slice split is runs of this function rather
than three literals written into it.

NO SWEEP, EVER, and it is in the module as the reason rather than the rule.
Annotation attachment is POSITIONAL, so repointing every site at the declaration
its annotation now sits above is not semantics-preserving: the measured specimen
is host_budget_unreadable_cgroup_receipt_note, whose prose was module-level
rationale about an absorbing-fallback deletion and whose following declaration is
now an unrelated seed-mirror scaffold disposition. A mechanical sweep would
manufacture, once per cross-file site, a citation that RESOLVES AND LIES -- worse
than one that dangles loudly, because a resolving citation is never re-examined.

MEMBERSHIP IS gunbc.prose_row_frontier's AND NOWHERE ELSE. The grep pattern is
deliberately WIDER than the rule -- every `data NAME: String` head -- and
prose_row_decl_name decides. Narrowing the argv to the `_note` suffix would put
the membership rule beside the module that owns it, where the two drift and the
argv wins silently. The stated consequence: a retired `data` row whose name lacks
that suffix is outside this subject, about five percent of what the slices
retired. Named rather than closed by widening a standing wall's recogniser from
inside a measurement lane.

THREE DEFECTS THIS FOUND IN ITSELF, each by execution rather than by review.

1. A three-argument lookup(map, key, default) compiled clean while never returning
   the value. The cross-file control passed FOR THE WRONG REASON -- with the path
   empty, every site reads as cross-file -- and only the same-file arm went red. The
   repair is construction, not a corrected default: the membership test and the read
   are one fold over the Optional, so the unreachable arm has no value to fabricate.

2. The diff producer refused, correctly, at 18 MB against an 8 MB shell output
   limit (13 MB restricted to *.dag). Its size is driven by distance to HEAD, not by
   the retirement measured, so it would refuse for every baseline eventually. Reading
   the baseline's own declarations through the new git.Inspect.GrepMatchesAtRevision
   is 1.06 MB and is the better question besides: the baseline declaring a row is a
   direct observation, where a diff infers it from everything that happened since.

3. The file roster was the union of data_decl_type_facts and decl_facts rel_paths.
   That is not a roster: a source with no `data` row is invisible to the first and
   the second skips test .dag files, so nine citation sites in test modules with zero
   data declarations were lost -- an empty-observation narrow arriving as a smaller
   number. Rebuilt from the tree listing, which is complete by construction. A
   declaration index answers which files declare something; this scan needs which
   files exist.

EVIDENCE. Sixteen controls green by execution under --claim-run, including the
twelve sampled corpus specimens carried verbatim so the precision result is
re-executed rather than remembered, both boundary arms, the semantic-position
negative, the non-prose-row negative, an identity join in both directions, and a
counter pair shown non-constant in its retired index. A deliberately false probe
was run to prove the harness reports red at all, then removed rather than left as
a permanent CI failure. Against an independently written oracle sharing no code:
ZERO sites missed, one extra explained by a main merge mid-session.

WHAT THIS DOES NOT CLAIM. The text acquisition is a declared Scaffold bound to
std.source_annotation SourceAnnotationDebt -- it dissolves when annotation text is
published corpus-wide beside the declaration index. This module does NOT admit it:
a new source-text recogniser is an operator judgment that gunbc.bare_reference_
scanner_admission explicitly does not cover, and a row granting its own admission
is the self-authorized dissolution this corpus names. The census gates nothing,
which is why it can stand unadmitted at all. The section 4c/4b ruling on whether
prose-citation resolution is a compiler capability is recorded as deferred, not
dropped; this module is what makes it decidable against a re-derivable population.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PXd2xwe4GiuVt3rmVt2g4E

* Enrol the prose-citation census witness in the required floor, so its evidence outlives the PR that added it

The floor executed all 18 controls on 4a14b72 and reported them
standing=planned-and-passed disposition=planned_as_changed_witness. That
disposition is the whole finding: they ran because THIS PR CHANGED THEM, not
because the gate selects them. required_gate_prefixes carries 27 prefixes and
none matches test.claim.prose_citation_census_witness, so on the next PR that
does not touch the file every one of those identities is declined SILENTLY and
the floor stays green.

That is evidence with an expiry date. DESIGN section 4b(4) keeps a class's
discriminating controls ENROLLED as the executing evidence that its rung stays
real, and a control that stops executing while the claim it backs still stands
is the inert-lens failure arriving by attrition rather than by deletion. Reporting
"18 identities passed" without this row would have been true of one run and read
as a standing property.

One prefix row, 27 -> 28, verified to match the module. Nothing else changes:
selection is additive, so no existing identity's disposition moves.

COST IS NOT A CONCERN HERE AND WAS CHECKED RATHER THAN ASSUMED. The controls are
pure string recognition over literal specimens -- no corpus walk, no filesystem
read, no git -- and all 18 already executed inside the floor run on 4a14b72
within its budget. v2.workflow.floor_cost_debt exists because the 500ms per-claim
line cannot carry witnesses that read the live tree; these do not.

NO MIRROR REGENERATION IS OWED: the seed decodes this roster from the .dag at run
time via floor_decode_module_prefix_roster, so there is no hand-authored Rust copy
of the list to drift. The row is not annotated because section 4c models
module-item grain only and this is a list element, and because no sibling row
carries one -- the rationale belongs here.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PXd2xwe4GiuVt3rmVt2g4E

* Record the operator scaffold admission in the carrier, with its scope, boundary and dissolution verbatim

OPERATOR DISPOSITION: ScaffoldAdmitted, 2026-09-01, bound to gunbc#9940 at head
4a14b72. Relayed by bright-ram-778; this session cannot read the operator
thread, so the relay is named as the carrier rather than presented as a first-hand
reading.

The verdict is RECORDED in prose_citation_text_acquisition_disposition's annotation
and was not decided there. That distinction is the reason the row previously stood
unadmitted: an author who can write a scaffold can equally write a row claiming it
was approved, so approval has to be external to the diff or it is not approval.

WHAT IS WRITTEN DOWN, all of it verbatim from the ruling rather than paraphrased,
because a paraphrased boundary is a boundary that has already moved once:

  SCOPE -- GrepMatchesAtRevision; the raw-source text acquisition; the pure
  recognizer, join, carrier and report; the current executing witness population;
  manual/on-demand invocation with caller-supplied baseline and report.

  BOUNDARY, each item requiring a NEW disposition -- no required or advisory
  workflow invocation; no merge gate; no automatic source rewrite or citation
  repointing; no widening of gunbc.prose_row_frontier membership; no reuse as a
  general source-language recognizer; no baked baseline or persisted count.

  RENEWAL -- a new workflow consumer, automatic judgment, an additional source-text
  recognizer, or a materially broader scan. A review correction preserving the
  scope is not a renewal.

THE DISSOLUTION IS IN THE RULING'S OWN TERMS BECAUSE THE WORDING IS THE GUARANTEE:
when annotation text AND ITS ATTACHMENT IDENTITY are published corpus-wide beside
the declaration index, the raw-line acquisition DELETES. It does not survive as a
fallback. An acquisition deleted in name that still answers whenever the published
surface is unavailable would leave two authorities for one fact and retire nothing,
which is the failure that sentence exists to forbid.

THE ROW STAYS Scaffold. Being admitted is not being terminal -- the ruling grants
that it may stand, not that it should survive -- and relabelling it Terminal on the
strength of an admission would convert a bounded exception into a permanent
construction, the one move the dissolution sentence forbids. The recogniser half
remains Terminal on its own executed controls, which is a different claim about a
different half.

AND IT IS A NEW DISPOSITION, NOT AN EXTENSION OF AN OLDER ONE. gunbc.bare_reference_
scanner_admission lists "additional source-text recognizers" among what it
explicitly does NOT cover, RESERVING them for a fresh judgment. Without that
sentence a later reader finds two source-text recognizers standing under one
admission and concludes the older one was widened. It was not.

Annotation text only; no declaration, type or behaviour changes. Compile over the
census closure: 0 blocking errors, 301 advisories.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PXd2xwe4GiuVt3rmVt2g4E

* review 58228 / 58234: key retirement by qualified identity, and split the two states a bare-name key was collapsing

Two REQUEST_CHANGES findings from codex/gpt-5.6-sol. Both accepted. They turned
out to be one defect seen at two levels, and the second finding's repair is what
made the first one's fix obvious.

IDENTITY. Retirement was keyed on bare decl_name against a bare-name liveness
index. The review called it a false-negative risk; it is worse than that, and the
reason is this module's own argument. A row retired from its module while the same
spelling survives in ANOTHER module read as "still live" and left the census
entirely -- but a prose citation of that name still RESOLVES, to a declaration that
is not the one the prose meant. That is precisely the state the no-sweep paragraph
calls worse than dangling, because a resolving citation is never re-examined. A
census arguing that cannot be built so those are the sites it cannot see.

Retirement is now decided on module_path + decl_name, with baseline module lines
read at the same revision through the same operation. Both sides of the join are
the authored UNSTRIPPED module name -- v2.std.decl_index documents module_path as
authored-and-unstripped, and this was checked rather than assumed, because a silent
v2. prefix mismatch would have made every src/v2 row read as retired. A baseline
path with no module line establishes no identity and is not judged either way;
defaulting it to retired would enrol every unparsed file.

The site now carries ProseCitationResolution = CitedNameAbsentEverywhere |
CitedNameSurvivesElsewhere, both counted, because those are the two states the old
key collapsed by dropping the second.

PREDICATE. prose_citation_site_is_annotation was an is_* -> Bool matching the
ProseCitationCarrier coproduct. Deleted and matched inline at its two consumers.
This is the same class review 58038 raised on gunbc#9874 against
rung_drop_is_standing, which I had already been shown and then reintroduced.

THE SAME ERROR ONE LEVEL UP, which the predicate finding is what exposed:
cross_file was a Bool. A Bool has no spelling for "the name was retired from
several paths, so which file this citation is local TO is not decidable from the
site" -- it must answer true or false, which is ignorance rendered as an answer.
It is now ProseCitationLocality = InRetiringFile | InAnotherFile |
RetiringFileAmbiguous, and the retired index carries ProseRowOrigin =
RetiredFromOnePath | RetiredFromSeveralPaths instead of a name-keyed map whose
map_insert was silent last-write-wins over distinct origins.

MEASURED BEFORE BUILDING, so neither fix is priced on a hypothetical: at the
pre-sweep baseline 4002 retired rows carry 4002 distinct names, 0 sites fall in the
survives-elsewhere class and 0 origins collide TODAY -- while 38 prose-row names in
that same baseline are declared across more than one file over 119 rows. The
spelling already collides in this corpus; only the retired subset happens not to.
A realized n of zero is a fact about this tree, not about the construction.

EVIDENCE. 26 controls green by execution under --claim-run, five of them new and
each a pair that a bare-name or Bool-valued version could not satisfy: the same
bare name retired in one module and live in its own; a cited name declared nowhere
versus surviving elsewhere; one origin versus several; the same path twice staying
one origin; a baseline row whose module is unknown going unjudged.

Live run, unchanged in every figure the prediction named:
  retired-rows=4002 sites=397 names=298 annotation=314 prose-row=83
  another-file=249 ambiguous-origin=0 absent-everywhere=397 survives-elsewhere=0
Sites 394 -> 397 is this branch's own newly-tracked prose citing retired names.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PXd2xwe4GiuVt3rmVt2g4E

* Record the admitted shape of the witness beside the controls it constrains

The ScaffoldAdmitted disposition of 2026-09-01 admits PERSISTENT REQUIRED-FLOOR
ENROLMENT of test.claim.prose_citation_census_witness OVER AUTHORED IN-MEMORY
FIXTURES, and explicitly does NOT admit live-instrument invocation or git,
filesystem or corpus acquisition during those controls. That boundary had no trace
in the file it constrains.

IT HOLDS TODAY BY CONSTRUCTION AND NOT BY DISCIPLINE, which is the property worth
preserving and the reason this is worth writing down at all: the module's import
list names only pure functions and types, so these controls CANNOT acquire
anything -- there is no acquirer in scope to call. Verified rather than asserted:
no filesystem_read, no git.Inspect operation, no data_decl_type_facts, and neither
live entry point appears anywhere in the module.

SO THE RULE IS ABOUT THE IMPORT LINE, NOT THE TEST BODY, and that is the sentence a
later author needs. Adding any acquirer leaves the admitted scope AND puts a
live-tree read inside a required-floor witness, which is the cost shape
v2.workflow.floor_cost_debt exists for. Two consequences from one edit that would
otherwise look like adding a test.

This is the same failure as the enrolment gap this branch already fixed: a real
constraint with nothing in the artifact carrying it, so it survives only as long as
whoever knows it is still reading. Annotation text only; 0 blocking, 302 advisories
over the witness closure.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PXd2xwe4GiuVt3rmVt2g4E

* review 58279: the census's own witness was citing a field this PR retired

A one-line nit the reviewer marked as not worth a round trip. It is worth one,
because of WHAT it is rather than its size: "SAME-FILE IS THE OTHER ARM OF
cross_file" cites a field this very diff deleted, inside the witness of the
instrument that measures citations to deleted symbols. Shipping it means the census
can report its own witness, and a reader who noticed would be right to distrust the
result.

THE POPULATION IS EIGHT MENTIONS AND THREE CLASSES, and treating them uniformly
would have deleted rationale that is doing real work:

  STALE CITATION, repaired -- the line above, which names cross_file as though it
  still exists. Two control NAMES with it too, renamed for what they actually
  assert: an_annotation_citation_in_another_file_is_one_site_at_its_line and
  a_citation_in_the_retiring_file_is_local_to_it.

  RATIONALE ABOUT A DELIBERATE ABSENCE, kept -- "A Bool cross_file would have had
  to answer this case true or false." That names something removed on purpose and
  says why the coproduct replaced it. Prose citing a live symbol is misplaced data;
  prose naming a deliberate absence is the reason the design has its shape, and
  sweeping it would leave the third locality arm looking arbitrary.

  ORDINARY ENGLISH, kept -- "cross-file site" describes a relationship between two
  files and refers to no field at all.

A rename changes an enrolled floor identity, so the two renamed controls were
executed under their new names rather than assumed inert: both PASS. Compile over
the witness closure 0 blocking, 302 advisories.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PXd2xwe4GiuVt3rmVt2g4E

* Refuse when the baseline module read is partial, instead of reading it as zero retirements

Review 58281 on #9958 is correct and the finding is my own named failure mode.
`prose_citation_census_live` checked `exit_code` on the first git query and
argued about it at length in an annotation, then consumed the SECOND query --
the `^module` read added during the qualified-identity rework -- inline as
`.matches` with no outcome check. A failed module read yields an empty index,
every baseline row then misses in `lookup`, the `Absent => false` filter arm
drops it silently, and the function returns `ProseCitationCensusObserved` with
zero retirements. An acquisition failure rendered as a reassuring census: the
empty-observation narrow this module's own header argues against.

Two arms, both fail-closed:

- the module read's `exit_code` is checked and only 0 is accepted. Unlike the
  declaration read, where exit 1 is an honestly empty match set, a baseline
  with no module lines at all is not a corpus this census can speak about.
- `prose_citation_retired_rows` becomes `prose_citation_retirement_scan`,
  returning `ProseCitationRetirementScan { retired, unidentified }`. Rows with
  no module identity are still not JUDGED -- but they are no longer DROPPED,
  and the caller refuses with the count when any exist. "Not judged" and "not
  counted" were the two states the single-list return conflated.

NAME THE POPULATION FIRST: measured at baseline 2afe322, 4807 prose rows
against 4412 module lines and ZERO rows without a module identity. So the new
refusal cannot fire on a healthy read; it fires exactly when the acquisition is
broken.

Evidence, by execution:
- 28/28 controls PASS on the real recogniser (up from 25; three new).
- DISCRIMINATING RED: restoring the dropping arm turns
  `a_baseline_row_whose_module_is_unknown_is_carried_not_dropped` and
  `a_partial_module_index_splits_the_rows_across_both_lists` RED while the
  counter pair `a_populated_module_index_leaves_nothing_unidentified` and the
  retirement controls stay PASS -- the controls catch this defect, not any
  change.
- Live re-run at 2afe322 is byte-identical to the pre-fix census:
  retired-rows=4002 sites=397 names=298 annotation=314 prose-row=83
  another-file=249 ambiguous-origin=0 absent-everywhere=397
  survives-elsewhere=0. Neither new arm fires.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PXd2xwe4GiuVt3rmVt2g4E

* Close the baseline side of the same class: read a match line into four arms, refuse on one

Ruling from XL-N: shipping the module arm alone leaves an asymmetry a reviewer
would be right to object to, because the covered half is what makes the
uncovered half look considered. Both conditions checked before building.

CONDITION 1 -- same shape, not a new mechanism. It holds, but the grain was
finer than expected: `prose_citation_baseline_row` returned `none` for THREE
materially different reasons, not two.

  - a `data NAME: String` row the frontier declines -- program data, 3058 of
    them at the baseline. Refusing on these would refuse on every healthy run.
  - the blank trailing element `split` yields for the final newline. It reaches
    the no-separator test, so a naive "refuse on unparsed" would have fired on
    EVERY run via the trailing newline alone.
  - output not shaped like git grep output -- the acquisition misreporting its
    own format. This is the only arm that is a refusal.

So `BaselineLineReading` is a four-arm sum and `prose_citation_baseline_scan`
returns `{ rows, non_prose_count, blank_count, unparsable }`. The caller refuses
on `unparsable`. Same shape as the module arm: the state leaves the population
with a diagnostic instead of silently.

CONDITION 2 -- RED reachable, GREEN not accidental. Both established by
execution rather than argued:

  - MUTATION A, collapsing `Unparsable` into the non-prose arm (the original
    defect), reds `a_baseline_line_with_no_path_separator_is_unparsable_not_
    merely_empty` and `every_baseline_line_lands_in_exactly_one_arm` while the
    program-data and accepted-row controls stay green.
  - MUTATION B, dropping the blank arm, reds the blank control and the
    partition control -- so the arm that keeps the wall shippable is itself
    guarded.
  - Live re-run at 2afe322 is unchanged: retired-rows=4002 sites=397 names=298
    annotation=314 prose-row=83 another-file=249 ambiguous-origin=0
    absent-everywhere=397 survives-elsewhere=0. The wall does not fire.

`every_baseline_line_lands_in_exactly_one_arm` is the executable form of the
measurement that admitted this wall (4807 + 3058 = 7865, zero unparsable). A
count gap and a mass silent drop are indistinguishable from the gap alone, so
the control asserts the four arms EXHAUST the input rather than asserting a
filter exists -- no future arm can quietly absorb a line without reddening it.

31/31 controls PASS (was 28).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PXd2xwe4GiuVt3rmVt2g4E

---------

Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants