Repository navigation
Close the remaining receipt-continuity production bypass: parse merge-base event data, enforce exact append-only prefix, hash every field - #7791
Conversation
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>
… 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>
…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>
…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>
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>
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>
…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>
Hermetic receipt-continuity fix (option 3)Per loyal-ram-550: hermetic witnesses no longer call Also fixed post-merge rustc break: restored Local hermetic: Surface-readiness witness timings (host measurement, hermetic
|
| 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>
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>
|
Addressed review 48762 (§5 empty-observation narrow on
Pushed in — sent from valiant-bat-462 |
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.
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>
…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.
…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.
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>
…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).
…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>
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>
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>
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>
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>
* 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>
…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.
…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>
…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
…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>
…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
…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>
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>
Summary
Closes the receipt-continuity production bypass: merge-base prior history is parsed from
dag/gunbc/roadmap_acceptance_event_history.jsonlviagit.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 intoacceptance_event_digestv2, and load/projection refusals propagate as typed...Refused{detail}instead of collapsing to empty lists. Hand-Rust JSONL parsing lives inroadmap_acceptance_history_carrier.rsbehindroadmap_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. Nowgunbc.roadmap_site_surface_observematerializes aRoadmapSiteSurfaceBundleonce;ground_service_ready_from_healthz_with_bundle(read, bundle)ingunbc.live_deploy.readinesscompares the independent HTTP read (HealthzEffectiveRead) againstbundle.healthz_body. Fresh-read and stale-read witnesses (roadmap_site_surface_witness.dag) take the bundle as an argument: the healthy fixture usesbundle.healthz_body; the RED control uses a planted body withstale-digestthat parses but does not match the bundle.P0 — authority identity covers the complete projected subject (fixed). Replaced the single
authority_identityfield with three digests onRoadmapSiteSurfaceBundle(roadmap_site_surface_types.dag, computed inroadmap_site_surface_observe.dag):subject_identity— acceptance snapshot +roadmap.md+dispatch.jsonbodies (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 digestsP1 — typed receipts rather than a Boolean call tree (deferred). Witnesses still compose as
roadmap_site_surface_readiness_group_holds() -> Boolwith bundle-parameterized member predicates inroadmap_site_surface_expect. The batch witness (witness_roadmap_site_surface_readiness_materialized_batch_holds) ensures one bundle materialization, butHealthzMemberReceipt/ 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 onelive_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.ymlregenerated after main merge (4109e854,release_binsstep id).ci.ymlnot directly edited by this lane (unchanged except via main merges).v1_interpreter_dispatch_generated.rsregen restored bridge lookups plus two roadmap parser builtin arms.Main merge (
48bb553): mergedorigin/mainat9ce6526(#7834); inheritedjob_idfalsifier witness failures cleared at source.Worker attestation
48bb553.Closes #Ndirective.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 batchwitness_roadmap_site_surface_readiness_materialized_batch_holds(dag/test/claim/roadmap_site_surface_readiness_witness_test.dag) — PASSroadmap_acceptance_history_carrierRust unit tests (cargo test -p v1-compiler roadmap_acceptance_history_carrier) — PASS (4 tests incl.unknown_jsonl_field_refuses)48bb553— pending after main merge