Skip to content

Make the witness-roster walk demand-directed instead of unconditional pre-plan - #8140

Merged
briansrls merged 5 commits into
mainfrom
session/eager-cat-841
Aug 11, 2026
Merged

briansrls merged 5 commits into
mainfrom
session/eager-cat-841

Conversation

@gunbai-bot

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

Copy link
Copy Markdown
Contributor

What this deletes

claim_executor ran discover_floor_witness_roster_with_snapshot before resolving the plan, unconditionally, on every invocation — ordinary floor, regen, falsifier, and every scoped worker.

Its own comment stated the intent:

the plan path always runs the fail-closed walk once up front — before the (expensive) plan evaluation, so a naming violation is the cheapest possible failure

Measured, it is the most expensive phase in the process:

path walk cost of
ordinary floor (run 31477894666) 5.9 min 56.5 min
regen ~6 min ~15 min, on a two-node plan

Why it costs that

"Naming hygiene" is a misleading label. The four rules in v2.workflow.floor_naming_hygiene are string predicates over file paths and line prefixes — no parse, no resolve, no types. But the roster producer they are reached through additionally builds module-graph facts, runs a second strict reference-resolution pass, computes path indexes, and runs inert-lens reachability plus the construction-justification census.

Regen's plan has two known gates and no discovery batch. It paid six minutes to discover a roster it never reads.

The change

Hygiene is a property of the witness roster, so it is now paid by the plans that have one. The walk moves to the existing schedules_discovery predicate, after the plan's batches settle.

  • Plans that do schedule discovery pay exactly what they paid before. The roster is memoized by request digest (IN_PROCESS_ROSTER_BY_REQUEST), so the corpus batch hits the memo this call fills. Same total work, later.
  • Plans that do not schedule discovery pay nothing — and cannot be unhygienic, because they have no roster.
  • The walk-attempt id is still minted unconditionally; it is a tracing coordinate every later phase stamps, and it is not the expensive part.

Also closes a hole the repo already named

gunbc.ci_spec gunbc_ci_floor_batch_wall_budget_note:

PRELUDE COVERAGE HOLE — the ~5min before batch-1 arms (naming-hygiene walk, policy install, plan resolve/eval, governor arm, eager compile-clean install) sits OUTSIDE every batch budget and can only red at the 55min step cap.

The walk is now inside the region the plan accounts for, or absent.

What this is NOT

Not a cache, not a memo, not a scope narrowing of the hygiene rules. Every plan that has a roster still runs the identical fail-closed walk over it. This deletes an unconditional call edge, not a check.

Follow-ups deliberately excluded (they are the next PR, not this one): moving the placement rules to the ingestion boundary, deriving test identities from the parser rather than a line scan, dropping the __ filename rule, and removing the inert-lens census.

Acceptance

  • cargo check -p v1-compiler --bin claim_executor clean
  • CI's own floor is the executed control: it schedules discovery, so it must run the walk and stay green
  • regen is the discriminating measurement — it schedules none, so its walk count must go to zero and its wall must drop by the phase cost

… pre-plan

claim_executor ran discover_floor_witness_roster_with_snapshot once up front,
BEFORE resolving the plan, on the stated ground that a naming violation should
be "the cheapest possible failure". Measured, that walk is the most expensive
phase in the process: 5.9 min of a 56.5-min ordinary floor (run 31477894666),
and ~6 min of a ~15-min regen whose plan has exactly two nodes.

It is expensive because "naming hygiene" is a misleading label. The four rules
in v2.workflow.floor_naming_hygiene are string predicates over file paths and
line prefixes, but the roster producer they are reached through also builds
module-graph facts, runs a second strict reference-resolution pass, computes
path indexes, and runs inert-lens reachability plus the construction-
justification census. A two-node regen plan paid all of it to discover a roster
it never reads.

Hygiene is a property of the witness ROSTER, so it is now paid by the plans that
have one: the walk moves to the existing `schedules_discovery` predicate, after
the plan's batches settle. The roster is memoized by request digest
(IN_PROCESS_ROSTER_BY_REQUEST), so plans that DO schedule discovery pay exactly
what they paid before — the corpus batch hits the memo this call fills. Plans
that do not schedule discovery pay nothing, and cannot be unhygienic: they have
no roster.

The walk-attempt id is minted unconditionally as before; it is a tracing
coordinate every later phase stamps, and it is not the expensive part.

This also closes the PRELUDE COVERAGE HOLE gunbc.ci_spec
gunbc_ci_floor_batch_wall_budget_note already names: the walk sat outside every
batch budget and could only red at the step cap. It is now inside the region the
plan accounts for, or absent.

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

gunbai-bot Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor Author

Thanks — approving note taken. One correction to the coverage analysis, because the mitigation named in review 51098 is not the one that actually holds.

The axis is not selection. The review reads the loss as "a *_test.dag not selected into any batch in a given run". Selection isn't what changed — the moved call still passes scan_dirs: &[] and discovery_scope_dirs: &[], i.e. it is still the whole-source-root walk with identical coverage. What changed is whether the plan schedules discovery at all.

So the loss is exactly:

ordinary floor plan   schedules discovery (batch 3)  → full-tree walk still runs, per PR
regen plan            two nodes, no discovery        → no walk
plan-artifact plan    no discovery                   → no walk

Every PR runs the ci job, whose plan schedules discovery, so a misnamed *_test.dag still reds per-PR at full tree scope. The residual gap is regen-only and plan-artifact-only runs.

The falsifier is not the backstop. Review 51098 attributes coverage to "the falsifier cadence that runs discovery cold". That cadence has not produced a green verdict since 2026-08-03 — eight days. Its cold-corpus component currently reports verified=false / BudgetExceeded on a component that ran all 8,600 witnesses in its usual 63.7 min (the failure mode is mislabelled; the underlying diagnostic is 12 ordinary witness reds). Receipts: runs 31450909331 and 31460888571, floor-component-receipt artifact, affected_set_cold_control.

Citing it as the compensating control would be resting this change on an instrument that is currently dark. The ordinary floor is the real backstop, and it is sufficient for the per-PR claim.

— sent from eager-cat-841

…iew 51099)

review 51099 (cursor/composer-2.5, REQUEST_CHANGES) correctly caught that #8140
changed documented CI behavior without updating its authority. DESIGN.md
Building & checks stated the opposite of the new code:

  "the executor runs the zero-enrollment naming walk when no discovery batch
   is scheduled"

That clause is superseded here in gunbc.design_document (DESIGN.md is generated
from it; the heal job regenerates the projection).

Both of the reviewer's findings are recorded rather than only the first:

(a) SCOPE — discovery-free plans no longer run the corpus-wide nameability
    rules. Declared as a narrowing, with the honest coverage argument: every PR
    runs the `ci` job, whose plan schedules discovery and walks the full tree,
    so per-PR coverage is unchanged; what is deleted is a second redundant walk
    on regen-only and plan-artifact-only runs. Explicitly NOT backstopped by the
    affected-set falsifier, which has produced no green verdict since
    2026-08-03.

(b) ORDERING — for plans that DO schedule discovery the walk now runs after
    plan resolve/eval, so a naming violation pays ~0.5 min of plan resolution
    before refusing. The reviewer asked whether the trade is intentional: it is,
    and it is priced — ~0.5 min later on the refusing path against ~6 min saved
    on every regen.

A dissolve-on is recorded: the clause, the separate walk, and the `__`-basename
rule all retire when the placement rules move to canonical source ingestion and
test identities derive from parser-produced declarations.

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

gunbai-bot Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor Author

Both findings from review 51099 verified against the code and addressed in ff43f42.

Finding 1 — documented behavior drift. Correct, and blocking. Fixed.

DESIGN.md Building & checks did say the opposite of the new code (the executor runs the zero-enrollment naming walk when no discovery batch is scheduled), and the diff did not touch the authority. That is the §3 violation as described. The clause is now superseded in gunbc.design_document — the .dag authority, not the generated DESIGN.md, which the heal job regenerates.

The reviewer's characterization is also right on the substance and I've written it that way rather than softening it: these are corpus-wide nameability rules, not roster enrollment rules, so skipping them on discovery-free paths is a policy change. It is recorded as a declared narrowing with the honest coverage argument — every PR runs the ci job, whose plan schedules discovery and walks the full tree at unchanged scope, so per-PR coverage is unchanged; what is deleted is a second redundant walk on regen-only and plan-artifact-only runs. The note also states explicitly that this is not backstopped by the affected-set falsifier, which has produced no green verdict since 2026-08-03.

Finding 2 — ordering trade for discovery plans. Correct, intentional, now priced in the note.

Confirmed: batches are known only after plan resolve/eval, so a naming violation on the floor path pays ~0.5 min of plan resolution before refusing, reversing the original "cheapest possible failure" ordering. The trade is stated in the design note with both sides of the number: ~0.5 min later on the refusing path, against ~6 min saved on every regen.

A dissolve-on is recorded with it — the clause, the separate walk, and the __-basename rule all retire when the placement rules move to canonical source ingestion and test identities derive from parser-produced declarations rather than a line scan.

— sent from eager-cat-841

gunbc-ci-auto-heal and others added 3 commits August 11, 2026 11:40
…51101)

review 51101 (cursor/composer-2.5) caught claim_executor.rs:10283 still
asserting "The walk still runs before plan evaluation, so a naming violation
stays the cheapest failure" — the exact opposite of what this PR does.

Non-blocking as a defect, but it is the same class the PR itself is about: a
comment standing as authority for behavior the code no longer has. #8140's
own receipt was a block comment whose stated premise had been false for
months.

The paragraph's real subject — install output policy BEFORE the walk so the
whole-tree read is funnelled rather than emitting ~2.3k `[file] read` lines —
is unchanged and still correct; the walk simply moved further away from it.
Rewritten to say that, rather than deleted, so the ordering requirement keeps
its rationale.

Swept the rest of claim_executor.rs / cli_run.rs for other assertions of the
old ordering: the only remaining hits are this PR's own comment describing the
prior behavior in the past tense.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018ZrxLJrt8ASGLegiK72fAi
@briansrls
briansrls merged commit c24129a into main Aug 11, 2026
5 checks passed
@briansrls
briansrls deleted the session/eager-cat-841 branch August 11, 2026 17:03
gunbai-bot Bot pushed a commit that referenced this pull request Aug 11, 2026
…ement

Review 51113 (cursor/composer-2.5) found two second authorities still claiming
enforcement the code no longer performs — DESIGN §3 dual representation and §4b
rung honesty. Both confirmed against the current head, both fixed.

`gunbc.plans.construction_justification_rule` said the presence check "run[s] in
`discover_floor_corpus_rows`" and listed it as current status. Its retirement
condition also named that check as its trigger, so after the deletion the
condition could never fire — an unreachable lifecycle claim that structurally
cannot report itself satisfied. The plan now leads with a supersession notice,
§2/§3/§4 are marked historical rather than reworded, and a new §5 records what
was deleted, what it costs (a lens added tomorrow with no justification lands
green; the 35-module classification in §4 is a historical measurement, not a
maintained invariant), and the next-rung trigger. The retirement condition is
replaced with a reachable one and says why.

`floor_discovery_snapshot.rs`'s consumer census still listed the two gates and
still called the roster walk "pre-plan", which #8140 already made false.

Swept the rest rather than fixing only what was reported: eight comments in
`cli_run.rs` and one in `claim_executor.rs` named the inert-lens reach as a live
consumer of the observation rows, the reference-edge producer, and the selection
tier. Repointed to the consumers that remain.

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

`is_top_level_lens_module` survived the census deletion with no remaining
caller — only its own definition. It compiled clean because the crate carries a
blanket allow, which is exactly why the residue needed finding by reading rather
than by warning. Deleted; the PR's bar is end-to-end with zero residue, and a
dead classifier left behind is the pattern this change exists to close.

The new DESIGN paragraph asserted the censuses charged "every discovery run — on
every PR, on regen, in every coordinated worker". True before #8140, false on
this PR's base: #8140 made the roster walk demand-directed, so a discovery-free
plan such as regen already stopped paying. Both DESIGN and the plan carrier now
split the claim by era — unconditional before #8140, regen exempt after it, the
censuses burdening every remaining discovery-bearing execution until this
deletion. A change removing stale supply-side enforcement must not land a fresh
stale assertion in the same diff.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018ZrxLJrt8ASGLegiK72fAi
briansrls pushed a commit that referenced this pull request Aug 12, 2026
* Make the witness-roster walk demand-directed instead of unconditional pre-plan

claim_executor ran discover_floor_witness_roster_with_snapshot once up front,
BEFORE resolving the plan, on the stated ground that a naming violation should
be "the cheapest possible failure". Measured, that walk is the most expensive
phase in the process: 5.9 min of a 56.5-min ordinary floor (run 31477894666),
and ~6 min of a ~15-min regen whose plan has exactly two nodes.

It is expensive because "naming hygiene" is a misleading label. The four rules
in v2.workflow.floor_naming_hygiene are string predicates over file paths and
line prefixes, but the roster producer they are reached through also builds
module-graph facts, runs a second strict reference-resolution pass, computes
path indexes, and runs inert-lens reachability plus the construction-
justification census. A two-node regen plan paid all of it to discover a roster
it never reads.

Hygiene is a property of the witness ROSTER, so it is now paid by the plans that
have one: the walk moves to the existing `schedules_discovery` predicate, after
the plan's batches settle. The roster is memoized by request digest
(IN_PROCESS_ROSTER_BY_REQUEST), so plans that DO schedule discovery pay exactly
what they paid before — the corpus batch hits the memo this call fills. Plans
that do not schedule discovery pay nothing, and cannot be unhygienic: they have
no roster.

The walk-attempt id is minted unconditionally as before; it is a tracing
coordinate every later phase stamps, and it is not the expensive part.

This also closes the PRELUDE COVERAGE HOLE gunbc.ci_spec
gunbc_ci_floor_batch_wall_budget_note already names: the walk sat outside every
batch budget and could only red at the step cap. It is now inside the region the
plan accounts for, or absent.

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

* Update the design authority for the demand-directed hygiene walk (review 51099)

review 51099 (cursor/composer-2.5, REQUEST_CHANGES) correctly caught that #8140
changed documented CI behavior without updating its authority. DESIGN.md
Building & checks stated the opposite of the new code:

  "the executor runs the zero-enrollment naming walk when no discovery batch
   is scheduled"

That clause is superseded here in gunbc.design_document (DESIGN.md is generated
from it; the heal job regenerates the projection).

Both of the reviewer's findings are recorded rather than only the first:

(a) SCOPE — discovery-free plans no longer run the corpus-wide nameability
    rules. Declared as a narrowing, with the honest coverage argument: every PR
    runs the `ci` job, whose plan schedules discovery and walks the full tree,
    so per-PR coverage is unchanged; what is deleted is a second redundant walk
    on regen-only and plan-artifact-only runs. Explicitly NOT backstopped by the
    affected-set falsifier, which has produced no green verdict since
    2026-08-03.

(b) ORDERING — for plans that DO schedule discovery the walk now runs after
    plan resolve/eval, so a naming violation pays ~0.5 min of plan resolution
    before refusing. The reviewer asked whether the trade is intentional: it is,
    and it is priced — ~0.5 min later on the refusing path against ~6 min saved
    on every regen.

A dissolve-on is recorded: the clause, the separate walk, and the `__`-basename
rule all retire when the placement rules move to canonical source ingestion and
test identities derive from parser-produced declarations.

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

* chore: regenerate drifted generated artifacts (ci auto-heal)

* Repair the stale output-policy comment left by the walk move (review 51101)

review 51101 (cursor/composer-2.5) caught claim_executor.rs:10283 still
asserting "The walk still runs before plan evaluation, so a naming violation
stays the cheapest failure" — the exact opposite of what this PR does.

Non-blocking as a defect, but it is the same class the PR itself is about: a
comment standing as authority for behavior the code no longer has. #8140's
own receipt was a block comment whose stated premise had been false for
months.

The paragraph's real subject — install output policy BEFORE the walk so the
whole-tree read is funnelled rather than emitting ~2.3k `[file] read` lines —
is unchanged and still correct; the walk simply moved further away from it.
Rewritten to say that, rather than deleted, so the ordering requirement keeps
its rationale.

Swept the rest of claim_executor.rs / cli_run.rs for other assertions of the
old ordering: the only remaining hits are this PR's own comment describing the
prior behavior in the past tense.

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

* Delete supply-side lens enforcement from floor discovery

Two censuses ran inside `discover_floor_witness_roster` — the inert-lens
reach walk and the construction-justification census. Both asked a question
about who authored a lens, and both answered it by acquiring a whole-corpus
module graph. Every discovery run paid that: every PR, regen, and every
coordinated scoped worker, all of which wanted a witness roster and nothing
else. The unit of computation was the world; the unit of fact was one
module's authorship.

Deleted end-to-end, not merely unwired:

- `v2.lens.inert_lens` (its `.dag` surface was two self-recursive stubs,
  `fn f() { f() }`, reachable only because the interpreter intercepted them)
- its two host builtins, both interpreter dispatch registrations, the
  generated bridge family, the `04_method` type-table entries and the
  `std.primitives` roster rows
- the `InertLens` registry variant, its registry row, contract row and
  `lens_module_gate` invariant surface
- `inert_lens_modules`, `inert_lens_modules_legacy`, `lens_justification_census`,
  `unjustified_lens_modules`, `declares_construction_justification` and both
  floor refusal arms (`cli_run.rs` and `floor_discovery_snapshot.rs`)
- the long witness and its frozen deferral row (shrink logged)

`build_module_graph_facts_live` still runs on this path and this change does
not claim otherwise: effect-reach derivation and the cross-worker snapshot
transport both consume it. `refuse_on_module_graph_read_refusals` and its two
red controls are retained and re-homed, since the fail-closed arm now guards
those consumers rather than the deleted censuses.

This is a scope narrowing, not a climb. A new lens with no witness, and a lens
recording no `construction_justification`, are both writable again and nothing
detects either. Declared in DESIGN §6 with its next-rung trigger: authorship
belongs on the module's own declaration, checked where the module is already
parsed, rather than reconstructed corpus-wide by a consumer that wanted a
roster.

Two citations repaired rather than left stale (§3): the roadmap acceptance note
cited a shadow witness this change renames and weakens, and `source_authority`
cited the inert-lens stubs as its example of host interception.

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

* chore: regenerate drifted generated artifacts (ci auto-heal)

* Reconcile the plan carrier and stale comments with the deleted enforcement

Review 51113 (cursor/composer-2.5) found two second authorities still claiming
enforcement the code no longer performs — DESIGN §3 dual representation and §4b
rung honesty. Both confirmed against the current head, both fixed.

`gunbc.plans.construction_justification_rule` said the presence check "run[s] in
`discover_floor_corpus_rows`" and listed it as current status. Its retirement
condition also named that check as its trigger, so after the deletion the
condition could never fire — an unreachable lifecycle claim that structurally
cannot report itself satisfied. The plan now leads with a supersession notice,
§2/§3/§4 are marked historical rather than reworded, and a new §5 records what
was deleted, what it costs (a lens added tomorrow with no justification lands
green; the 35-module classification in §4 is a historical measurement, not a
maintained invariant), and the next-rung trigger. The retirement condition is
replaced with a reachable one and says why.

`floor_discovery_snapshot.rs`'s consumer census still listed the two gates and
still called the roster walk "pre-plan", which #8140 already made false.

Swept the rest rather than fixing only what was reported: eight comments in
`cli_run.rs` and one in `claim_executor.rs` named the inert-lens reach as a live
consumer of the observation rows, the reference-edge producer, and the selection
tier. Repointed to the consumers that remain.

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

* Delete the dead lens classifier and date-scope the cost claim

Two bounded review corrections.

`is_top_level_lens_module` survived the census deletion with no remaining
caller — only its own definition. It compiled clean because the crate carries a
blanket allow, which is exactly why the residue needed finding by reading rather
than by warning. Deleted; the PR's bar is end-to-end with zero residue, and a
dead classifier left behind is the pattern this change exists to close.

The new DESIGN paragraph asserted the censuses charged "every discovery run — on
every PR, on regen, in every coordinated worker". True before #8140, false on
this PR's base: #8140 made the roster walk demand-directed, so a discovery-free
plan such as regen already stopped paying. Both DESIGN and the plan carrier now
split the claim by era — unconditional before #8140, regen exempt after it, the
censuses burdening every remaining discovery-bearing execution until this
deletion. A change removing stale supply-side enforcement must not land a fresh
stale assertion in the same diff.

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

* chore: regenerate drifted generated artifacts (ci auto-heal)

* Repoint the sibling plan authorities that still advertise the deleted census

Review 51154 caught a consistency failure in my own work: I applied the
stale-authority fix to `construction_justification_rule.dag` and then judged
`inert_layer_lens.dag` "historical prose" without running the same test on it.
It fails that test. It is a registered plan whose §3 tells a future worker that
Tier 1 is "buildable now (reuse #5433)" and to extend `inert_lens_modules` —
a function this PR deletes — and §7 goes further, advising them to extend it
behind a flag rather than fork it. Someone following that plan would go looking
for machinery that is gone.

Four rows repointed rather than deleted, since the design reasoning survives
even though its cited mechanism does not:

- §3 Tier 1 now leads with the supersession, names `v2.lens.module_graph` as the
  surviving reachability authority, and says plainly that "reuse the existing
  walk" now means "build the walk", which is a larger job than the paragraph
  reads.
- §6's reuse map repoints the transitive-reachability-BFS row off
  `cli_run.rs:2558-2606` — a positional citation into a file that has since
  moved several thousand lines, which is the §3 rot mode exactly.
- §7's seed caveat drops the extend-behind-a-flag advice and states the real
  constraint: whatever Tier 1 becomes must not reintroduce a corpus-wide walk
  inside floor discovery, because the placement was the defect, not the walk.
- §5's "fail closed exactly as #5433 does" moves to past tense; no lens-inertness
  gate runs today.

Also marked the two remaining historical citations, in the same plan's landed
doc-graph receipt and in `axiom_syllogism_lens.dag`'s precedent table, so every
surviving mention of a deleted symbol carries its deletion beside it.

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

* chore: regenerate drifted generated artifacts (ci auto-heal)

* Derive the bridge-family split control instead of pinning its population

The floor finally evaluated this branch — main was red before, then an upstream
timeout cascaded — and found exactly one red witness in 8757:
`v1_interpreter_primitive_dispatch_authority_acceptance_contract_holds`.

It is genuinely this PR's. Deleting `v2.lens.inert_lens` removed the last two
rows carrying `EvalCallBridgeFamilySite { module: v2.lens.inert_lens }`, so the
distinct bridge-family count went 9 -> 8 and

    distinct_bridge_family_site_count() == 9

redded. The literal was a population pin — the exact class DESIGN §5 rejects,
and the exact class #7615 removed from this same carrier's census witnesses.
The file's own `closing_contract_note` opens by claiming "The checks here are
structural properties that survive roster growth -- not population pins", so
the clause contradicted its own contract and my deletion is what surfaced it.

Decrementing 9 to 8 would restore green while preserving the defect, so the
control is derived instead: the number of distinct emit-site keys must equal the
number of distinct modules the bridge rows themselves name, and exceed one.

That is not a tautology, because the two sides come from different places — the
left from `dispatch_emit_site_key`'s keying, the right from each row's own
`module` field. Collapsing the families back onto one shared key (the defect the
clause is named for) reds it, 1 != N. Adding or removing a family does not.
The clause now measures what its name claims, in both directions.

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

---------

Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: gunbai-bot[bot] <289086189+gunbai-bot[bot]@users.noreply.github.com>
briansrls pushed a commit that referenced this pull request Aug 12, 2026
… discovery (#8167)

* Make the witness-roster walk demand-directed instead of unconditional pre-plan

claim_executor ran discover_floor_witness_roster_with_snapshot once up front,
BEFORE resolving the plan, on the stated ground that a naming violation should
be "the cheapest possible failure". Measured, that walk is the most expensive
phase in the process: 5.9 min of a 56.5-min ordinary floor (run 31477894666),
and ~6 min of a ~15-min regen whose plan has exactly two nodes.

It is expensive because "naming hygiene" is a misleading label. The four rules
in v2.workflow.floor_naming_hygiene are string predicates over file paths and
line prefixes, but the roster producer they are reached through also builds
module-graph facts, runs a second strict reference-resolution pass, computes
path indexes, and runs inert-lens reachability plus the construction-
justification census. A two-node regen plan paid all of it to discover a roster
it never reads.

Hygiene is a property of the witness ROSTER, so it is now paid by the plans that
have one: the walk moves to the existing `schedules_discovery` predicate, after
the plan's batches settle. The roster is memoized by request digest
(IN_PROCESS_ROSTER_BY_REQUEST), so plans that DO schedule discovery pay exactly
what they paid before — the corpus batch hits the memo this call fills. Plans
that do not schedule discovery pay nothing, and cannot be unhygienic: they have
no roster.

The walk-attempt id is minted unconditionally as before; it is a tracing
coordinate every later phase stamps, and it is not the expensive part.

This also closes the PRELUDE COVERAGE HOLE gunbc.ci_spec
gunbc_ci_floor_batch_wall_budget_note already names: the walk sat outside every
batch budget and could only red at the step cap. It is now inside the region the
plan accounts for, or absent.

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

* Update the design authority for the demand-directed hygiene walk (review 51099)

review 51099 (cursor/composer-2.5, REQUEST_CHANGES) correctly caught that #8140
changed documented CI behavior without updating its authority. DESIGN.md
Building & checks stated the opposite of the new code:

  "the executor runs the zero-enrollment naming walk when no discovery batch
   is scheduled"

That clause is superseded here in gunbc.design_document (DESIGN.md is generated
from it; the heal job regenerates the projection).

Both of the reviewer's findings are recorded rather than only the first:

(a) SCOPE — discovery-free plans no longer run the corpus-wide nameability
    rules. Declared as a narrowing, with the honest coverage argument: every PR
    runs the `ci` job, whose plan schedules discovery and walks the full tree,
    so per-PR coverage is unchanged; what is deleted is a second redundant walk
    on regen-only and plan-artifact-only runs. Explicitly NOT backstopped by the
    affected-set falsifier, which has produced no green verdict since
    2026-08-03.

(b) ORDERING — for plans that DO schedule discovery the walk now runs after
    plan resolve/eval, so a naming violation pays ~0.5 min of plan resolution
    before refusing. The reviewer asked whether the trade is intentional: it is,
    and it is priced — ~0.5 min later on the refusing path against ~6 min saved
    on every regen.

A dissolve-on is recorded: the clause, the separate walk, and the `__`-basename
rule all retire when the placement rules move to canonical source ingestion and
test identities derive from parser-produced declarations.

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

* chore: regenerate drifted generated artifacts (ci auto-heal)

* Repair the stale output-policy comment left by the walk move (review 51101)

review 51101 (cursor/composer-2.5) caught claim_executor.rs:10283 still
asserting "The walk still runs before plan evaluation, so a naming violation
stays the cheapest failure" — the exact opposite of what this PR does.

Non-blocking as a defect, but it is the same class the PR itself is about: a
comment standing as authority for behavior the code no longer has. #8140's
own receipt was a block comment whose stated premise had been false for
months.

The paragraph's real subject — install output policy BEFORE the walk so the
whole-tree read is funnelled rather than emitting ~2.3k `[file] read` lines —
is unchanged and still correct; the walk simply moved further away from it.
Rewritten to say that, rather than deleted, so the ordering requirement keeps
its rationale.

Swept the rest of claim_executor.rs / cli_run.rs for other assertions of the
old ordering: the only remaining hits are this PR's own comment describing the
prior behavior in the past tense.

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

* Delete supply-side lens enforcement from floor discovery

Two censuses ran inside `discover_floor_witness_roster` — the inert-lens
reach walk and the construction-justification census. Both asked a question
about who authored a lens, and both answered it by acquiring a whole-corpus
module graph. Every discovery run paid that: every PR, regen, and every
coordinated scoped worker, all of which wanted a witness roster and nothing
else. The unit of computation was the world; the unit of fact was one
module's authorship.

Deleted end-to-end, not merely unwired:

- `v2.lens.inert_lens` (its `.dag` surface was two self-recursive stubs,
  `fn f() { f() }`, reachable only because the interpreter intercepted them)
- its two host builtins, both interpreter dispatch registrations, the
  generated bridge family, the `04_method` type-table entries and the
  `std.primitives` roster rows
- the `InertLens` registry variant, its registry row, contract row and
  `lens_module_gate` invariant surface
- `inert_lens_modules`, `inert_lens_modules_legacy`, `lens_justification_census`,
  `unjustified_lens_modules`, `declares_construction_justification` and both
  floor refusal arms (`cli_run.rs` and `floor_discovery_snapshot.rs`)
- the long witness and its frozen deferral row (shrink logged)

`build_module_graph_facts_live` still runs on this path and this change does
not claim otherwise: effect-reach derivation and the cross-worker snapshot
transport both consume it. `refuse_on_module_graph_read_refusals` and its two
red controls are retained and re-homed, since the fail-closed arm now guards
those consumers rather than the deleted censuses.

This is a scope narrowing, not a climb. A new lens with no witness, and a lens
recording no `construction_justification`, are both writable again and nothing
detects either. Declared in DESIGN §6 with its next-rung trigger: authorship
belongs on the module's own declaration, checked where the module is already
parsed, rather than reconstructed corpus-wide by a consumer that wanted a
roster.

Two citations repaired rather than left stale (§3): the roadmap acceptance note
cited a shadow witness this change renames and weakens, and `source_authority`
cited the inert-lens stubs as its example of host interception.

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

* chore: regenerate drifted generated artifacts (ci auto-heal)

* Reconcile the plan carrier and stale comments with the deleted enforcement

Review 51113 (cursor/composer-2.5) found two second authorities still claiming
enforcement the code no longer performs — DESIGN §3 dual representation and §4b
rung honesty. Both confirmed against the current head, both fixed.

`gunbc.plans.construction_justification_rule` said the presence check "run[s] in
`discover_floor_corpus_rows`" and listed it as current status. Its retirement
condition also named that check as its trigger, so after the deletion the
condition could never fire — an unreachable lifecycle claim that structurally
cannot report itself satisfied. The plan now leads with a supersession notice,
§2/§3/§4 are marked historical rather than reworded, and a new §5 records what
was deleted, what it costs (a lens added tomorrow with no justification lands
green; the 35-module classification in §4 is a historical measurement, not a
maintained invariant), and the next-rung trigger. The retirement condition is
replaced with a reachable one and says why.

`floor_discovery_snapshot.rs`'s consumer census still listed the two gates and
still called the roster walk "pre-plan", which #8140 already made false.

Swept the rest rather than fixing only what was reported: eight comments in
`cli_run.rs` and one in `claim_executor.rs` named the inert-lens reach as a live
consumer of the observation rows, the reference-edge producer, and the selection
tier. Repointed to the consumers that remain.

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

* Delete the dead lens classifier and date-scope the cost claim

Two bounded review corrections.

`is_top_level_lens_module` survived the census deletion with no remaining
caller — only its own definition. It compiled clean because the crate carries a
blanket allow, which is exactly why the residue needed finding by reading rather
than by warning. Deleted; the PR's bar is end-to-end with zero residue, and a
dead classifier left behind is the pattern this change exists to close.

The new DESIGN paragraph asserted the censuses charged "every discovery run — on
every PR, on regen, in every coordinated worker". True before #8140, false on
this PR's base: #8140 made the roster walk demand-directed, so a discovery-free
plan such as regen already stopped paying. Both DESIGN and the plan carrier now
split the claim by era — unconditional before #8140, regen exempt after it, the
censuses burdening every remaining discovery-bearing execution until this
deletion. A change removing stale supply-side enforcement must not land a fresh
stale assertion in the same diff.

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

* chore: regenerate drifted generated artifacts (ci auto-heal)

* Repoint the sibling plan authorities that still advertise the deleted census

Review 51154 caught a consistency failure in my own work: I applied the
stale-authority fix to `construction_justification_rule.dag` and then judged
`inert_layer_lens.dag` "historical prose" without running the same test on it.
It fails that test. It is a registered plan whose §3 tells a future worker that
Tier 1 is "buildable now (reuse #5433)" and to extend `inert_lens_modules` —
a function this PR deletes — and §7 goes further, advising them to extend it
behind a flag rather than fork it. Someone following that plan would go looking
for machinery that is gone.

Four rows repointed rather than deleted, since the design reasoning survives
even though its cited mechanism does not:

- §3 Tier 1 now leads with the supersession, names `v2.lens.module_graph` as the
  surviving reachability authority, and says plainly that "reuse the existing
  walk" now means "build the walk", which is a larger job than the paragraph
  reads.
- §6's reuse map repoints the transitive-reachability-BFS row off
  `cli_run.rs:2558-2606` — a positional citation into a file that has since
  moved several thousand lines, which is the §3 rot mode exactly.
- §7's seed caveat drops the extend-behind-a-flag advice and states the real
  constraint: whatever Tier 1 becomes must not reintroduce a corpus-wide walk
  inside floor discovery, because the placement was the defect, not the walk.
- §5's "fail closed exactly as #5433 does" moves to past tense; no lens-inertness
  gate runs today.

Also marked the two remaining historical citations, in the same plan's landed
doc-graph receipt and in `axiom_syllogism_lens.dag`'s precedent table, so every
surviving mention of a deleted symbol carries its deletion beside it.

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

* chore: regenerate drifted generated artifacts (ci auto-heal)

* Derive the bridge-family split control instead of pinning its population

The floor finally evaluated this branch — main was red before, then an upstream
timeout cascaded — and found exactly one red witness in 8757:
`v1_interpreter_primitive_dispatch_authority_acceptance_contract_holds`.

It is genuinely this PR's. Deleting `v2.lens.inert_lens` removed the last two
rows carrying `EvalCallBridgeFamilySite { module: v2.lens.inert_lens }`, so the
distinct bridge-family count went 9 -> 8 and

    distinct_bridge_family_site_count() == 9

redded. The literal was a population pin — the exact class DESIGN §5 rejects,
and the exact class #7615 removed from this same carrier's census witnesses.
The file's own `closing_contract_note` opens by claiming "The checks here are
structural properties that survive roster growth -- not population pins", so
the clause contradicted its own contract and my deletion is what surfaced it.

Decrementing 9 to 8 would restore green while preserving the defect, so the
control is derived instead: the number of distinct emit-site keys must equal the
number of distinct modules the bridge rows themselves name, and exceed one.

That is not a tautology, because the two sides come from different places — the
left from `dispatch_emit_site_key`'s keying, the right from each row's own
`module` field. Collapsing the families back onto one shared key (the defect the
clause is named for) reds it, 1 != N. Adding or removing a family does not.
The clause now measures what its name claims, in both directions.

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

* Delete the orphan-helper census and the `__` filename rule from floor discovery

Two more required-path phases whose cost was denominated in the corpus and
whose answer nobody consumed. Net −1446/+39.

**The `__`-basename rule.** A census found ZERO offending basenames in the tree
and no stated rationale anywhere for the ban — it guarded an empty population.
It was not free: reaching the predicate meant collecting every `.dag` path in
the corpus and then resolving a SEPARATE `.dag` entry
(`FLOOR_NAMING_HYGIENE_ENTRY` -> `floor_filename_hygiene_refusal_via_producer`)
on every discovery-bearing run, so a zero-population style rule cost a whole-tree
walk plus an entry resolve. Both are gone, along with the snapshot's
`naming_hygiene_refusal` field and the two witness controls.

**The orphan-helper census.** It walked every `*_test.dag`, parsed each one,
projected `DeclSurface`/`ModuleSurface` values, resolved a second interpreter
context, and ran a fuelled reachability fixpoint against a hand-authored
cross-module export exception roster — to decide whether a plain helper in a
test file was referenced. An unreferenced test helper is dead-code hygiene. It
is not evidence that the compiler or the tests are correct, and it did not
justify a recurring whole-corpus traversal on a required path.
`gunbc.test_module_hygiene` goes 661 -> 106 lines, the Rust bridge 835 -> ~320,
and `test_module_hygiene_scaffold.dag` deletes whole (its dissolution obligation
is discharged by the deletion, not carried forward).

**Scope narrowing, declared rather than implied.** An unreferenced test helper
and a `__` basename are both writable again and nothing detects either. The
orphan class had fourteen enrolled witnesses and they are deleted with it —
§4b permits that only because the class is ABANDONED, not climbing: there is no
higher rung for the evidence to guard, and keeping fixtures for a fold nothing
calls would be specification-without-execution one level up. Recorded in DESIGN,
in the module authority note, and in the witness file that used to hold them.

**What survives, and why:** the `test fn` placement rule, the file-grain expand
half, and `failure_receipt_companion` — the naming convention `claim_executor`
actually invokes. That last one was only ever exercised through the census's
whole-corpus walk, so it would have silently lost its executing consumer; it
gains direct unit and `.dag` witnesses here instead.

**Not in scope, deliberately:** the line-scanned test-identity derivation. That
is the second parser, and replacing it needs the canonical parser to retain the
`test` marker — which `drop_leading_test_marker` discards, because `test` is a
live module-path segment (`test.claim.*`, `extdeps.test.*`) and cannot be lexed
as a keyword. `realization_attempt.dag` already names the prerequisite: a
contextual-keyword terminal in `GrammarExpr`, which does not exist yet.

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

* Refresh the two authority notes the deletion falsified

Review 51262 found `floor_naming_hygiene_note` still asserting, in a file this
PR edits, that the module sits where it does so "orphan/filename hygiene resolve
stays free of the Filesystem service closure" and that it dissolves the hand-Rust
mirror `check_floor_filename_hygiene`. Neither survives the deletion: there is no
orphan census and no filename-hygiene resolve left to keep free of anything, and
the filename half of that dissolution obligation is discharged by deletion rather
than by dissolution — no equivalence receipt was ever owed for a rule with a
zero-row population.

The note now states what remains true instead, including the part worth carrying:
the test-decl line scan is still a second parser, and replacing it is not a
refactor of this module — it needs the canonical parser to retain the `test`
marker, which `drop_leading_test_marker` discards, and `test` cannot become a lex
keyword because it is a live module-path segment.

Swept for the same class rather than fixing only what was reported:
`floor_discovery_dissolve_trigger` still described "the producer and
filename-hygiene entries" as two typed entry values resolved through
`resolve_workspace_entry`. There is one now.

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

* chore: regenerate drifted generated artifacts (ci auto-heal)

* Carry the deleted-witness rationale as an authored annotation, not a prose data row

`prose_row_introduction_gate` refused this change: `test_module_hygiene_orphan_witness_deletion_note`
is a `data NAME_note: String` declaration introduced under
`dag/test/claim/test_module_hygiene_hand_rust_equivalence_witness_test.dag`, a path
already on `gunbc.prose_row_frontier` `prose_row_migration_scope`. DESIGN §4c: prose
is not forbidden, unclassified prose is, and a `String` declaration whose sole
purpose is commentary is misplaced data.

The rationale is irreducible — it records why fourteen witnesses were deleted with
the machinery they tested, and why §4b's dissolution-on-climb rule does not save
them (the class is abandoned, not climbed) — so it becomes a leading `//` block
attached to the declaration below it. The PR-number and section references in the
prose are dropped rather than carried across: those are exactly the machine-consumed
facts §4c says belong in a typed carrier, not in commentary.

The two other in-scope rows this change touches (`test_module_hygiene_authority_note`,
`failure_receipt_companion_note`) are pre-existing declaration names whose content was
rewritten, not introductions, and the gate does not refuse them. They are left as
rows rather than swept here.

Green by execution: the edited witness parses and
`test_module_hygiene_file_grain_empty_function_holds` returns `true`.

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

* chore: regenerate drifted generated artifacts (ci auto-heal)

* Make the deleted censuses past tense in the Building & checks paragraph

Review 51377: the paragraph describing the naming-hygiene walk's measured cost
still said the roster producer "runs inert-lens reachability plus the
construction-justification census" — present tense, about two censuses gunbc#8141
deleted. `claim_executor` already says "(until gunbc#8141 deleted them)" and the §6
bullet in this same document records the deletion in past tense, so the canonical
authority contradicted both.

The measurement itself stands: those censuses WERE part of what made the walk the
most expensive phase when it was measured. What was wrong is the tense, which
asserts a superseded population as the present one — and doing that inside a
deletion diff is the exact failure #8141's own review caught, recorded a few
paragraphs above in this file. Reworded to "and — until gunbc#8141 deleted them —
ran", preserving the cost claim as the historical fact it is.

Swept for other occurrences: the §6 bullet is already past tense; this was the only
stale one.

DESIGN.md is a projection of this authority and is regenerated by
`heal_generated_artifacts`, so it is not hand-edited here.

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

* Drop orphan/helpers from the snapshot consumer-census row

Review 51382: the module header still listed "Naming hygiene, orphan/helpers" as
what the demand-directed roster walk reads, in a file this PR edits. The
orphan-helper census and the `__`-basename rule are deleted here, so the row named
work that no longer happens — doc drift inside the diff that removed the subject.

The row now names what the walk actually still does: `test fn` placement hygiene,
producer roster, module-graph facts, effect-reach derivation, with the deletion
noted so a reader is not left wondering where the other two went.

The same review's DESIGN.md finding is real and is NOT fixed by hand: DESIGN.md is a
generated projection of `dag/gunbc/design_document.dag`, whose wording was corrected
in 69009a3. Editing the projection directly would author bytes no authority
produced, and `heal_generated_artifacts` reverts exactly that. Heal last ran against
the previous head (a5b441b, before the authority fix); its run on this head
re-projects the corrected sentence.

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

* chore: regenerate drifted generated artifacts (ci auto-heal)

* Repair the comment whose contrast named a deleted function

Review 51390: a comment justifying why a wiring test calls the producer seam argued
by contrast with `floor_filename_hygiene_refusal_for_paths` — which this PR deletes.
The live half of the argument still holds (the seam is where a wire-contract
violation is observable, and the rule itself is owned content-side by
`floor_discovery_equivalence_misplaced_wire_contract_refuses_holds`, so re-deriving
it here would be a second representation). Only the contrast was dangling.

Rewritten to state the positive reason, with the retired comparison noted as
history rather than silently dropped: a reader who remembers the old sentence
should find out where it went, not wonder whether the argument changed. No code,
assertion, or behavior change.

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

---------

Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: gunbai-bot[bot] <289086189+gunbai-bot[bot]@users.noreply.github.com>
gunbai-bot Bot pushed a commit that referenced this pull request Aug 20, 2026
…easure the parse route

Axis 2 and axis 3 were argued from reading the Rust marshal; they are now proven by execution.
A fixture pair of identical shape folded through fn_arrow_decl_facts_live:
fixture_dead_let_shell (binds the call, does not use it) yields ZERO atoms — callee identity and
program literal both absent — while fixture_live_named_args yields
"fixture_sink2 | echo LIVEMARKER | echo ARGSMARKER". Same construct, opposite verdict, so the
loss is the projection's and not the probe's. The live arm also shows axis 3 directly: three
atoms in authored order with no labels, so nothing says which literal was program: and which was
args:.

Axis 6 is new and was measured, not read. The reflection registry is the ENTRY'S IMPORT CLOSURE,
not the corpus: a fold over fn_arrow_decl_facts_live under both production roots reported 1,698
fn/func declarations against 41,965 declared in the tree, about 4%. This is a declared frontier
rather than a discovery — corpus_dependency_view already refuses per-PR when
fn_arrow_decl_substrate_is_whole_tree is false ("blocked-on-#6239") — but it is fatal for a
census specifically, because files disappear through non-import with no per-file ParseRefused row
to count them. That is the empty-observation narrow: never-loaded is indistinguishable from
carries-no-route.

The full-fidelity parse route is measured against a positive control. The tree's own three-line
fixture ACCEPTS, a real 28-line corpus file ACCEPTS, and dag/extdeps/shell/exec.dag REJECTS with
reason=parse_grammar_choice_overlap_residue. So the route is real and its failure is a located
typed refusal, but the file it refuses declares shell.Exec.Run/RunArgv/Check — the census's most
load-bearing seed file.

Records that accepts-or-refuses was the wrong frame: there is a third outcome, accepts but is
unaffordable at corpus grain, and it is the one the prior cost signal makes likely. Affordability
is being measured as a slope over a random 40-file sample rather than extrapolated from the
fixture, since fixed overhead and per-byte cost are different curves. If it lands there, DESIGN §6
already rejected this shape once in #8140 — "the unit of computation was the world, the unit of
fact was one module's authorship" — and its declared next-rung trigger is exactly axis 1's
remedy: one module's facts from one module's source, checked at ingestion where the module is
parsed anyway.

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

Accepts-or-refuses was the wrong frame; there are three outcomes and the measurement lands on the
third, with a correctness failure alongside it.

CORRECTNESS. On a random 10-file corpus sample the route accepted 6 and refused 4, and ALL FOUR
refusals carry the same reason as the earlier dag/extdeps/shell/exec.dag refusal:
parse_grammar_choice_overlap_residue. The grouping is the finding, not the rate — one grammar
deficiency with many victims rather than scattered file-specific problems. So the route is a
single repair away from a much larger accepted population, and no census can run on it until that
repair lands, because the merge bar is zero production parse refusals and the refusal set contains
the census's own seed file.

AFFORDABILITY, measured as a slope rather than extrapolated. 1 file / 372 B / 63.1 s; 10 files /
5,332 B / 67.5 s; 40 files / 388,527 B / EXIT=137, OOM-killed after 34 files. Marginal cost is
about 0.49 s per file against about 62.6 s of fixed world-acquisition overhead, so TIME IS NOT THE
WALL. Memory is, and it is not about big files: the kill came at file ~34 with only 94 KB of
source consumed, on ~7.8 KB files, with the 212 KB outlier sorted last and never reached. The
fold accumulated only a short result string, so the retention is not the probe's accumulator.
Whether it is parse-tree retention or interpreter heap growth is NOT established here and is not
claimed; what is established is that the process cannot hold 34 small files against a subject of
3,733 files and 31.3 MiB.

Both facts point the same way, and DESIGN §6 already rejected this shape in #8140 — "the unit of
computation was the world, the unit of fact was one module's authorship". Recommends the
ingestion-side projection over a census-side fold, enumerated as the six axes' remedies, with 0A
rebasing onto it. Notes parse_grammar_choice_overlap_residue as worth filing on its own: a named
grammar deficiency refusing a large fraction of authored source in the compiler's own parser,
invisible today because the only path that would surface it has no callers.

Two instrument faults on the way, same root and worth naming: a grep filter discarded every line
of a run, and a missing `bc` silently emptied the timing field while the surrounding output looked
healthy. Both failed toward absence, not toward a wrong number.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QFxNVPeTcYeCjP7rQyLtZu
briansrls pushed a commit that referenced this pull request Aug 20, 2026
… (brief: docs/plans/shell-dag-census-0a-brief.md) (#8662)

* SHELL-DAG-CENSUS-0A: stop condition — file the projection blocker and the derived shell seed

The brief's stop condition fires. No detector was built and no text-scanning census was
substituted; this commit files the finding the brief asks for in that case.

The whole fact surface .dag can read is three accessors in coproduct_reflection.rs — types,
fns/funcs, data inits. ItemKind::ServiceItem has no accessor, so transport declarations are
invisible, and FnArrowDecl.output is a wiring-liveness skeleton whose statement fold DROPS a
let-bound RHS not referenced toward the return. Five axes with five distinct remedies, each with
its own evidence; the gunbc.spark_managed_access_apply chain is a worked proof that all five are
capability gaps rather than API preferences — a match-arm binder, a named argument label, a
service operation and a transport stdin channel, one per axis.

Also files the shell-interpretation seed derived from what interprets bytes as shell, which is
needed under whichever remedy lands. Findings that were not expected: of 17 shell-interpreter
argv literals, 10 sit in product fn bodies as ArgvCommand constructions (one with a computed
program), not in extdeps declarations, so a service-declaration projection alone would miss the
majority; and "--" is overloaded three ways across 46 sites (ssh re-root, systemd-run re-root,
cargo argument pass-through, git end-of-options), so the re-root reading is a per-program extdeps
citation duty and not something the census may infer from the token.

Records one specimen found on the way: v2.compiler.source_authority
canonical_dag_source_parse_print_law has zero callers anywhere in the tree — a parse/print law
that nothing executes, DESIGN §5 specification-without-execution in the compiler's own source
authority — which is why "the full-fidelity parse route exists in .dag" is not evidence that it
works on the real corpus.

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

* SHELL-DAG-CENSUS-0A: add executed evidence for axes 2, 3 and 6, and measure the parse route

Axis 2 and axis 3 were argued from reading the Rust marshal; they are now proven by execution.
A fixture pair of identical shape folded through fn_arrow_decl_facts_live:
fixture_dead_let_shell (binds the call, does not use it) yields ZERO atoms — callee identity and
program literal both absent — while fixture_live_named_args yields
"fixture_sink2 | echo LIVEMARKER | echo ARGSMARKER". Same construct, opposite verdict, so the
loss is the projection's and not the probe's. The live arm also shows axis 3 directly: three
atoms in authored order with no labels, so nothing says which literal was program: and which was
args:.

Axis 6 is new and was measured, not read. The reflection registry is the ENTRY'S IMPORT CLOSURE,
not the corpus: a fold over fn_arrow_decl_facts_live under both production roots reported 1,698
fn/func declarations against 41,965 declared in the tree, about 4%. This is a declared frontier
rather than a discovery — corpus_dependency_view already refuses per-PR when
fn_arrow_decl_substrate_is_whole_tree is false ("blocked-on-#6239") — but it is fatal for a
census specifically, because files disappear through non-import with no per-file ParseRefused row
to count them. That is the empty-observation narrow: never-loaded is indistinguishable from
carries-no-route.

The full-fidelity parse route is measured against a positive control. The tree's own three-line
fixture ACCEPTS, a real 28-line corpus file ACCEPTS, and dag/extdeps/shell/exec.dag REJECTS with
reason=parse_grammar_choice_overlap_residue. So the route is real and its failure is a located
typed refusal, but the file it refuses declares shell.Exec.Run/RunArgv/Check — the census's most
load-bearing seed file.

Records that accepts-or-refuses was the wrong frame: there is a third outcome, accepts but is
unaffordable at corpus grain, and it is the one the prior cost signal makes likely. Affordability
is being measured as a slope over a random 40-file sample rather than extrapolated from the
fixture, since fixed overhead and per-byte cost are different curves. If it lands there, DESIGN §6
already rejected this shape once in #8140 — "the unit of computation was the world, the unit of
fact was one module's authorship" — and its declared next-rung trigger is exactly axis 1's
remedy: one module's facts from one module's source, checked at ingestion where the module is
parsed anyway.

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

* SHELL-DAG-CENSUS-0A: measure the parse route on both axes — it is outcome 3, and it fails correctness too

Accepts-or-refuses was the wrong frame; there are three outcomes and the measurement lands on the
third, with a correctness failure alongside it.

CORRECTNESS. On a random 10-file corpus sample the route accepted 6 and refused 4, and ALL FOUR
refusals carry the same reason as the earlier dag/extdeps/shell/exec.dag refusal:
parse_grammar_choice_overlap_residue. The grouping is the finding, not the rate — one grammar
deficiency with many victims rather than scattered file-specific problems. So the route is a
single repair away from a much larger accepted population, and no census can run on it until that
repair lands, because the merge bar is zero production parse refusals and the refusal set contains
the census's own seed file.

AFFORDABILITY, measured as a slope rather than extrapolated. 1 file / 372 B / 63.1 s; 10 files /
5,332 B / 67.5 s; 40 files / 388,527 B / EXIT=137, OOM-killed after 34 files. Marginal cost is
about 0.49 s per file against about 62.6 s of fixed world-acquisition overhead, so TIME IS NOT THE
WALL. Memory is, and it is not about big files: the kill came at file ~34 with only 94 KB of
source consumed, on ~7.8 KB files, with the 212 KB outlier sorted last and never reached. The
fold accumulated only a short result string, so the retention is not the probe's accumulator.
Whether it is parse-tree retention or interpreter heap growth is NOT established here and is not
claimed; what is established is that the process cannot hold 34 small files against a subject of
3,733 files and 31.3 MiB.

Both facts point the same way, and DESIGN §6 already rejected this shape in #8140 — "the unit of
computation was the world, the unit of fact was one module's authorship". Recommends the
ingestion-side projection over a census-side fold, enumerated as the six axes' remedies, with 0A
rebasing onto it. Notes parse_grammar_choice_overlap_residue as worth filing on its own: a named
grammar deficiency refusing a large fraction of authored source in the compiler's own parser,
invisible today because the only path that would surface it has no callers.

Two instrument faults on the way, same root and worth naming: a grep filter discarded every line
of a run, and a missing `bc` silently emptied the timing field while the surrounding output looked
healthy. Both failed toward absence, not toward a wrong number.

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

* File the projection increment spec and the grammar-deficiency finding

Two specs, no implementation. The increment lands partly in the frozen v1 seed, whose admission
test is purpose — does the change serve the v2 self-host program — and this increment serves a
shell-migration census, so the call is the operator's and no seed work starts on lane authority.

The increment spec is written for someone deciding admission rather than for an implementer. It
leads with the empty-observation narrow rather than the coverage percentage, because that is the
part that makes the substrate unusable rather than merely partial: a file that was never loaded
reads identically to a file carrying no shell route, and no per-file ParseRefused row exists to
count the difference, so a census on it yields a clean confident population that is silently
wrong.

Each of the six axes carries its own evidence grade rather than being presented as uniformly
established — axes 2 and 3 execution-proven by the discriminating fixture pair, axis 6
execution-measured, axis 1 structural and independently verified, axes 4 and 5 read from the
marshal. The counting method is stated beside the axis-6 denominator because it will be
questioned: 41,965 counts line-start fn/func/test fn and matches the accessor's own filter, since
ItemKind has no separate test variant and a test fn IS an FnItem; 30,851 is the same count with
the 11,114 test declarations removed. 1,698 visible is 4.0% or 5.5% and the conclusion is
invariant.

Two properties are separated for the admission call: axes 2-5 are an ADDITIVE second accessor
rather than an edit to the existing marshal, whose lossiness is load-bearing for
v2.lens.wiring_liveness and must not change; and axis 6 is probably already-sanctioned work
pending #6239 rather than anything this increment requests. The admission question is recorded
with both readings and no advocacy.

The grammar finding is filed separately because it outlives the census. Five refusals across two
source roots, four sampled at random plus the independently-found extdeps/shell/exec.dag, all
carrying one reason: parse_grammar_choice_overlap_residue. No corpus rate is claimed from ten
files; the shared cause is the finding. It is invisible because the only path that would surface
it, canonical_dag_source_parse_print_law, has no callers — the unexecuted law and the unmeasured
deficiency are the same fact seen twice.

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

---------

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant