Skip to content

Close the remaining receipt-continuity production bypass: parse merge-base event data, enforce exact append-only prefix, hash every field - #7791

Merged
gunbai-bot[bot] merged 41 commits into
mainfrom
session/valiant-bat-462
Aug 5, 2026
Merged

gunbai-bot[bot] merged 41 commits into
mainfrom
session/valiant-bat-462

Conversation

@gunbai-bot

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

Copy link
Copy Markdown
Contributor

Summary

Closes the receipt-continuity production bypass: merge-base prior history is parsed from dag/gunbc/roadmap_acceptance_event_history.jsonl via git.Core.Show (or typed authority-text bootstrap when the carrier is absent at merge-base), append-only prefix law applies when prior is non-empty, every receipt field flows into acceptance_event_digest v2, and load/projection refusals propagate as typed ...Refused{detail} instead of collapsing to empty lists. Hand-Rust JSONL parsing lives in roadmap_acceptance_history_carrier.rs behind roadmap_acceptance_event_history_jsonl_parser_seed_scaffold (Scaffold → RealizationDispatch).

Operator items (loyal-ram-550)

P0 — self-comparing recorded provider (fixed). Readiness previously grounded healthz by comparing an observed body to roadmap_site_healthz_body(), which re-invoked the same render path — both sides derived from one producer call. Now gunbc.roadmap_site_surface_observe materializes a RoadmapSiteSurfaceBundle once; ground_service_ready_from_healthz_with_bundle(read, bundle) in gunbc.live_deploy.readiness compares the independent HTTP read (HealthzEffectiveRead) against bundle.healthz_body. Fresh-read and stale-read witnesses (roadmap_site_surface_witness.dag) take the bundle as an argument: the healthy fixture uses bundle.healthz_body; the RED control uses a planted body with stale-digest that parses but does not match the bundle.

P0 — authority identity covers the complete projected subject (fixed). Replaced the single authority_identity field with three digests on RoadmapSiteSurfaceBundle (roadmap_site_surface_types.dag, computed in roadmap_site_surface_observe.dag):

  • subject_identity — acceptance snapshot + roadmap.md + dispatch.json bodies (or exact refusal detail when projection refuses)
  • producer_identity — observe/render implementation (gunbc.roadmap_site_surface_observe/v1)
  • bundle_identity — fold of all five served-artifact digests

P1 — typed receipts rather than a Boolean call tree (deferred). Witnesses still compose as roadmap_site_surface_readiness_group_holds() -> Bool with bundle-parameterized member predicates in roadmap_site_surface_expect. The batch witness (witness_roadmap_site_surface_readiness_materialized_batch_holds) ensures one bundle materialization, but HealthzMemberReceipt / per-member typed carriers remain a follow-up.

subject / producer / bundle split — landed as above.

Six-witness timing — partially addressed, measurement deferred. Six separate healthz witnesses were collapsed into roadmap_site_surface_readiness_group_holds() behind one live_roadmap_site_surface_bundle() call (one authority projection + one render pass). Local batch run ~3.4s vs ~20.6s sequential; formal timing enrollment deferred per operator ruling.

Generated workflows — falsifier.yml regenerated after main merge (4109e854, release_bins step id). ci.yml not directly edited by this lane (unchanged except via main merges). v1_interpreter_dispatch_generated.rs regen restored bridge lookups plus two roadmap parser builtin arms.

Main merge (48bb553): merged origin/main at 9ce6526 (#7834); inherited job_id falsifier witness failures cleared at source.

Worker attestation

  • Title describes the change (not the session id or branch).
  • PR body summarises what and why (three operator items addressed by name above).
  • Tests run — see Test plan; CI re-running on 48bb553.
  • If this closes a work item, the body contains a Closes #N directive.
  • No commits on this branch are surprises.
  • No secrets / credentials / large binaries staged.

Test plan

  • roadmap_receipt_continuity_acceptance_contract_holds (dag/test/claim/roadmap_receipt_continuity_acceptance_test.dag) — PASS (17 hermetic sub-witnesses: deleted events, prefix law, empty-prior bypass discriminant, digest-field mutation, revocation while live, git-refusal observation, typed load/projection chain)
  • live_acceptance_history_integrity_holds_on_authority (dag/test/claim/roadmap_receipt_continuity_live_witness_test.dag) — wet corpora batch
  • witness_roadmap_site_surface_readiness_materialized_batch_holds (dag/test/claim/roadmap_site_surface_readiness_witness_test.dag) — PASS
  • roadmap_acceptance_history_carrier Rust unit tests (cargo test -p v1-compiler roadmap_acceptance_history_carrier) — PASS (4 tests incl. unknown_jsonl_field_refuses)
  • CI floor on 48bb553 — pending after main merge

gunbc-ci-auto-heal and others added 2 commits August 4, 2026 15:00
Move acceptance events to dag/gunbc/roadmap_acceptance_event_history.jsonl,
parse HEAD and merge-base carrier revisions independently (no overlay .dag
eval), delete authored seal count/digest, and extend hermetic RED controls
for prefix law without seal co-edit and digest-field mutation.

Co-authored-by: Cursor <cursoragent@cursor.com>
@gunbai-bot
gunbai-bot Bot marked this pull request as ready for review August 4, 2026 15:31
gunbc-ci-auto-heal and others added 8 commits August 4, 2026 15:48
… refusal.

Migrate acceptance history to JSONL with merge-base carrier parse, authority
projection bootstrap when the carrier is absent at base, and
RoadmapAcceptanceReceiptsProjection so LoadRefused never masquerades as an
empty receipt list. Move the JSONL parser under cli_run/ for regen copy.

Co-authored-by: Cursor <cursoragent@cursor.com>
Add AcceptedRoadmapNodesProjection and AcceptedRoadmapNodeIdsProjection
so carrier load refusal no longer masquerades as an empty accepted set
(active frontier, startable checks, and roadmap page now match on Refused).

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

The hermetic witness proves the old authority-changed path admitted deletion
with prior_history = [] while observed non-empty prior refuses, closing the
third operator RED control alongside prefix-law and digest-field mutation.

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

Callers now use accepted_roadmap_node_ids_projection directly; tests fail
closed on ProjectionRefused instead of treating refusal as zero acceptances.

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

acceptance_revocation_disposition_digest recurses over the disposition
variant so future additions cannot collide, and the authority projection
scaffold removes its temp directory when overlay staging fails.

Co-authored-by: Cursor <cursoragent@cursor.com>
The unchanged-carrier branch no longer aliases prior_history to the
working-tree load, so dirty local JSONL edits refuse against the
git-observed committed prior instead of self-matching.

Co-authored-by: Cursor <cursoragent@cursor.com>
gunbc-ci-auto-heal and others added 2 commits August 4, 2026 22:57
…ection.

Rename ForecastRefusal's authority arm to ForecastRoadmapAuthorityRefused so it no longer collides with RoadmapAuthorityProjectionRefused, and evaluate roadmap_site_healthz_body from one projection pass to avoid repeated carrier reads.

Co-authored-by: Cursor <cursoragent@cursor.com>
gunbc-ci-auto-heal and others added 3 commits August 4, 2026 23:49
…itnesses.

The batch witness in roadmap_site_surface_expect now owns those predicates; leaving the plain fn helpers in roadmap_static_site_witness_test.dag tripped witness naming hygiene and blocked regen/CI.

Co-authored-by: Cursor <cursoragent@cursor.com>
gunbc-ci-auto-heal and others added 3 commits August 5, 2026 01:57
Drop the invalid `as expect_healthz_surface_is_current` rename and the
shadowing 1-arg wrapper; keep the bundle delegate and expose the
materializing entry as roadmap_site_healthz_surface_is_current_from_observed_body.

Co-authored-by: Cursor <cursoragent@cursor.com>
gunbai-bot Bot pushed a commit that referenced this pull request Aug 5, 2026
Operator correction 2026-08-05: 5000ms is the executor fail-stop, not a
witness budget; the migration threshold is 500ms, and re-homing a file to
long/ is not a migration unless the operation is inherently external or
whole-system. This note previously cited an "operator 5s fast-lane rule"
as its justification, which read the policy wrongly.

The 11 rows enrolled in the previous commit stay enrolled: the long dir is
excluded from per-PR discovery, so those witnesses previously executed
NOWHERE, and enrolled-and-scheduled dominates unscheduled. Confirmed by
still-bat-561 and loyal-ram-550 independently, the latter citing #7804's
operator-signed note that "ALLOWED TO REMAIN and HAS AN EXECUTING CONSUMER
are different facts". What changes is the claim being made: enrollment is
no longer describable as completed migration.

Records the cost class (expensive graph/load/resolve setup -> acquire the
population once), the measurement that bounds any plan (682 of 930 entries
resolve at 1000ms+, max 11223ms, shared per file -- so splitting a witness
makes one resolve serve more rows, it does not make the entry cheaper),
and the real migration shape (recursive composition, precedent #7791).

The dissolve_on strings on the rows still cite the 5000ms kill cap and are
wrong today. Deliberately not mass re-pointed here: that converts
dissolvable rows into permanent residents with no migration plan behind
them, and belongs to the single change that lands the typed 500ms
threshold (merry-raven-690's lane).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
gunbc-ci-auto-heal and others added 2 commits August 5, 2026 04:03
…d keep roadmap parser arms.

The merge dropped main's v1_interpreter_dispatch_generated bridge lookup tables while retaining new interpreter bridge calls, breaking the rustc compile gate. Restore origin/main's generated file and re-add only this PR's two roadmap JSONL/authority-text builtin arms.

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

gunbai-bot Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor Author

Hermetic receipt-continuity fix (option 3)

Per loyal-ram-550: hermetic witnesses no longer call Filesystem.Read. They hand carrier text to load_roadmap_acceptance_event_history_from_carrier_text / roadmap_*_from_carrier_text and assert on specific parse-refusal details (line 1:), not generic hermetic refusal. Reverted the wet-split for witness_missing_head_carrier_path_read_refuses (blocked by #7804 witness-admission freeze).

Also fixed post-merge rustc break: restored v1_interpreter_dispatch_generated.rs bridge lookups from main and kept this PR's two roadmap parser arms (59a66bfb2b5).

Local hermetic: roadmap_receipt_continuity_acceptance_contract_holds PASS.

Surface-readiness witness timings (host measurement, hermetic claim_batch eval wall)

Before (six independent witnesses, parent b491a03, each re-materializes surface):

Witness ms
witness_fresh_surface_read_grounds 3423
witness_stale_surface_read_does_not_ground 3607
witness_healthz_surface_tolerates_transport_trailing_lf 3215
witness_healthz_publishes_every_served_surface_digest 3449
witness_reconcile_grounds_healthy_fixture_read 3525
witness_service_ready_once_converges_on_healthy_fixture 3415
Sequential sum 20634

After (one batch, witness_roadmap_site_surface_readiness_materialized_batch_holds, HEAD): 3358 ms (single live_roadmap_site_surface_bundle())

Still above the 500 ms immediate-migration bar and 1 s target per loyal-ram-550, but ~6× faster than the prior sequential six-materialize pattern on this host.

— sent from valiant-bat-462

…led-compat scaffold.

Route active roadmap rendering through roadmap_authority_projection; remove narrow
active_* wrappers; separate subject/producer/bundle identities; add sealed-compat
dissolution trigger and prior-prefix mismatch index; serde-tag revocation disposition.

Co-authored-by: Cursor <cursoragent@cursor.com>
gunbc-ci-auto-heal and others added 4 commits August 5, 2026 11:57
Add bin_wet row for live_roadmap_acceptance_history_integrity_failure_receipt
alongside the renamed holds witness so Phase 0(b) witness admission stops
refusing the new companion function.

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

Authority delegation to gunbc.test_module_hygiene now logs resolve/call refusals and degrades to no companion so claim_executor cannot abort on hygiene load failure; documents that the JSONL seed bridge bypasses the digest refinement at Value construction.

Co-authored-by: Cursor <cursoragent@cursor.com>
failure_receipt_companion_from_authority returns a three-valued FailureReceiptCompanionLookup so hygiene resolve/call failures surface as failure_receipt_companion_refused in witness receipts instead of silently masquerading as no companion (review 48762).

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

gunbai-bot Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor Author

Addressed review 48762 (§5 empty-observation narrow on failure_receipt_companion_from_authority).

failure_receipt_companion now returns a three-valued FailureReceiptCompanionLookup — NotDeclared | Declared(name) | AuthorityRefused{cause} — and append_failure_receipt_companion_loudness propagates AuthorityRefused into the Bool(false) receipt as failure_receipt_companion_refused: <cause>. Hygiene resolve/call failures are no longer indistinguishable from "no companion declared."

Pushed in c7335a3.

— sent from valiant-bat-462

@gunbai-bot
gunbai-bot Bot merged commit bfaaf3e into main Aug 5, 2026
5 checks passed
@gunbai-bot
gunbai-bot Bot deleted the session/valiant-bat-462 branch August 5, 2026 14:31
briansrls pushed a commit that referenced this pull request Aug 5, 2026
Resolve roadmap_program_view_witness_test: keep fixture-only witnesses;
live integration stays in live_corpus_receipt_test with projection API from

Co-authored-by: Cursor <cursoragent@cursor.com>
#7791 receipt continuity work.
gunbai-bot Bot pushed a commit that referenced this pull request Aug 5, 2026
Lands .dag semantic authority, floor-entry companions, the
seed_runner_bool_false_failure_detail bridge, loudness witnesses with
mutation control, and witness_template #7834 positional fix. Integrates
with main's append_failure_receipt_companion_loudness /
test_module_hygiene authority (#7791) rather than duplicating Rust
companion derivation.

Co-authored-by: Cursor <cursoragent@cursor.com>
gunbai-bot Bot pushed a commit that referenced this pull request Aug 5, 2026
…tins)

The main merge left v1_interpreter.rs and v1_interpreter_dispatch_generated.rs
internally inconsistent — interpreter arms for Class B builtins with no matching
generated dispatch rules. Regenerate the coupled dispatch roster so both the

Co-authored-by: Cursor <cursoragent@cursor.com>
#7791 roadmap builtins and Class B closure-control builtins are present.
gunbai-bot Bot pushed a commit that referenced this pull request Aug 5, 2026
…tins)

The main merge left v1_interpreter.rs and v1_interpreter_dispatch_generated.rs
internally inconsistent — interpreter arms for Class B builtins with no matching
generated dispatch rules. Regenerate the coupled dispatch roster so both the

Co-authored-by: Cursor <cursoragent@cursor.com>
#7791 roadmap builtins and Class B closure-control builtins are present.
gunbai-bot Bot pushed a commit that referenced this pull request Aug 5, 2026
Lands .dag semantic authority, floor-entry companions, the
seed_runner_bool_false_failure_detail bridge, loudness witnesses with
mutation control, and witness_template #7834 positional fix. Integrates
with main's append_failure_receipt_companion_loudness /
test_module_hygiene authority (#7791) rather than duplicating Rust
companion derivation.

Co-authored-by: Cursor <cursoragent@cursor.com>
gunbai-bot Bot pushed a commit that referenced this pull request Aug 5, 2026
…easure after #7822

TWO FINDINGS, both by execution.

1. A RUNTIME BREAK THE TYPECHECK DID NOT CATCH. #7791 changed
roadmap_acceptance_receipts() from returning List<RoadmapAcceptanceReceipt> to
returning RoadmapAcceptanceReceiptsProjection, a coproduct. live_program_view_result
passed it straight into v1_program_view(receipts:), which compiled clean and failed
at runtime with "fold expects a list, got Variant". So a List-versus-coproduct swap
at a call site is a class the substrate does not currently wall -- worth naming,
since every other break this branch hit across merges was a compile refusal.

Fixed without fabricating: a receipts-projection refusal is NOT a
ProgramViewRefusalCause, so forwarding it as one would have put a cause in front of
the reader that the model never produced -- the exact failure this page exists to
avoid. LiveProgramView keeps both refusal sources and renders either as its own
located line, so the page contract is unchanged: refuse loudly with causes named,
never draw a smaller program.

2. THE DISSOLVE-ON IS RE-MEASURED, NOT INFERRED. #7822 landed the keyed-lookup
restructure this branch's long-lane row named, including program_dedupe_ids onto a
seen-map. This keystone re-measured 17899ms -> 1843ms on the same host and binary,
about a tenfold cut, which CLEARS the 5000ms condition the row originally named.

The row still does not dissolve, and the reason is that the bar moved the same day:
at the operator's 500ms per-witness warning threshold, re-merging a 1843ms witness
per-PR would sit 3.7x over the warning line and move the problem rather than close
it. The remaining residue is mostly the served-page render, not the projection --
different work from what #7822 did. Both the roster row and the witness header now
carry the new number, because a stale measurement inside a carrier whose only job is
to justify a deferral is the citation-rot class DESIGN section 3 names.

Verified: per-PR mechanism half PASS (147ms), long-lane live half PASS (1716-1843ms).
briansrls pushed a commit that referenced this pull request Aug 5, 2026
…ysical screen audition (#7824)

* WIP: frontend

* WIP: frontend

* First v1-deletion instrument: semantic camera, focal salience, physical screen audition

Adds the model layer and a served /sandbox/instrument surface, all derived from
V0's four real v1-deletion finish lines rather than a demo roster.

- instrument_camera: four state owners (only the authoritative view may write a
  domain fact), ProgramDepth/ProgramMode/ProgramCamera. A camera carries a focus
  KEY, never a program fact, so no gesture can corrupt one. Depth crosses exactly
  one detent by construction (step takes a direction, not a target).
- instrument_projection: fires salience_note's declared dissolve-on. Roles are
  DERIVED from selection — selected Focal, region siblings Supporting, outside
  Ground, aggregated refusal one Critical — and judged by region_focal_admission,
  the same fold that judges hand-authored assignments.
- instrument_physical: the register amendment. Drift/jitter/shift/impulse are
  admitted on the ENCLOSURE only; every channel is preference-controlled with a
  total off position, carries no domain fact, and the COMPOSED displacement is
  bounded by the register's existing attraction travel. PhysicalImpulseSource
  names host capabilities, not a browser, per the standing don't-anchor directive.
- instrument_audition: one real finish line at three energies, each admitted
  through the register's own emission/attraction/displacement gates. Why has no
  rationale carrier, so it returns a typed refusal rather than paraphrasing the
  claim into something that reads like an answer.
- /sandbox/instrument: served page. The impulse glitch on press is real, built
  through the ordinary ResponseRule machinery. The IDLE channels are budgeted but
  not animated — ambient motion has no constructor in this register by design,
  and emitting past that wall would be an unmarked workaround. Dissolve-on named.
- theme_scoped_blocks: one theme-selector grammar, three var families. Removes
  the hand-rolled duplicate in roadmap_style band_root_css rather than adding a
  third copy.
- principles: PhysicalEnclosure added; StillUntilTouched restated to name its
  scope (the causal world, not the enclosure).

Verified by execution: 14 camera/projection witnesses, 18 physical/audition
witnesses, 9 served-page witnesses green; perturbing placement_role to drop
siblings to Ground reds the camera keystone, so the projection witness
discriminates.

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

* Give the depth and mode variants a type stem so they cannot collide

A bare nullary-variant identifier is a corpus-wide name in this substrate, not a
module-local one: the interpreter resolves an imported data item's free names
through a flat registry in the importing entry's closure. The first cut named
the depths Program/Outcome/Front/Node/Evidence and the modes Status/Remaining/
Why — and `Node` collided head-on with the substrate's own `Node` type, which is
the nicknaming violation before it is ever a resolution hazard. `Program` and
`Outcome` collide with real declarations too (product.compute_fabric,
v2.std.diagnostic).

Renamed to Depth*/Mode*, matching the convention the corpus already uses
(SalienceFocal, ReadingStatus, AuditionRestrained). Every projected key string
is unchanged — "program", "node", "why" — so nothing downstream moves.

Same class as the Clock collision this session root-caused on #7809; that one
reached CI because it is invisible from inside the module that owns the name.
This one was found by auditing for it instead.

Camera (14), physical/audition (18) and served-page (9) witnesses all still
green by execution after the rename.

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

* WIP: frontend

* Re-pin the moodboard HTML digest for the PhysicalEnclosure principle

CI red: witness_moodboard_html_digest_pinned. The moodboard renders
register_principles as a table, so the twelfth row and the restated
StillUntilTouched law move its bytes. Derived by execution
(moodboard_html_derived_digest), never chosen: e43de6d6 -> 4041adc0.

The four pins that did NOT move are the scope evidence, and CI established
that rather than this commit asserting it — of the five digest witnesses in
that file, exactly one went red:

- moodboard_css: the amendment is model-layer, adds no stylesheet rule
- moodboard_thesis_themes: register_thesis is untouched (the difference from
  the S1 re-pin, which DID revise the thesis)
- accent_study_html: renders the thesis, not the principles table
- roadmap_css: unchanged even though band_root_css was rewritten to call
  theme_scoped_blocks — which is the emission-identity proof for that
  consolidation, the same three selector blocks byte for byte from one
  authority instead of two copies

All five re-verified green by execution after the re-pin.

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

* WIP: frontend

* WIP: frontend

* Rework against review: read V0's derived world, compose one envelope, prove the joins

Four blocking findings, all real. What each was and what closed it:

1. THE FOCAL VISUAL BYPASSED BOTH THE DERIVED ROLE AND ITS ADMISSION.
   audition_card passed SalienceFocal as a literal, and the stylesheet was
   generated from audition_emission regardless of the verdict — so a refused
   emission still painted and the admission only controlled the prose printed
   underneath it. Role now comes from project_finish_line_salience over the
   exemplar camera; emission is projected from AuditionAdmitted alone. The
   control that was missing is now the load-bearing one: render at a role the
   register refuses and no emission appears in the CSS at all.

2. THE CAMERA BYPASSED V0. This is the one worth stating plainly: the previous
   revision answered Why with a typed refusal whose cause read "no rationale
   carrier exists for a v1 finish line". That was FALSE when it was written.
   gunbc.roadmap_program_view was already on this branch's base, its header
   says it is "the world those cameras look at", and ConstraintView exists
   precisely to answer why-is-this-slow without inventing prose. The refusal
   was the empty-observation narrow — could-not-find rendered as does-not-exist
   — in the module whose own notes warn against it, and it reached review green
   because nothing about a refusal looks wrong without going to check.
   read_camera now takes a V1DeletionProgramView: Status reads FinishLineView,
   Remaining renders RemainingShape, Why renders ConstraintView, and the five
   depths project genuinely different grains. Evidence still refuses — that one
   is real, and gunbc.roadmap_program_view records the same gap.

3. PhysicalEnclosure STATED A GUARANTEE ITS CARRIER DID NOT ENFORCE, three ways.
   Amplitudes were signed Int so two channels could cancel and pass (now Nat).
   The prose said "below" while the check admitted equality (one rule now:
   composed may spend the envelope fully, enclosure character alone may not
   reach it). Enclosure and focal attraction were bounded by separate gates
   that could not see each other — now one ComposedVisualDisplacement over
   every positional contribution. That change has a consequence worth reading:
   the register's canonical focal_attraction spends 12 of its 14 declared
   pixels, so instrument character and canonical attraction are alternatives,
   not companions. The audition variants now differ by one channel each rather
   than hiding the trade.
   GlitchPersistent was a locally invented meaning on a cited word — the
   reference's persistent glitch is a LATCHED state a later tap reseats, not a
   longer decay. Our transients are named ImpulseOff/Brief/Long and the latch
   is recorded as an unmodelled interaction.

4. THE DISSOLVE-ON CLAUSES WERE ARMED. #7809 merged, so main is consumed and
   the prose provenance is replaced by the typed edge it promised:
   channel_behaviour_axis binds each channel to a reference_instrument axis,
   and ChannelBuoyantDrift resolving to an OriginatedHere axis is the case
   that makes the edge worth having.

Realization and witness cleanup, as asked: the page is called a static study,
declares lang and viewport, drops the header controls it cannot operate, makes
the press specimen a focusable button, and describes the translation as a press
response rather than a realized CRT glitch. The witnesses are reshaped around
the production joins — the three substring-theatre claims are gone, the theme
block check now asserts occurrence INSIDE each block by position, and the
refused-cannot-paint control exists.

Also fixed from the follow-up review: the DepthFront fold ignored its
accumulator, so last-wins ran under a first-wins comment and the exemplar
rendered v2-generation where namespace-pderive was promised. Selection is now
a separate take-first, witnessed against V0's own contributing order.

Green by execution: camera 14, physical/audition 20, sandbox 10.

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

* WIP: frontend

* Revert auto-heal WIP sweep: drop transient extdeps crutch and unmeasured witness edit

An automated gunbc-ci-auto-heal commit ("WIP: frontend", 499e736) swept an
uncommitted working tree onto this branch and pushed it. It carried two things
that were never meant to land:

  - dag/extdeps/cloud/gcp/secret_ref.dag: a transient `import ... { GcpProjectId }`
    used ONLY to work around the local Class B bare-reference resolution failure
    (DESIGN open threads) so the witness could be evaluated on this host. It is an
    unmarked workaround in an extdeps file, unrelated to this PR's brief, and
    DESIGN section 5 names that class a line-stop signal rather than a landing state.

  - dag/test/claim/instrument_sandbox_witness_test.dag: a restructure that threaded
    one shared render through the claims to cut a presumed six-renders cost shape.
    Measured under a controlled same-host comparison it changed nothing (old 19532ms
    vs new 20050ms) because nullary calls are memoized, so the duplicate renders were
    already free. The accompanying note asserted it fixed the fast-lane budget
    overage, which is false. Shipping a claim that measurement refutes is the exact
    defect class this PR has been correcting, so the edit is withdrawn rather than
    kept with softened prose.

Both files return to their 7df2afa content. The budget failure is real and remains
open; it is attributed in the PR discussion, not papered over here.

* WIP: frontend

* Remove cost-attribution scratch swept in by auto-heal

dag/test/claim/tmp_cost_attribution / tmp_pv_attribution were throwaway probes
used to split the sandbox witness's eval cost. A gunbc-ci-auto-heal "WIP: frontend"
commit swept the second one onto the branch and pushed it before it could be
deleted; this removes it. Nothing in the PR depends on it and its findings are
reported in the PR discussion, not carried as a test.

* Split the instrument sandbox witness: mechanism per-PR, live half on the falsifier long lane

CI refused instrument_sandbox_keystone_holds at 5074ms thread-CPU against the
5000ms fast-lane budget (run 30986055960). Attribution by execution, not by
assumption:

  one served-page render        19098ms
    of which live_program_view   18510ms   (97%)
  instrument_css                   90ms
  derived role / emission / admission  0-2ms each

So the cost is one live V0 projection, and the register-gate claims are free.
Per the 2026-08-04 admission ruling a live-population subject decomposes into
small discriminating mechanism fixtures per PR plus the irreducible live half on
an enrolled cadence, and the mechanism half is never what moves:

  - per-PR (dag/test/claim/instrument_sandbox_witness_test.dag): derived role,
    the emission/admission join, the refused-role RED control, theme-block
    position, and the press CSS half. Measured 98ms, down from ~20050ms on this
    host, and it no longer pulls the serve closure at all.

  - falsifier long lane (dag/test/claim/long/instrument_sandbox_live_witness_test.dag):
    every claim that renders the page or reads the live view, including the
    front-grain claim from review 48579 and the evidence-refusal control.
    Measured 18399ms here; enrolled on falsifier_substrate_long_lane_rows with a
    WitnessExclusionRow so the carve-out from per-PR discovery is declared rather
    than implied by its directory.

The row does NOT claim irreducible corpus breadth. The projection's inputs cost
263ms to build and deriving over them costs 5132ms at n=25 nodes -- about 20x --
so the dissolve-on names the real fix: program_depth_lookup folds every row with
no early exit, membership is tested by linear any-scans at every level, reverse
adjacency is rebuilt per finish line where roadmap_focus already hoists it, and
program_dedupe_ids rescans its accumulator per element. program_relax_to_fixpoint
early-exits correctly and roadmap_dependency_graph is a trivial map; both were
checked and neither is the cause. When that derivation moves onto keyed lookup,
these claims re-merge per-PR and the long file, its roster row and its exclusion
row delete together.

Not done, and named because the diagnostic that produced this split names both:
the file was not relocated to drop it from discovery without an executing
consumer, and the keystone was not split into two per-PR test fns to draw two
budgets -- total cost would be unchanged and that is the same evasion.

* Program depth reads program grain under focus; make the collapse unwritable (review 48719)

review 48719 is correct. read_line_view matched ProgramDepth and carried a
DepthProgram arm byte-identical to its DepthOutcome arm, and read_camera_at
routed BOTH into it whenever a subject was focused. So the program detent
produced outcome-grain readings while the page kept labelling the row
"program / ...", and reading_grain_note's claim that Program reads the whole
program's shape held only with nothing selected. read_program_depth -- the sole
producer of ReadingProgramShape -- was unreachable under focus.

Fixed one rung above the report rather than at it. The suggestion was to route
DepthProgram to read_program_depth and reserve read_line_view for lower grains;
that corrects the arm but leaves the bad state writable, and this module has now
produced the same note-vs-code split three times. So the whole-program grain has
no representation in the line reader at all: SubjectDepth enumerates only the
grains that ARE a property of one finish line (Outcome, Node, Evidence),
DepthProgram cannot be projected into it, and no caller can hand the line reader
the program grain. A dead DepthFront arm went with it -- read_camera_at has
answered fronts through first_front_view since that fold landed.

Discriminating witness, per-PR because it is mechanism (117ms):
witness_the_program_detent_reads_program_grain_even_when_focused reads a PLANTED
view whose program remaining and line remaining are deliberately different
numbers (open_fronts 7 vs 1, startable_now 5 vs 0), so a collapse is caught by
VALUE, not merely by variant -- a variant-only assertion would still pass if some
future arm returned a program-shaped reading built from the line's own numbers.
witness_red_the_outcome_detent_still_reads_the_line is the other half, so the fix
cannot be satisfied by making every depth answer program-grain.

Proven by execution both ways: the witness FAILS when read_camera_at is perturbed
to route DepthProgram through SubjectOutcome, and PASSES on the fix. The original
bug is not reproducible by that perturbation because it is now unwritable -- the
perturbation simulates its effect. Long-lane live witness re-run green (17899ms).

reading_grain_note corrected in place to say what the code holds, and to record
that the sentence was false when written rather than quietly repairing it.

* State what focal_attraction_headroom_px actually holds, and name its next rung

Self-audit finding, not a reviewer's. The note claimed the derivation makes an
overrunning attraction impossible "by construction". It does not, for any
preference the envelope does not admit: the subtraction is total on Int, so a
preference whose channels sum past instrument_displacement_max_px yields a
negative headroom, and the composed record's focal_attraction_px is a Nat whose
refinement is not re-checked on a computed value -- so the sign-cancellation
class closed at the field in the composed-envelope fix is still reachable through
the derived path.

Bounded, which is why this is a prose correction rather than a carrier change:
it is unreached (preference_default spends 6 of 14) and the configuration that
would reach it is already refused by displacement_admission's
EnclosureCharacterReachesResponseTravel arm. The residual risk is a caller
reading headroom without consulting that admission first.

So the note now states the qualifier, records that the first version omitted it,
declares the rung honestly (mechanically preventable, ceiling structural
impossibility), and names the next-rung trigger per DESIGN 4b's no-untracked-stall
rule: headroom returns HeadroomAvailable { px: Nat } | HeadroomUnavailable, so a
caller cannot obtain a number when the enclosure has overspent. That change is
left for the operator rather than taken unilaterally -- it is a carrier change in
a PR already twice over its requested size, and the false claim is what needed
removing today.

Physical witness re-run green (3ms).

* Handle V0's two new refusal causes on the instrument page (#7822 merge)

#7822 grew ProgramViewRefusalCause by DuplicateAcceptanceReceipt and
DuplicateProgramNodeId, and the compiler refused refusal_cause_text until both were
handled. Worth recording as a construction-wall receipt rather than a merge chore:
nobody had to NOTICE that V0 gained two refusal shapes, because no Accepted program
could be built without naming them.

The totality matters here beyond typechecking. This page's contract when the
projection refuses is that it renders the located causes instead of a smaller
program, so a cause the page could not name would be a cause the reader never sees --
the empty-observation narrow one layer out from where this PR already fixed it.

* Consume roadmap_acceptance_receipts as the projection it now is; re-measure after #7822

TWO FINDINGS, both by execution.

1. A RUNTIME BREAK THE TYPECHECK DID NOT CATCH. #7791 changed
roadmap_acceptance_receipts() from returning List<RoadmapAcceptanceReceipt> to
returning RoadmapAcceptanceReceiptsProjection, a coproduct. live_program_view_result
passed it straight into v1_program_view(receipts:), which compiled clean and failed
at runtime with "fold expects a list, got Variant". So a List-versus-coproduct swap
at a call site is a class the substrate does not currently wall -- worth naming,
since every other break this branch hit across merges was a compile refusal.

Fixed without fabricating: a receipts-projection refusal is NOT a
ProgramViewRefusalCause, so forwarding it as one would have put a cause in front of
the reader that the model never produced -- the exact failure this page exists to
avoid. LiveProgramView keeps both refusal sources and renders either as its own
located line, so the page contract is unchanged: refuse loudly with causes named,
never draw a smaller program.

2. THE DISSOLVE-ON IS RE-MEASURED, NOT INFERRED. #7822 landed the keyed-lookup
restructure this branch's long-lane row named, including program_dedupe_ids onto a
seen-map. This keystone re-measured 17899ms -> 1843ms on the same host and binary,
about a tenfold cut, which CLEARS the 5000ms condition the row originally named.

The row still does not dissolve, and the reason is that the bar moved the same day:
at the operator's 500ms per-witness warning threshold, re-merging a 1843ms witness
per-PR would sit 3.7x over the warning line and move the problem rather than close
it. The remaining residue is mostly the served-page render, not the projection --
different work from what #7822 did. Both the roster row and the witness header now
carry the new number, because a stale measurement inside a carrier whose only job is
to justify a deferral is the citation-rot class DESIGN section 3 names.

Verified: per-PR mechanism half PASS (147ms), long-lane live half PASS (1716-1843ms).

---------

Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
gunbai-bot Bot pushed a commit that referenced this pull request Aug 5, 2026
Lands .dag semantic authority, floor-entry companions, the
seed_runner_bool_false_failure_detail bridge, loudness witnesses with
mutation control, and witness_template #7834 positional fix. Integrates
with main's append_failure_receipt_companion_loudness /
test_module_hygiene authority (#7791) rather than duplicating Rust
companion derivation.

Co-authored-by: Cursor <cursoragent@cursor.com>
gunbai-bot Bot pushed a commit that referenced this pull request Aug 5, 2026
The first draft cited "#7770 twice, #7791, #7835, #7857". Two errors:
#7770 hit the author-commit-required class three times on 2026-08-05
(ci.yml at 04:39 and 17:42, falsifier.yml at 06:34), and #7835 was only
a prospective warning, never a confirmed incident — the real fourth PR
is #7772. Verified against this lane's dispatch receipts rather than
recall, and the count is now stated as a floor rather than a census.

A wrong enumeration inside a canonical carrier is the citation class
DESIGN §3 names, so it gets the same bar as any other cited fact.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
gunbai-bot Bot pushed a commit that referenced this pull request Aug 5, 2026
Lands .dag semantic authority, floor-entry companions, the
seed_runner_bool_false_failure_detail bridge, loudness witnesses with
mutation control, and witness_template #7834 positional fix. Integrates
with main's append_failure_receipt_companion_loudness /
test_module_hygiene authority (#7791) rather than duplicating Rust
companion derivation.

Co-authored-by: Cursor <cursoragent@cursor.com>
gunbai-bot Bot pushed a commit that referenced this pull request Aug 5, 2026
Lands .dag semantic authority, floor-entry companions, the
seed_runner_bool_false_failure_detail bridge, loudness witnesses with
mutation control, and witness_template #7834 positional fix. Integrates
with main's append_failure_receipt_companion_loudness /
test_module_hygiene authority (#7791) rather than duplicating Rust
companion derivation.

Co-authored-by: Cursor <cursoragent@cursor.com>
briansrls added a commit that referenced this pull request Aug 5, 2026
* Make scope placement gate refusals loud in CI floor receipts.

Lands .dag semantic authority, floor-entry companions, the
seed_runner_bool_false_failure_detail bridge, loudness witnesses with
mutation control, and witness_template #7834 positional fix. Integrates
with main's append_failure_receipt_companion_loudness /
test_module_hygiene authority (#7791) rather than duplicating Rust
companion derivation.

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

* Consolidate failure-receipt naming onto test_module_hygiene.

Address review 48788: delete parallel gunbc.floor_witness_failure_receipt
authority; floor_effect_gate_witness now consumes
gunbc.test_module_hygiene.failure_receipt_companion (same path as
cli_run::failure_receipt_companion). Add HAND-RUST disposition on
seed_runner_bool_false_failure_detail.

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

* Fix plan modules missing md_helpers imports for compile-clean gate.

branch_merge_admission_model and merge_admission_gate_shape_proposal use
cell/row and other markdown helpers without importing gunbc.plans.md_helpers,
which dag_compile_clean_gate now pulls into the affected closure.

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

---------

Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
gunbai-bot Bot pushed a commit that referenced this pull request Aug 5, 2026
…tins)

The main merge left v1_interpreter.rs and v1_interpreter_dispatch_generated.rs
internally inconsistent — interpreter arms for Class B builtins with no matching
generated dispatch rules. Regenerate the coupled dispatch roster so both the

Co-authored-by: Cursor <cursoragent@cursor.com>
#7791 roadmap builtins and Class B closure-control builtins are present.
briansrls pushed a commit that referenced this pull request Aug 6, 2026
…les from the path roster (#7830)

* WIP: import -> namespace (import deletion)

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

* Namespace closure: three prerequisite rows in front of reference-derived-closure

namespace-reference-derived-closure carried a six-capability set-difference
closing contract in which every row read Unavailable, while the node itself was
the only dispatchable thing in the lane -- one startable row standing for three
separable pieces of work with different substrates.

The cut follows the contract's own triggers, which already record what each
capability waits on:

  namespace-structural-observations   4 caps, P2aStructuralCandidateProducer7515
  namespace-cross-file-provenance     1 cap,  P2aReferenceDependencyProjection7515
  namespace-pool-independence         1 cap,  P2aPoolIndependentDependencyProjection7515

The first two are parallel -- no dependency runs between the same-file rules and
the cross-file projection. Pool independence depends on cross-file provenance
because a differential needs a projector to perturb.

No new identity was minted for integration or for the census.
namespace-reference-derived-closure keeps its durable identity and now denotes
the aggregate handback (its first_slice moved; its boundary, which still covers
all six, did not). namespace-ambiguity-discharge keeps its identity and its
existing dependency on the closure node.

The three new rows are deliberately ExecutionContractUnspecified. Each first_slice
names authoring its own closing check as its first act, per
v1_lane_binding_survey_note: the contract follows the witness, never precedes it.
The derived closing-contract tasks for the two startable rows are the honest
fail-closed state, not a gap; pool-independence gets none because it is
dependency-held, and could not carry one anyway -- its differential compares an
output shape its prerequisite has not yet produced.

Also adds roadmap-receipt-continuity (roadmap-runtime, off the namespace spine):
a receipt that was valid and is now absent refuses unless an explicit revocation
names the exact node, the exact record, a reason and its disposition. Motivated
by #7739, where a branch spent real effort reconstructing an acceptance record
that already existed because nothing refused when it went missing. Distinct from
startable_nodes_missing_closing_contract, which finds nodes that never had a
check rather than accepted state that vanished.

Evidence, by execution on this tree:
- roadmap_authority_test: 42/42 witnesses PASS
- generated_artifact_drift_test: 7/7 PASS
- ROADMAP.md regenerated via main_wet on dag/tools/generated_artifact_gate.dag;
  the projection shows reference-derived-closure requiring the two new
  prerequisites, and derived closing-contract tasks appearing for exactly the
  two startable unbound rows.

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

* WIP: import -> namespace (import deletion)

* Remove stray empty file committed by WIP auto-commit

An empty file named 'true' was created in the worktree by a shell-quoting
mishap while sending dashboard messages, then picked up and committed by
the WIP auto-commit process. It is not on main and carries no content.

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

* WIP: import -> namespace (import deletion)

* Regenerate ci.yml: heal repair artifact publishes its hidden payload

Author-committed because the GitHub App lacks workflows:write, so the
heal job can detect this drift but can never push the fix.

Emitted from the ci_workflow.dag change in this branch; the value is
derived from author_commit_required_committed_artifact_paths(), not
hard-coded.

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

* Correct the incident enumeration in the hidden-files note

The first draft cited "#7770 twice, #7791, #7835, #7857". Two errors:
#7770 hit the author-commit-required class three times on 2026-08-05
(ci.yml at 04:39 and 17:42, falsifier.yml at 06:34), and #7835 was only
a prospective warning, never a confirmed incident — the real fourth PR
is #7772. Verified against this lane's dispatch receipts rather than
recall, and the count is now stated as a floor rather than a census.

A wrong enumeration inside a canonical carrier is the citation class
DESIGN §3 names, so it gets the same bar as any other cited fact.

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

* Regenerate ci.yml against merged main (author-committed)

The merge brought in 52 commits of main, and the generated-artifact merge
driver keeps this side's copy for generated paths, so the merged ci.yml
was this branch's pre-merge bytes: it was missing main's new registered
plans and stage0 modules in AUTHORED_CONFLICTS, the heal commit's
--no-verify, several step ids, and a test-negation respelling.

Regenerated from the authority rather than hand-merged. The output now
differs from origin/main by exactly one line — the include-hidden-files
key this branch adds — which is the check that the regeneration is
correct rather than a plausible-looking text merge.

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

* WIP: import -> namespace (import deletion)

* WIP: import -> namespace (import deletion)

* Remove the floor/heal gating model change: it belongs to #7882, not here

review 49102 is correct and this was my error. ci_workflow.dag declared
needs: [build, regen, heal_generated_artifacts] with a job-level if, while
the committed ci.yml carried neither -- an internally inconsistent PR that
would have failed ci_yaml_parse_witness, since expected_ci_yml() serializes
the model.

The cause was mechanical rather than a decision: the gating work was in this
worktree when the WIP auto-commit picked it up and pushed the .dag half,
while the regenerated ci.yml was discarded by a local reset moments later.
The two halves were split across a push boundary.

The fix is removal, not regeneration. That change is not in this PR's scope
and already exists as #7882, authored on main with its own witnesses and a
proven RED control. Regenerating ci.yml here would have made this PR
self-consistent by duplicating another PR's change, which is the worse
resolution of the two.

The three files are restored to cfea75a, the last head where this branch
carried only the heal-artifact fix. Regen after the restore produces no
ci.yml drift, which is the check that model and artifact now agree.

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

---------

Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
gunbai-bot Bot pushed a commit that referenced this pull request Aug 29, 2026
…prepare or build over the live tree carry a live-corpus ignore reason and leave the required run, and the rot the first-ever `cargo test` exposed is repaired at its authorities, not hidden

`cargo test -p v1-compiler --lib` had never run in CI. Its first run (33238828500) was cancelled by its own 60-minute timeout with 204 of 682 tests finished, because ~126 of the "unit" tests each build a fresh multi-entry index over `src/v2`+`dag` (4,260 modules; ~197 single-thread minutes on srv2 under nextest, 97 tests over 60 s, `self_compile_all_modules` alone 505 s), and the runner executes them serially. Those tests now carry `#[ignore = "live-corpus: ..."]` — the crate's existing `manual:` convention, one class, declared on the carrier — and the rung-drop row `required_gate_bankruptcy` names them by their instrument (`cargo test -p v1-compiler --lib -- --ignored --list`). The unit population runs in ~10 s after the compile (srv2: 537 passed / 136 ignored).

Of the 44 failures the full run exposed, the 15 in the unit population are repaired where the fact lives:
- REAL DEFECTS (two): `try_index_source_root_into_module_index` keyed files by their walked path, absolute since #9548 anchored the root, while the strict builder keys through `module_index_path_key` — the primary-precedence index disagreed with the strict one on every path; keyed through the same authority now. `try_build_module_index` carried `if root_idx > 0 { continue; }` before its collision refusal (from #7791), so a module declared in two roots shadowed silently in the builder named strict; the guard is gone and overlay callers have `build_module_index_primary_precedence`.
- v1 TYPECHECK DEFECT: `declared_type_inhabitance` reads `params` as generic type parameters, which is exactly what a callable formal carries, so every higher-order call produced a counted advisory with a false reason (#9194); `direct_call_argument_inhabitance_diags` now excludes callable formals like its sibling `direct_call_arg_type_mismatch`. Mirror regenerated (two passes: the test blob lives inside the emitter).
- STALE AUTHORITY ROWS after the #9637 reorg: 12 entry literals in `gunbc.ci_layer_roots` and 2 in `gunbc.offline_local_recipe` repointed; the two long-lane rows and one freeze row whose subjects 611fd02 and #9206 deleted are gone; the three freeze rows for relocated witnesses are DELETED rather than repointed, because the freeze gate defines relocation as growth and the roster may only shrink. `gunbc.non_fold_residue` receives the 22 sites it lacked and loses the 4 whose subjects moved or greened; its .dag twin therefore leaves floor_expected_red (it passes) and joins cost-debt chunk 12 (629 ms against the 500 ms ceiling, its whole cost the corpus scan it checks).
- DELETED SUBJECTS: `cli_run::floor_witness_a_prove` (its runner, prove test and fixtures went with the FLOOR-Y cutover); the census pin tests and helpers for `docs/probes/census_extra_excludes.txt` (#9132 deleted every transcription).
- EARLY ABORTS: three witness-admission tests and the roadmap jsonl-carrier test were "fast" only because they failed before their expensive step; with their inputs repaired they read the live tree for 2-4 minutes each and join the live-corpus class.
- TEST ROT: the reorg rewrote a revision-addressed literal (`9ce6526c528:dag/gunbc/roadmap/...`) that must name the pre-reorg path; the method-existence witness anchored on a `Primitive()` row the frontier no longer holds.

Not done here, receipts-lane rot for follow-ups: `test.claim.expectation_frontier_witness_test` names the deleted long-lane file; the affected-set kernel (`floor_diff_edits_from_diff_text`, `rerun_frontier_nodes_for_entry`, …) has no production consumer since FLOOR-Y and should go with its remaining fixture-dependent tests; the roadmap jsonl-carrier test takes 453 s and fails after its expensive step.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013G3t66QwKJFK5w8jXxMXP2
briansrls added a commit that referenced this pull request Aug 29, 2026
…e prepares the roster's closure, not the tree; rust unit tests in their own job; the un-required phases declared as a rung drop (#9663)

* Unbreak main: drop the JsSite artifact rows whose authority #9641 deleted, and give the six witness-bin TypeEnv initializers the unit_variant_index #9656 added

Two integration collisions between independently green PRs:
- #9641 deleted dag/examples/js_site but gunbc.generated_artifact and
  gunbc.generated_artifact_emit still imported it, so the whole-tree
  strict resolve refused and every floor on main has been red since.
- #9656 added TypeEnv.unit_variant_index; infer_semantics_witness.rs
  builds six TypeEnvs by hand and none carried it, so --bins failed.

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

* The lib's own unit tests build one more TypeEnv by hand; give it unit_variant_index too

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

* Required CI is the compiler floor: a static gate roster, prepared as its own import closure, with the other four phases and the product witnesses moved off the merge path

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

* Drop the six duplicate unit_variant_index initializers the merge with #9648 produced

* Drop the six duplicate unit_variant_index initializers the merge with #9648 produced

* Regenerate .gitattributes: the six js_site rows projected from the deleted artifact registry entries go with them

* Regenerate the four projections of this change: witnesses.yml (probe and all-bins steps gone, rust-unit-tests job added), DESIGN.md and design-ledgers.md (the rung-drop row), .gitattributes (js_site rows gone)

* Restore the lib-test TypeEnv initializer's unit_variant_index (lost when the merge took main's cli_run.rs wholesale)

* The gate closure is the loader's both-closure (imports + reference edges to a fixpoint), not the import headers: stripped modules reach their providers by reference, and the header walk left 1,190 names unresolved

* Shrink the namespace transition roster: the 314 std->extdeps consolidation rows landed with #9641 and now refuse every PR as stale

* Build the entry index once for both gate closures (it is the expensive part: ~75-110s per build on the corpus)

* Gate closure includes containment ancestors to a fixpoint: a module importing only a child of the declaring module still binds the parent's declarations

* The floor's policy module is always a closure seed: its rosters are evaluated in a frame over the prepared subject

* The reference-closure index is keyed by the prepared subject's digest, bounded to the two subjects a floor process prepares by design — the gate's policy-closure preparation and the gate closure are two subjects in one process, and a once-per-process index refused the second (ReferenceIndexSubjectChanged built_for_modules=47 observed_modules=1952, CI and srv2 at 066725c)

The old check keyed on module COUNT: two subjects of equal size would have
shared one index silently. The new one keys on `subject_digest`, so the
index a scope consults was built from the graph that scope is over, by
construction. The population is bounded by
FLOOR_PREPARED_SUBJECTS_PER_PROCESS = 2 (policy closure, gate closure) — a
third distinct subject still refuses with the same cause, because a
subject per claim is the corpus walk per row the index exists to avoid.

Evidence: srv2 rerun of `claim_executor --required-ci --required-lane
witnesses` at this tree builds the 47-module policy index
(subject=09966adcd218af0e) and proceeds into the 1,954-module gate
preparation instead of refusing at claim scope.

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

* The floor's own runtime authorities are explicit closure seeds: the gate-bounded subject refused at output-policy install because resolve_channel_policy had only ever resolved by pool-membership coincidence — the flat bare-name channel found gunbc.output_policy because the whole corpus was loaded, not because the policy closure references it

REQUIRED_FLOOR_RUNTIME_AUTHORITY_MODULES names every module the floor's
Rust evaluates by name outside the gate roster: the policy module (its
rosters), v2.workflow.floor_naming_hygiene (qualified evaluations), and
gunbc.output_policy (bare, from install_output_policy_in). All three are
seeds of the gate closure; a new by-name evaluation adds its module here
or refuses at its own call site.

Measured: the first gate-bounded run (srv2, at 2d5502a) got past both
reference-closure indexes and refused with "no declaration named
'resolve_channel_policy' in this execution's loaded index".

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

* A by-name evaluation of a module's declaration runs in THAT module's scope: the floor installed the output policy and the naming-hygiene predicates from the policy module's frame, which reached gunbc.output_policy only by the accident of the whole-tree reference closure — under the gate-bounded subject the module was loaded and the name still refused

floor_authority_frame(prepared, module) builds a hermetic frame over one
module's exact claim scope. install_output_policy_in now receives the
frame over gunbc.output_policy; floor_barren_test_sidecars the one over
v2.workflow.floor_naming_hygiene. The policy module's frame keeps only
the policy module's own rosters.

Measured (srv2, lanes 5 and 6): with gunbc.output_policy present in the
1,954-module subject — the seeds changed the seed count 906 -> 908 and
the closure not at all — resolve_channel_policy still refused as "no
declaration named ... in this execution's loaded index". The scope, not
the subject, was the coincidence.

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

* The floor's rosters are joined only over identities inside the required gate — an enrolled identity whose module the gate never loads is withheld with the same accounting as cost-debt withholding, not refused as stale; and two modules that reached rust_target_model_staging by bare reference now import it, because the loader follows bare references only for import-free modules while the claim scope follows all of them

Measured on the first gate-bounded fold (srv2 lane 7, CI at 006b0ef):
ExpectedRedIdentityDidNotExecute count=39, every row in a module outside
the gate roster; and v2.test.lens_vacuity.vacuity_test x5 ERROR
no-such-function `rust_target_model_staging`, reproduced standalone with
`gunbc run --entry src/v2/test/lens_vacuity/vacuity_test.dag`. The
loader's both-closure (build_both_closure_edge_index) skips the bare
scan for any source that declares import lines, so rung_3_4_common
(one import) and leaf_model_verification's bare edge to
v2.extdeps.languages.rust was never followed; under the whole-tree
subject the flat channel found it anyway. The import is the form 10 of
the 12 sibling callers already use; the loader/scope divergence is
recorded in the PR.

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

* The gate closure follows bare cross-module references from EVERY module, with the loader's own scanner, to a joint fixpoint with containment ancestors — the loader's both-closure bare-scans only import-free sources, while the claim scope the fold builds over the subject follows bare references from all of them; and route-gap expectations located outside the gate are withheld like the roster rows they join

Measured 2026-08-29 on srv2: with the gate subject, `gunbc run` of
v2.test.lens_vacuity.vacuity_test refused no-such-function
`rust_target_model_staging`, then `eval_context` after the first was
imported — one absent module per run, because rung_3_4_common (one
import line) and leaf_model_verification reach them by bare reference
and build_both_closure_edge_index skips the bare scan for any source
that declares an import. The fixpoint reuses
bare_reference_pull_paths_for_source, so the relation is the loader's
and not a second scanner; the count of modules pulled this way is
printed on the gate-closure line.

Lane 8 (srv2) then refused `floor_route_gap_expectations: located
identity is absent from derived roster` for an identity whose module is
outside the gate: the roster had its outside-gate rows withheld and the
expectations had not. Both sides now withhold by the same predicate,
counted.

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

* Cost-debt rows outside the required gate are withheld from the staleness join, route-gap expectations honour cost-debt withholding, and emit_on_demand_classical_not_native_one_build_holds moves to the cost-debt roster — it is budget-refused before it reaches the host effect its route-gap enrollment expects, on both hosts

Measured on the first complete gate-bounded fold (srv2 lane 10 and CI at
e8effe8, identical): verdict=FloorRefused with unexpected_failures=0 —
no claim inside the gate fails — and two bookkeeping refusals: 122
STALE-COST-DEBT rows, every one in a module the gate never loads, and
one STALE-ROUTE-GAP row whose claim ran past its CPU ceiling before
reaching the effect. The first is the same out-of-scope population the
expected-red and route-gap joins already withhold, now counted the same
way. The second is a real cost debt (floor_cost_debt already records
this claim at 502 -> 2374 ms), and cost debt wins over route-gap
enrollment by the roster's own rule; the expectations decode now treats
a cost-debt-withheld identity as dormant rather than absent.

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

* Two lens_module_gate_witness rows leave the expected-red roster: under the gate-bounded subject both PASS on CI and on srv2, and the floor refuses a passing enrollment as STALE-QUARANTINE

Measured at 1f4bda9 (CI) and srv2 lane 12: verdict=FloorRefused with
unexpected_failures=0 and exactly these two STALE-QUARANTINE rows on
CI. Both are "live" claims whose question ranges over the loaded
corpus; under the gate closure that corpus is 2,021 modules rather
than 4,260, and the population they were red on is outside it. That
is a narrowing of what the claim observes, stated here rather than
hidden: the whole-corpus receipts run is where the wider question is
asked again. srv2 additionally passes four emit_host_* rows that stay
red on the required host; those stay enrolled — CI is the oracle for
the required gate.

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

* Eleven claims interrupted before verdict on the gate-bounded subject join the cost-debt roster as proven chunk 12 — the same eleven on the GitHub runner and on srv2, run after run

At 92cc92e the floor reports verdict=FloorRefused with
unexpected_failures=0, no stale rows, no now-passing rows, and eleven
INTERRUPTED-BEFORE-VERDICT identities (cost_coverage_witness x3,
loaded_carrier_receipts x3, lens_closure_question_zero_holds_live,
green_control_sanctioned_reader_body_not_flagged,
same_grammar_parse_ingest_bridge_holds, kotlin_grammar_parse_accepted,
nominal_distinct_control_compiles_ok). The set is identical at e8effe8
and 1f4bda9 on CI and in srv2 lane 12, so it is a property of the
subject, not of host load: on the gate closure these claims first-touch
artifacts the whole-tree fold had warmed before reaching them. Declared
here as the roster's own containment for a cost the ceiling cannot
hold; the exit is the warm, as the roster's header states.

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

* lens_module_gate_holds_live joins cost-debt chunk 12: it was interrupted at 1076ms the run after its sibling was withheld, because the 1.07s pool-root module_path_index fill is billed to whichever consumer runs first

CI 0829ad8: verdict=FloorRefused, unexpected_failures=0, one
INTERRUPTED-BEFORE-VERDICT row. The claim-cost receipt reads
budget_interrupted 1076ms for it and
`[floor-shared-fill] cache=module_path_index key=.../src/v2/lens
fill_ms=1070 paid_by=...lens_module_gate_holds_live consumer_claims=1`;
at 92cc92e the same fill was paid by lens_closure_question_zero_holds_live
(consumer_claims=2) and this claim passed. The index is keyed on a pool
root the decl_facts seam asks for at claim time, so preparation cannot
warm it ahead; with both consumers withheld nothing pays it. The
roster's own header names the warm as the exit.

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

* The pool-root module_path_index for src/v2/lens is warmed in preparation by evaluating the declared producer once in its own module's scope — the 1.07s fill was a positional bill that interrupted a different lens_module_gate_witness live claim in each of three consecutive runs — and the two fill-only rows leave cost-debt chunk 12

CI 92cc92e, 0829ad8, 154fb1f: each run's single INTERRUPTED-BEFORE-VERDICT
row was the next `lens_module_gate_witness` live claim in evaluation
order, at 1068–1252ms, with the claim-cost receipt and
`[floor-shared-fill] cache=module_path_index key=.../src/v2/lens`
naming that claim as the payer. The witness-roots warm cannot reach a
per-pool-root key; this warm evaluates
`v2.lens.registry.completeness.lens_registry_completeness_live_facts`
in that module's frame, so the root comes from
`lens_registry_completeness_pool_roots` and the key is the consumers'
by construction. Adjudicated with the other preparation warms as
`ModulePathIndexBuild/lens-pool-roots`; skipped (printed) when the
subject does not carry the producer; a producer that fails to evaluate
refuses. The two rows whose entire cost was this fill leave chunk 12,
as the roster header says they must once the warm exists.

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

* lens_closure_question_zero_holds_live leaves the expected-red roster: with the src/v2/lens pool-root index warmed in preparation it passes, as its two siblings did once they stopped paying that fill

srv2 lane 13 at 8ad4091: `[floor-shared-fill] cache=module_path_index
key=.../src/v2/lens paid_by=<outside-fold> consumer_claims=3`, no lens
claim interrupted, and STALE-QUARANTINE for this row — the same row
that was red only while it paid the fill (CI 92cc92e).

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

* The four bootstrap_footprint_anchor claims join cost-debt chunk 12: 474–505ms CPU on three consecutive CI runs with no fill billed to them, so the 500ms ceiling decides them run by run

CI f462bc9: planned=executed=2834, passed=2754, known_red_held=27,
failed=0, no stale rows, interrupted_before_verdict=4 — these four, at
502–505ms. At 154fb1f the same four completed at 487–504ms and at
0829ad8 at 474–485ms; the run-to-run spread is the runner slot, not the
claim. The gate did not change their cost — nothing in the shared-fill
attribution names them — so the disposition is the roster's, not a
ceiling change: withheld as declared debt until the host-load row
lands.

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

* The rust-unit-tests job runs the unit population: the lib tests that prepare or build over the live tree carry a live-corpus ignore reason and leave the required run, and the rot the first-ever `cargo test` exposed is repaired at its authorities, not hidden

`cargo test -p v1-compiler --lib` had never run in CI. Its first run (33238828500) was cancelled by its own 60-minute timeout with 204 of 682 tests finished, because ~126 of the "unit" tests each build a fresh multi-entry index over `src/v2`+`dag` (4,260 modules; ~197 single-thread minutes on srv2 under nextest, 97 tests over 60 s, `self_compile_all_modules` alone 505 s), and the runner executes them serially. Those tests now carry `#[ignore = "live-corpus: ..."]` — the crate's existing `manual:` convention, one class, declared on the carrier — and the rung-drop row `required_gate_bankruptcy` names them by their instrument (`cargo test -p v1-compiler --lib -- --ignored --list`). The unit population runs in ~10 s after the compile (srv2: 537 passed / 136 ignored).

Of the 44 failures the full run exposed, the 15 in the unit population are repaired where the fact lives:
- REAL DEFECTS (two): `try_index_source_root_into_module_index` keyed files by their walked path, absolute since #9548 anchored the root, while the strict builder keys through `module_index_path_key` — the primary-precedence index disagreed with the strict one on every path; keyed through the same authority now. `try_build_module_index` carried `if root_idx > 0 { continue; }` before its collision refusal (from #7791), so a module declared in two roots shadowed silently in the builder named strict; the guard is gone and overlay callers have `build_module_index_primary_precedence`.
- v1 TYPECHECK DEFECT: `declared_type_inhabitance` reads `params` as generic type parameters, which is exactly what a callable formal carries, so every higher-order call produced a counted advisory with a false reason (#9194); `direct_call_argument_inhabitance_diags` now excludes callable formals like its sibling `direct_call_arg_type_mismatch`. Mirror regenerated (two passes: the test blob lives inside the emitter).
- STALE AUTHORITY ROWS after the #9637 reorg: 12 entry literals in `gunbc.ci_layer_roots` and 2 in `gunbc.offline_local_recipe` repointed; the two long-lane rows and one freeze row whose subjects 611fd02 and #9206 deleted are gone; the three freeze rows for relocated witnesses are DELETED rather than repointed, because the freeze gate defines relocation as growth and the roster may only shrink. `gunbc.non_fold_residue` receives the 22 sites it lacked and loses the 4 whose subjects moved or greened; its .dag twin therefore leaves floor_expected_red (it passes) and joins cost-debt chunk 12 (629 ms against the 500 ms ceiling, its whole cost the corpus scan it checks).
- DELETED SUBJECTS: `cli_run::floor_witness_a_prove` (its runner, prove test and fixtures went with the FLOOR-Y cutover); the census pin tests and helpers for `docs/probes/census_extra_excludes.txt` (#9132 deleted every transcription).
- EARLY ABORTS: three witness-admission tests and the roadmap jsonl-carrier test were "fast" only because they failed before their expensive step; with their inputs repaired they read the live tree for 2-4 minutes each and join the live-corpus class.
- TEST ROT: the reorg rewrote a revision-addressed literal (`9ce6526c528:dag/gunbc/roadmap/...`) that must name the pre-reorg path; the method-existence witness anchored on a `Primitive()` row the frontier no longer holds.

Not done here, receipts-lane rot for follow-ups: `test.claim.expectation_frontier_witness_test` names the deleted long-lane file; the affected-set kernel (`floor_diff_edits_from_diff_text`, `rerun_frontier_nodes_for_entry`, …) has no production consumer since FLOOR-Y and should go with its remaining fixture-dependent tests; the roadmap jsonl-carrier test takes 453 s and fails after its expensive step.

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

* The host-tool probe root carries the process id: temp_dir() is the host's shared /tmp on a self-hosted runner, and a fixed directory name collided with one another runner slot's uid left behind — PermissionDenied on two tests that had never run in CI before

Found by the first green-by-duration run of the unit population (dc3ca52: 533 passed, 2 failed, 9.59s). The same class as the shared-/tmp emit_on_demand collision on srv2: a test that writes a fixed path into a location the process does not own.

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

---------

Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
gunbai-bot Bot pushed a commit that referenced this pull request Sep 3, 2026
…the join key is (name, revision)

I reported cli_run.rs's run_in_context "roadmap_acceptance_event_history" as a live break
because no declaration of that name exists AT HEAD. That was a defect in my census method,
not in the seed.

The decoder is the carrier-introduction bootstrap: it fires only when the JSONL carrier is
ABSENT at the merge-base, and it decodes git.Core.Show of the merge-base revision's
roadmap_authority.dag -- not the worktree's. The two facts were bound in one commit: at
bfaaf3e^ (#7791) the function exists and the carrier is absent; at bfaaf3e the
carrier exists and the function is gone. So the arm's own guard implies the old spelling is
present in the text it is about to read. Correct for exactly the revisions where it can
fire, unreachable everywhere else.

The probe question, answered rather than assumed: the pin to 9ce6526 is LEGITIMATE and
stays. That revision is an ancestor of bfaaf3e^, carries the function, and has no
carrier -- a faithful representative of the revision class the decoder serves. A live probe
that reddens on a rename would assert a property the code never claimed. The #[ignore] is
separately declared (live-corpus) and hid nothing.

The class this actually names is a census-method class: a spelling-keyed decode whose
subject is a REVISION-ADDRESSED text must be joined against the revision it reads, not
against HEAD. It narrows to P4; P1/P2/P3/P5 decode values from the current resolved graph,
so the HEAD join is right for them. Recorded because a reader copying the method would
repeat the error.

Also states what the rung refinement costs: priced by deferred detection, not corrupted
output.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FbsVmKQEBj7KAwfKEn6JCQ
gunbai-bot Bot added a commit that referenced this pull request Sep 3, 2026
…ling-keyed (census only) (#10180)

* Census the seed's spelling-keyed decode of .dag authorities, and find a second already-fired instance

The seed reads .dag values through the interpreter and addresses them by SPELLING -- type
name, variant name, field name, entry-function name, all string literals in Rust. Seed and
authority share no Rust type, so a rename has no compile-time link to the decoder that
depends on it. #9975 found this by accident. This is the population.

Five decode primitives, all bottoming out in four InterpContext methods; two of them (P3
resolve-and-match-arm, P5 file-local wrappers) are invisible to a grep written from the
#9975 sym_eq specimen and carry 97 further sites in 9 files. 25 unambiguously-attributed
.dag authorities are decoded; the mint side carries 262 more sites in the other direction.

Second already-fired instance, found by the census rather than by accident: cli_run.rs calls
run_in_context "roadmap_acceptance_event_history", which no declaration in the corpus
carries -- gunbc.roadmap_authority renamed it to _load and changed the result shape. The
only test over the route is #[ignore]d AND pins the authority text to the pre-rename SHA, so
it can never observe the break.

Rung found at 1: every decode site read fails closed with a typed Err, so the class is not
silent-wrong-answer but silent-at-COMPILE-time. Ceiling 3, trigger stated as the capability:
emitted typed decoders and constructors sufficient to leave no hand-written .dag spelling in
the seed. Census only -- no repair, no ledger enrolment.

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

* RETRACT instance 2: the decoder's subject is revision-addressed, and the join key is (name, revision)

I reported cli_run.rs's run_in_context "roadmap_acceptance_event_history" as a live break
because no declaration of that name exists AT HEAD. That was a defect in my census method,
not in the seed.

The decoder is the carrier-introduction bootstrap: it fires only when the JSONL carrier is
ABSENT at the merge-base, and it decodes git.Core.Show of the merge-base revision's
roadmap_authority.dag -- not the worktree's. The two facts were bound in one commit: at
bfaaf3e^ (#7791) the function exists and the carrier is absent; at bfaaf3e the
carrier exists and the function is gone. So the arm's own guard implies the old spelling is
present in the text it is about to read. Correct for exactly the revisions where it can
fire, unreachable everywhere else.

The probe question, answered rather than assumed: the pin to 9ce6526 is LEGITIMATE and
stays. That revision is an ancestor of bfaaf3e^, carries the function, and has no
carrier -- a faithful representative of the revision class the decoder serves. A live probe
that reddens on a rename would assert a property the code never claimed. The #[ignore] is
separately declared (live-corpus) and hid nothing.

The class this actually names is a census-method class: a spelling-keyed decode whose
subject is a REVISION-ADDRESSED text must be joined against the revision it reads, not
against HEAD. It narrows to P4; P1/P2/P3/P5 decode values from the current resolved graph,
so the HEAD join is right for them. Recorded because a reader copying the method would
repeat the error.

Also states what the rung refinement costs: priced by deferred detection, not corrupted
output.

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

* Second pass: P4 residue closed by subject-revision attribution, two more primitives found, and the shape axis named

ATTRIBUTION. All 42 literal-entry run_in_context sites -- the first pass said 30; a stricter
re-extraction finds 42 -- attributed by reading each caller's context construction.
17 HEAD/live-worktree (ctx from default_source_roots/workspace_root), 24 in-file synthetic
source (the module text and the entry name are authored in the same expression, so a rename
edits both and they are not exposure at all), and exactly 1 revision-addressed: the
carrier-introduction bootstrap already adjudicated. The residue is closed; all 17 HEAD-subject
names resolve today.

TWO MORE PRIMITIVES, found by this pass rather than the first sweep, taking the set 5 -> 7.
P7: entry/function names passed as subprocess ARGV (--entry/--function) -- 35 sites in 3
files, larger than P4 and completely invisible to a run_in_context grep. All HEAD-subject,
all 11 names resolve. P6: str::replace rewriting a live-HEAD .dag file's own text, 2
producers / 6 call sites, and the ONLY primitive in the set that can fail OPEN -- replace
returns the input unchanged on a miss. Its two arms differ: a missed module-path rewrite hits
the module-path collision wall (loud); a missed /tmp-path rewrite makes the witness write to
the shared path instead of its scratch dir (silent). Scored per arm, not per primitive.

THE SHAPE AXIS, named as residue on the design authority's ruling. The class is any change to
a .dag schema element consumed reflectively by host code, not renames alone -- including
changing optionality, cardinality or shape while preserving every identifier. All seven
primitives are NAME-keyed, so that axis passes every one of them and still breaks the decode:
the population measured here is the NAME-KEYED SUBSET. Not hypothetical -- the retracted
instance was half a shape change, since the .dag side also moved List<T> to a Load coproduct.
The ceiling is unaffected: a generated typed decoder makes a shape change a type error exactly
as it makes a rename one. The ceiling is right; only the census is narrow.

Also adopts the four routes by which a compiler-silent class becomes operationally silent:
the path does not run, a fixture bypasses it, a default absorbs the mismatch, or a stale
artifact answers instead.

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

* Close P6's fail-open: every scratch rewrite of a live .dag now refuses on an absent pattern

str::replace returns its input UNCHANGED on a miss, so an ordinary edit to a .dag literal
made interp_recorded_fixture_witness's scratch copy silently unrewritten -- DESIGN section 5's
failure arm that widens instead of refusing. Two arms, only one loud: a missed module-path
rewrite produced a same-name duplicate the module-path collision wall refuses, while a missed
/tmp rewrite made the witness write to the SHARED path instead of its per-run scratch
directory, unreported, landing as cross-run interference in another session's witness.

Being caught by a neighbouring wall is a property of that wall, not of this rewrite, so all
five substitutions across both producers now route through `substituted`, which refuses when
the pattern is absent and names the PATTERN and the SOURCE FILE -- whoever trips it will be
editing the .dag with no reason to know a Rust harness depends on its literal text.

Evidence, 3 passed remotely: a discriminating RED (pattern edited out -> refuses, asserting
the refusal names both), a positive control (pattern present -> substitutes), and a
COUNTERFACTUAL running bare str::replace on the identical input and asserting it answers with
the source unchanged and no error. The counterfactual is load-bearing: `substituted` did not
exist before, so the RED alone would show only that a function which refuses, refuses.
Placement stated honestly in the doc -- these run under cargo test --workspace, not the
required lane, which is --lib only.

The census also records that the primitive is not repository-specific: the script adding that
counterfactual used a Python str.replace whose pattern did not match, silently changed
nothing, exited 0, and produced a green remote run of the two tests already present. `2
passed` rather than 3 was the only tell.

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

* Record the class reproducing on the author, inside the repair, within the hour

Promoted from a parenthetical to its own section, because it is the only observation in the
document that shows the class ARISING rather than being inventoried, and it happened to the
person writing the inventory.

Adding the counterfactual test to the P6 repair -- the repair whose entire subject is
str::replace failing open on a missed pattern -- the editing script used a Python str.replace
whose pattern did not match, because \n and \" escaping differed between script and file.
Every signal agreed with success: the call returned a string (the file, unchanged), cargo fmt
reported "modified 1 file" from an unrelated reformat, the command exited 0, and the remote
run came back GREEN because it ran the two tests that already existed. `2 passed` where 3 was
expected was the entire discriminating signal, caught by reading the run's test NAMES rather
than its exit code.

Three consequences, none about Python. The primitive is not .dag- or seed-specific: it
reproduced in a different language against a different file one hour after the paragraph
explaining why it is dangerous was written, which is the strongest available evidence that the
population estimated here is a FLOOR rather than a ceiling -- the class needs only a
substitution whose failure arm widens, not the seed/authority seam. Assert the pattern is
PRESENT before replacing; the edits that worked did, the one that vanished did not, and that
is the whole difference. And a green run is not evidence a test EXISTS -- a run reports the
tests that are there, never the ones you meant to add, so a vanished edit and a passing suite
are indistinguishable by colour, exit code, or any single-number summary. Same shape as a
vacuous `0 passed; 0 failed; N filtered out`; both are caught by arithmetic, not suspicion.

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

* Record two review-instrument findings, and reframe the census as one seam of a non-seam-specific primitive

The census began as a census of a seed defect. The P6 incident shows the class is not
seam-specific -- it needs only a substitution whose failure arm widens, and reproduced in a
different language against a different file within the hour, on the author repairing it. So
what is measured is ONE SEAM of a primitive that is not seam-specific, and the population is
a FLOOR rather than a ceiling. Stated up front rather than left as an inference from the
incident section.

Separately, docs/plans/review-instrument-observations.md records two findings about the
review and merge-readiness tooling, kept out of the census proper because they are facts
about the instrument rather than about the seed.

(1) stale_provider_count does not fire even where both operands are local. One payload
carried the approving review's sha, the dashboard's own head_sha, and gh's headRefOid as
THREE DIFFERENT VALUES, with stale_provider_count 0 and meets_approval_rule true. The lag
reading -- stale=0 means "not yet noticed", not "judged current" -- is true and worth knowing,
but incomplete: the approval sha differs from the dashboard's OWN head_sha in the same object
and staleness still reads 0. So comparing dashboard head_sha to gh headRefOid is necessary but
NOT sufficient; the reader must compare reviews[].sha to headRefOid themselves. A softer form
is also recorded: an approval can be superseded in PREMISE rather than in sha, as this PR's
was ("census-only, no code" over a head that later added code).

(2) A refused review burns its sha slot invisibly. Review 59066 failed with a worktree
freshness refusal -- correct behaviour, but the slot is consumed and never retried, leaving no
trace in approvals, request_changes or stale_provider_count. The pairing is the finding: one
half of the system refuses to review unless its checkout matches the PR head exactly, while
the other half reports staleness as 0 across a three-sha spread.

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

* Correct two internal contradictions the census introduced when it grew from five primitives to seven (review 59095)

Both findings are real and both were introduced by APPENDING P6/P7 without revisiting the
sentence and column that described the set of five.

(1) "All of them ultimately bottom out in four InterpContext methods" was true of P1-P5 and
false the moment P6 and P7 were added: P6 is a str::replace over file text and P7 is a
subprocess argument vector, and neither touches InterpContext. Corrected -- and the correction
carries the reason rather than just the fact, because it is the census's own thesis: every
earlier sweep was keyed on the interpreter surface, so a name crossing into .dag by any other
route was outside the search BY CONSTRUCTION. That is exactly why P6 and P7 were missed. The
primitives are grouped by the ROUTE a name takes, not by a shared implementation.

(2) The P6 row read "2 producers, 6 call sites" in a column whose other rows count
substitution/decode sites, next to prose saying "all five substitutions". Those are two
different quantities -- five substitutions inside two producer functions, which are reached
from six call sites -- but the column made them read as a contradiction. The row now states
the substitution count in the column's own unit (5, as 3 + 2) and names the other two
quantities inline; the prose and the residue entry agree with it.

Verified against the code: 8 `substituted(` occurrences = 1 definition + 3 in
unique_fs_witness_entry + 2 in closure_scale_witness_entry + 2 in the tests.

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

* Correct my own overstated claim about stale_provider_count: a later payload refutes it

I wrote that the staleness comparison "does not fire even when it has everything it needs",
on one payload. A later payload on the same PR reports stale_provider_count: 1, correctly
marking the provider whose latest review is behind head. So the field is not inert and that
sentence is wrong as written.

Both observations are now tabulated, and the hypothesis that fits them is labelled as a
hypothesis rather than a measurement: staleness is likely evaluated at review INGEST against
the head known then, and stored, while head_sha is read live at query time -- under which the
first observation is a stored verdict that went false underneath rather than a comparison
that failed to run. Distinguishing the two would need a payload sampled at a known ingest
boundary, which has not been done.

The operative rule is unchanged, which is why the correction does not disturb it: a
stored-and-gone-stale verdict and a non-firing comparison are indistinguishable to a reader,
and both report 0 on an approval that is not on the current head. Compute
reviews[].sha == headRefOid yourself.

Also records the same shape for request_changes_count: a codex REQUEST_CHANGES vanished from
the counter after the next push. Its findings WERE addressed in that push, but the counter
would read 0 either way, because a REQUEST_CHANGES is superseded by any push regardless of
whether anything was fixed. The commit and the reply are the evidence; the zero is not.

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

---------

Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
gunbai-bot Bot added a commit that referenced this pull request Sep 3, 2026
dag/gunbc/roadmap/roadmap_authority.dag's annotation opens "roadmap_acceptance_event_history
is the single authority for acceptance facts". No declaration of that name exists in the
corpus. #7791 replaced it with roadmap_acceptance_event_history_load, returning
RoadmapAcceptanceEventHistoryLoad instead of List<RoadmapAcceptanceEvent>, in the same commit
that introduced the JSONL carrier -- and the prose did not move with it.

The bare spelling is a symbol citation rather than conceptual shorthand, and the surrounding
block is what settles it: every other referent in the same annotation is named by its exact
symbol -- roadmap_acceptance_receipts, RoadmapAcceptanceReceiptsProjectionRefused,
gunbc.roadmap_acceptance_history_observation,
AcceptanceHistoryIntegrityRefusedPriorHistoryObservation, git.Core.Show. One name in that
register that resolves to nothing is stale, not informal.

DESIGN section 3's standing rule predicts exactly this rot: a citation nothing checks decays
silently, and no wall reads annotation prose, so nothing went red when the symbol left. The
class is the reason section 3 asks for the symbol rather than the position, applied to a name
that was correct when written.

Annotation-only, so by section 4c it cannot alter any semantic occurrence identity,
resolution result, semantic hash, or emitted bytes.

Found while censusing seed-side spelling-keyed decode (#10180); filed separately because a
stale citation is its own class and would have been lost bundled with a census correction.


Claude-Session: https://claude.ai/code/session_01FbsVmKQEBj7KAwfKEn6JCQ

Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.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