Repository navigation
v1-run-stability M2: Schedule-derived per-module retention - #7129
Conversation
…cle (M2) v1-run-stability throughline M2 — the shelved milestone, trigger fired. Deliverable 1 — schedule-derived eviction (LANDED, green-by-execution). The executor holds the whole discovery schedule, so per-module retention is EXACT: each module's typed state (typed-module result, normalize/ownership diagnostic memos, parse-body + source-hash entries in the process-shared MultiEntryIndex) is refcounted by the count of remaining scheduled entries whose closure reaches it, and dropped when that count hits zero. No threshold, no recency, no GC (DESIGN 4/5). Heads stay resident by construction. A provenance gap RETAINS and COUNTS (RetentionUnknown), never a silent retain-everything. A decrement past zero REFUSES, typed and located, never a wrong verdict against evicted state (content-key recompute-on-miss is the correctness license). Scoped to the private-index serial floor-drain regime (forced_serial=1) — the crawl class the throughline names; the Adaptive shared-store path keeps its behavior as a declared PR-beta frontier, never a silent widen. Policy modeled in dag/gunbc/executor_schedule_retention.dag and mirrored in cli_run.rs, pinned by a lockstep witness (the resolved_graph SizeBounded-cap pattern). The [floor-drain] receipt now carries schedule_evictions and retention_unknown. Deliverable 2 — single-binary claim execution (MECHANISM landed + equivalence proven; live fold-in staged). cli_run::run_claims_in_process runs claims in-process (grouped by entry, one resolve per closure, per-witness discipline via run_claim_measured, declared envelope threaded through unchanged) — the vehicle the run_gunbc_claims_pooled_note reserved, safe to fold in only because Deliverable 1 now bounds the retention the claim_batch child reclaimed by dying. Routing the six runtime-present run_gunbc_claims transport sites needs an interpreter-reentrancy builtin whose end-to-end behavior cannot be verified green in this environment; per 5 that unverified floor-affecting change is NOT landed here — the mechanism is landed and proven verdict-identical to the spawn path, dormant until its arming. The "what stays a process" set already has its authority in gunbc.ci_layer_roots.bin_witness_wet_entries (referenced, not forked, 3). RED controls, all green-by-execution (witness names, not PR numbers): - schedule_eviction_disabled_retains_everything_but_still_counts (#1) - claim_in_process_matches_spawn_verdict (#2, spawn vs in-process, both ways) - schedule_underflow_refuses_typed (#3, corruption -> typed refusal) - retention_unknown_is_counted_per_module_once (#4) - schedule_eviction_drops_at_refcount_zero, ..._end_to_end_on_real_index, schedule_retention_policy_matches_modeled_authority (lockstep) - schedule_retention_exposes_no_tunables / ..._policy_is_fail_closed (in-corpus) Expected post-merge (commitments; a miss is a diagnosis receipt): executor peak RSS ~16 GiB -> ~6-8 GiB, throttle ~4,785 -> ~0, swap -> ~0, ordinary floor ~37-42 -> ~22-28 min, the variance band and 4h crawl unreachable by construction. Proof is RSS, not map-entry counts (the InternTable pin caveat is measure-first, on the existing floor-peak steps). No timeout/envelope/disk-cache changes; governor width>1 not delivered here. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TUqWZP4HTVyUfW4qRqWya1
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
|
Review: Approve Deliverable 1 on substance; three body corrections required before merge (qualitative — CI hasn't run on this head). From the CI-audit session that issued the brief. D1 — the retention keystone — is the strongest version of this mechanism I could have asked for:
Three corrections to the PR body (the body is the record; it must match what shipped):
One measurement note: Sequencing (also on #7128): merge #7128 first — shared Generated by Claude Code |
Author hardening (#7129 review): an accidentally-set env must not silently revert the M2 memory win in CI. index_arm_schedule_retention now emits a loud [floor-drain] SCHEDULE-RETENTION EVICTION DISABLED line at arm time when the measurement pole is active — schedule_evictions=0 is no longer the only tell (a zero read as "nothing to evict" rather than "eviction off"). One line per armed run; the retain-all pole is otherwise unchanged (RED #1 still counts + refuses). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TUqWZP4HTVyUfW4qRqWya1
|
All three body corrections landed (body updated), plus the measurement-pole hardening pushed as
Hardening: Sequencing: holding for #7128 to land, then I'll take a main merge and resolve conflicts against #7128's side (its D1 pool + D2 teardown fast-exit are the shared- Generated by Claude Code |
…efusal) The floor's witness_execution_leg_label fail-closed-refused on the new dag/test/claim/executor_schedule_retention_test.dag entry: every discovered witness must have a row in docs/probes/witness_entry_eligibility_census.tsv, and a new witness has none until the census is regenerated. The per-PR affected-set floor surfaced it (the witness is in this PR's diff). Regenerated the census via its single authority (witness_entry_eligibility_ census_emit — hand-editing the generated TSV is the anti-pattern), bumping the pinned count witness_entry_eligibility_census_entry_count 857 -> 865 to match the true roster. The regen also swept 7 net pre-existing latent-stale rows this branch's corpus had accumulated (10 real witnesses the stale census was missing — ci_heal_job, component_dispatch_button, css_grain, dispatch_presentation, floor_discovery_*, host_axis_caps, media_type, roadmap_sandbox, the moved orchestration_while_emit — minus 3 deleted/renamed files: fleet_converge_emit, roadmap_dashboard_emit, the old orchestration_while_emit path). Those never surfaced per-PR because they weren't in a diff; the falsifier cold sweep would have. Histogram regenerated in lockstep (total 857 -> 865). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TUqWZP4HTVyUfW4qRqWya1
|
CI floor fix pushed ( Fixed by regenerating the census via its single authority ( Heads-up on the diff (why a retention PR now touches the census): the regen also swept +7 net pre-existing latent-stale rows this branch's corpus had accumulated — 10 real witnesses the stale census was missing ( The five Rust RED controls + equivalence remain local-only (nextest off CI); the local Generated by Claude Code |
main advanced (force-updated to 608749d, sharing the reconciled lineage) and its census regens collided with this branch's on the three generated census artifacts. cli_run.rs auto-merged cleanly (main's changes and the M2 ScheduleRetention / run_claims_in_process additions are in disjoint regions) — verified by a clean lib build and green RED controls post-merge. The census is a generated artifact, so the conflict is resolved by its single authority, not by hand: took main's side on all three files, then regenerated via witness_entry_eligibility_census_emit against the MERGED working tree. The merged roster is 880 (main's pinned count 876 was itself stale by ~3 vs main's real corpus, plus this branch's one new witness executor_schedule_retention); bumped witness_entry_eligibility_census_entry_count 876 -> 880 and regenerated TSV + histogram in lockstep. My new witness is present; count consistent. Note: #7128 is NOT yet in main, so its D1 cheap_gate_pool / D2 floor_terminal_fast_exit cli_run conflicts are still a future resolution — when #7128 lands, a fresh main merge resolves cli_run against its side (per the review's sequencing). This merge only brings current main + the census regen. Post-merge verification (green by execution): lib build clean; 6 schedule_ retention RED controls pass; claim_in_process_matches_spawn_verdict passes; census witness green via claim_batch; cargo fmt --all --check clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TUqWZP4HTVyUfW4qRqWya1
…l dependency edges, corrections + new 2c lens-enforcement group Every review claim was verified against the tree before accepting; all load-bearing ones held. Changes: - 2b is now explicitly a PROJECTION of gunbc.v1_deletion_plan (which exists and declares itself the plan authority — the prior block was a partial fork); new ts-authority-converge row extends the carrier with the execution-track bricks (observation contract, divergence root cause, materialization-provider interface, evaluator completeness, executor seams, quarantine rehearsal) instead of restating them here. - Edges now encode the actual dependency graph (RoadmapEdge is dependency-gating per roadmap_spawner node_dep_done, not containment): store-econ -> material-ci and the 2a flip; observation-contract -> flip; evaluator/effects/material/seams -> quarantine -> delete; zero-hand after delete as its own terminal milestone. - ts-native-flip-revert corrected: re-flip is NOT gated only on the store — the frontier dissolve_on requires the divergence root-caused with member + both values named plus a fresh warm per-host receipt (the loudness carrier names failures, it does not resolve them). - ts-effects-providers: the three conflated populations named apart (2 EmittedEffectFamily variants / 9 witness families / ~35 host-fed entries); work item is a typed operation-keyed census; boundary enforcement (host_run_boundary_admission pending) called out so the agency problem does not move into generated providers. - ts-store-econ: provider-interface-first ordering; artifact store, resolved_graph_cache, and #7129 schedule-retention become SIBLING provider rows under the materialization kernel, never one merged store. - ts-material-ci: eval/realize/materialize kept distinct (materialize is analysis-side per its own note; realize_pack advisory); the 0.6 percent unkeyed receipt bounded properly (run 30027001708 partial-run vs committed whole-run ~47.6 — different denominators, record not reprice). - New rows: ts-observation-contract, ts-evaluator-complete (reject arms + missing CPU-deadline/call-depth guards), ts-executor-seams (critical slice vs full hollowing), ts-quarantine (deletion dress rehearsal). - New group 2c (operator request): lens enforcement live in CI — per-lens disposition + receipt (zero inert lenses, not 55-blocking; complexity is AuditOnly/NoConsumerWitness today), fn-body visibility as the real dependency (42 contracts pending reflection; space complexity re-homes off src/v1 before terminal deletion), coverage re-enrollment priced through the D5 budget wall. ROADMAP.md regenerated via main_wet (only ROADMAP.md + authority changed); roadmap_authority witnesses green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg
…review sets, with two claims adjudicated against the tree Integrates every verified correction from the adversarial pass (stacked as #7135 on the pre-rework commit, now absorbed here): - 9-of-11 precision on the frontier retention reasons (complement + meet_join at agreement_red_on_main; the store gates the other nine families' FIRST flip, not the reverted pair's re-flip). - Cache-root truth: ci.yml pins GUNBC_NATIVE_CACHE_ROOT to the runner tool-cache (durable, R2-keyed); what's missing is budget/eviction authority + the executor-grain consult, not 'no store at all'. - Gate-1 gloss corrected to the carrier definition (GateEmitterFixedPoint = the emitter re-emits itself) + prereq_drift_ruling_2026_07_23 cited. - interpreter_surviving_roles named as the roles carrier; the un-rostered wet-workflow surfaces (serve/belt, main_wet, gunbc ci, pre-push, probe bins) become an enrollment obligation AND a delete condition. - Third carrier contradiction recorded (^hand_queue_drain: 7-files prose vs live 25-file roster; pins-not-drain-targets vs the collapse ruling). - 2a census staleness: 876 entries not 744, first_error_class still CensusPending; totality denominator must be derived (group 5a). - ts-store-econ SIZED (IntricacyHigh/VolumeMedium) with Accept + RED, provider shape as ONE CacheLookupResult contract with N sibling provider rows (store tier, resolved_graph_cache, recorded_fixture, #7129 schedule-retention, W3). - 2c upgraded to the five-row v2-door lane (M-L1 door / M-L2 treewide store-priced / M-L3 contract truth / M-L4 complexity scope), keeping this branch's disposition taxonomy and the space-complexity re-home rider; cross-edge ts-lens-treewide -> ts-store-econ. Two adjudications where the reviews conflicted, settled by direct read: (1) Filesystem Delete/List EXIST (filesystem_io.dag operation Delete; artifact_fs_delete/artifact_fs_list in the fs transport) — review 1 was right; the artifact_store_fs transport NOTE is the stale artifact, and ts-store-econ now says wiring-counted-eviction, not modeling. (2) the zero-hand edge direction: full zero-hand stays AFTER the delete (its own terminal milestone); the narrower ^hand_queue_drain brick precedes QUARANTINE per the carrier's prereq ruling — both encoded, neither review's blanket edge taken. ROADMAP.md regenerated via main_wet; roadmap_authority witnesses green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg
…red cli_run #7128 (CI floor endgame D1–D6) landed on main. Merged it in per the review's sequencing note ("resolve cli_run against #7128's side"). In practice cli_run.rs AUTO-MERGED cleanly: #7128's D2 floor_terminal_fast_exit / terminal-path work and the M2 ScheduleRetention + run_discovery_rows eviction + run_claims_in_process additions live in disjoint regions — no textual conflict, and the two are complementary (eviction shrinks the retained store; the fast-exit skips the Drop of whatever remains). host_prelude's cheap_gate_pool likewise didn't collide. Verified the shared territory is sound, green by execution: - #7128's claim_executor battery: 18/18 (walk-exit-code pin, unwritable-receipt RED, batch-wall receipt both directions, lane-promotion battery) - M2 schedule_retention RED controls: 6/6 - claim_in_process_matches_spawn_verdict (D2 equivalence): pass - merged lib build clean; cargo fmt --all --check clean Only the two generated census artifacts conflicted; resolved via the single authority (witness_entry_eligibility_census_emit) against the merged tree — roster 880 -> 881 (#7128 added one net witness), constant bumped and TSV + histogram regenerated in lockstep, my witness present, count consistent. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TUqWZP4HTVyUfW4qRqWya1
…urce-load Acceptance floor on 931c991 timed out at 55 min in the discovery phase (target_width=1, cross_worker_store withheld — the private-index serial regime where eviction arms). Diagnosis from the run: compile-clean finished fine at 4.88 GB (t=1m); discovery then pegged at ~16 GB + 32 GB swap and crawled at swap speed (v2.compiler.normalized_tree typecheck 607s, extdeps.memory.types 505s). Because this PR touches the compiler host (cli_run.rs), the affected set is 602 compiler-witness entries sharing the dominant compiler core, so refcount-by-remaining-entries cannot evict that core until the run's end — RSS does not step down here (the compiler-host §9.2 worst case; the honest metric stays post-merge ordinary-diff runs). This commit removes the one regression I control: index_arm_schedule_retention front-loaded `collect_both_closure_module_names_for_entry` — a per-entry SOURCE LOAD + #6848 both-closure fixpoint — for every distinct entry (~694 here, including the ~92 the affected set skips). Replaced with a cheap BFS over the prebuilt `selection_adjacency` (`selection_closure_live_paths_with_facts`): no source loading, no fixpoint. The refcount is re-keyed from authored module name to REPO-RELATIVE PATH (arming's facts paths ↔ reconcile's `decl_file`), proven aligned on a live index by `schedule_eviction_end_to_end_on_real_index`. The wider selection tier (import + strict reference edges) over-retains rather than premature-evicting a bare-reference-reached module into a recompute-on-miss. Green by execution: 6 schedule_retention RED controls (incl. the e2e real-index eviction 3->2->0), lib build clean, cargo fmt --all --check clean. The deeper RSS-does-not-step-down on shared-closure corpora is the priced known-risk #1, unchanged by this commit. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TUqWZP4HTVyUfW4qRqWya1
|
Acceptance floor timed out at 55 min — diagnosis + a fix pushed ( From the run (job 89335211621): compile-clean finished fine at 4.88 GB (t=1m); the crawl is in discovery — Fixed ( Honest caveat: I can't run the 55-min floor here, so I don't know the arming cut is sufficient — the swap-speed typecheck of the retained shared core is the dominant cost, and my fix doesn't touch that. If the re-run still times out, the shared-closure retention is the real wall, and that's your reserved known-risk #1 call: the throughline-M2 env-strip / scoped-intern rework to free the shared core's Generated by Claude Code |
…ipts Three additions from the #7129 review, aimed at the acceptance re-run: 1. Fact #4 — release the Rc pin (the likely dominant evictable mass). Per-module eviction dropped typed_module_cache entries, but `resolved_graph_memo` retains one assembled ResolvedGraph per entry-closure (up to ~602), and each strong- Rc-pins the very TypedModules being dropped — so the module bytes never freed ("strong Rc pins from elsewhere"). index_schedule_entry_completed now also drops the completed entry's graph from resolved_graph_memo, keyed by its closure subject (`current_closure_subject`, which at the entry-change hook still holds the previous entry's subject). The entry's own InterpContext holds the graph until the next resolve, so this only removes the memo's pin; a rare later entry with the identical closure re-resolves (memo miss, cost only). Verified by the extended e2e RED control: resolved_graph_memo 2 -> 1 -> 0 as entries complete, in lockstep with typed_module_cache 3 -> 2 -> 0. 2. Unconditional ARMED receipt line — proves schedule-derived retention is LIVE on a run (entries + modules_refcounted + evict_enabled), so a later schedule_evictions=0 reads as "shared closure held resident", not "never armed". 3. Early per-entry drain receipt — index_schedule_entry_completed now emits `[floor-drain] schedule-retention: entry=... evicted_modules=N evicted_graph=B schedule_evictions=Z graph_evictions=G retention_unknown=W typed_cache=T resolved_graphs=R` UNCONDITIONALLY (not floor_verbose-gated), so a step-cap timeout still shows eviction working — the walk-end receipt never lands on a timeout. New ScheduleRetention counter resolved_graph_evictions + getters. Green by execution: 6 schedule_retention RED controls (incl. the graph-eviction e2e), lib build clean, cargo fmt --all --check clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TUqWZP4HTVyUfW4qRqWya1
|
Pushed
On the RSS-step-down probe (merge-bar #3) — a mechanics finding that reshapes it: Generated by Claude Code |
… the #7129 swap-crawl Diagnosis (probe receipts, this branch's kit, 52-entry execution slice): arm A baseline peak 7198 MiB with 51 memoized graphs vs arm B (--drop-resolved-memo) peak 5166 MiB — ~2.0 GiB ≈ 40 MiB/graph retained on an 80-module-avg closure slice; arm C (+ --drop-entry-sources --with-eval-context) peak 5165 MiB — entry sources negligible, NO eval-side residue. Scaled to CI's ~200-694-module closures × 602 entries = the observed ~48 GB. Fix 1 — arming grain (#7129 wiring defect): index_arm_schedule_retention moved out of run_discovery_rows (per-group = one-entry schedule: every closure module hit refcount zero at its own entry's completion, evicting the shared prefix the next entry re-typechecked cold) up to the two drain-level sites (Serial branch, width=1 inline drain), armed ONCE over the full sorted schedule. Fix 2 — resolved_graph_memo is schedule-governed at entry grain (modeled schedule_retention_resolved_graph_scope_is_per_entry): subjects recorded at resolve (hit + install), dropped at entry completion; pre-drain rows (the compile-clean gate's whole-tree graph, prelude subjects) cleared once at arming; the completed entry's PROCESS_RESOLVE_STORE rows (wet-witness re-resolve pin) evicted with it. Disabled pole (GUNBC_SCHEDULE_RETENTION_EVICT=0) drops nothing, as before. Receipts: graph_evictions + resolve_store rows on the group/final [floor-drain] lines and arming line (predrain_memo_dropped, resolve_store_rows). Tests: subject-grain bookkeeper RED/GREEN controls, e2e real-index memo assertions, policy lockstep extended to the new modeled flag. Probe bin gains --real-drain (the REAL Serial drain, witnesses executing) for the end-to-end retention A/B. Also dedupes the duplicate [[bin]] measure_discovery_retention manifest row (broke cargo build on the branch as pushed). Co-authored-by: Brian Searls <briansrls@users.noreply.github.com>
…s=1 churn) The Adaptive width=1 inline drain calls run_discovery_rows once per entry-group, so arming inside that function handed each group a ONE-ENTRY schedule: every module in the entry's closure got refcount 1 and evicted the instant the entry finished. That collapsed "keep a shared module resident until its last consumer" into "cold-recompute the shared compiler core once per entry" — the churn that held batch-3 wall at ~41min over the 22min budget while RSS was already bounded (253-module closures re-resolving in 23s, 280 in 32s, over and over). Hoist index_arm_schedule_retention out of run_discovery_rows to the two call sites that own the long-lived process index and know the whole schedule: Serial (the single call, already whole-batch) and the Adaptive width=1 inline drain (once, before the entry-group loop). Now a shared module's refcount spans every entry that reaches it and it stays resident until its genuinely-last consumer's entry completes; only an entry's unique tail evicts when that entry finishes. The per-entry completion decrements against the caller-armed refcount (a no-op when unarmed — the plural/shared-store worker path, its declared PR-b frontier). Mechanism unchanged (ScheduleRetention internals untouched); the eviction grain moves from per-entry to whole-batch. All 11 schedule-retention lib tests green, including schedule_eviction_drops_at_refcount_zero (shared survives to last use) and schedule_eviction_end_to_end_on_real_index. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TUqWZP4HTVyUfW4qRqWya1
…iction-claims-wzwgbf
The census count lives in four hand-synced copies; the emit transport reconciles the module constant + committed TSV at regen but never touches the test file's literal or note. A prior regen bumped witness_entry_eligibility_census_entry_count 880 -> 881 (this branch's executor_schedule_retention_test.dag) while the test kept its hardcoded `== 880`, so witness_entry_eligibility_census_count_holds compared 881 == 880 and reded — a latent drift this PR's affected set was the first to run the witness against. Merge current main, regenerate the TSV/histogram against the merged tree (emit tool authoritatively reports 881; rows shifted with main's witness-file set), and sync the two hand-copies the transport does not own: test literal `== 881` and the note. All three census witnesses PASS by execution (witness_entry_eligibility_census_count_holds / _carrier_paths_holds / _witnesses via claim_batch). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TUqWZP4HTVyUfW4qRqWya1
Records the 2026-07-24 operator decisions: placement by measured warm cost (≤5s rides the PR path, wet admissible if fast + hermetic-classified), DELETE the per-PR selection-control audit step (falsifier cadence is the surviving control), Rust seed stays tested-by-execution in CI. Dependency order D0–D5 with the post-merge #7129 P1s folded into D0 and the run_claims_in_process activation blockers into D1. Doc bound to gunbc.ci_spec.gunbc_ci_spec; dissolves when D3's placement axis lands. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg
…cklist Operator directive 2026-07-24: no staged drag-out — pre-PR probe does all measurement, one redesign PR lands D1+D3+D4+D5 atomically (single revert), D0 close-out routed to the #7129 worker and sequenced first (shared cli_run.rs). Before/after sheet with falsification bounds per row; §9 decision checklist for reviewer sign-off. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg
…iction, staleness, D5 brief in-tree All five findings verified against the tree before applying: (1) parity_window required_consecutive_green_windows=3 + frontier dissolve_on strings contradict the 2a re-pricing (no first flip writable with the falsifier red) — joins ts-authority-converge's stale-prose deliverables as the FOURTH contradiction; (2) ts-store-econ's '#7129 in flight' corrected to merged + PR-0 close-out; (3) rust-suite disposition miscite fixed at its authorities (design_document, ci_spec — DESIGN.md reprojects; actual decl commit_gate_rust_suite_removed_disposition); (4) roster rows corrected to post-pooling reality (6 = 1 union + 4 ingest-overlay by construction per ingest_pool_separation_note + 1 reads-class; batch-6 414s not 12.15m); zero-hand tag repointed at ts-seed-interim; (5) D4 leaves PR-1 — fast-follow micro-PR gated on first green cadence (§9.7). Implementer round folded in: D1b scope refinement (plain resolve_entry_graph — spawns removed, per-entry resolves not), 5s threshold-vs-mechanism caveat (§9.1), and §11 lands the DiffBaseline brief in-tree (previously chat-only). ROADMAP.md regenerated via main_wet. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg
… apart, two operator rulings recorded (#7132) * Roadmap 2b: interpreter-deletion endgame lane — the three deletions named apart, two operator rulings recorded (zero hand-maintained Rust; effects as emitted per-language providers) New section group 2b (Track B past strong self-host), reconciled against the verified state on main rather than memory: - ts-interp-endgame: the delete-v1 conflation split into its three finish lines — compiler (§1 gates, undisturbed), interpreter (2a bulk arc + this lane), host-physics (pinned v2-EMITTED kernel per seed census). - ts-zero-hand: operator ruling 2026-07-23 — hand-MAINTAINED Rust goes to exactly zero; the pinned kernel is emitted from cited models; the hand roster (25 files + module_path_index, growing) becomes a counted burn-down frontier with a new-additions-need-dissolution-triggers review bar; names the two doc contradictions to fix (interpreter-kernel-d collapse-vs-pin either-or resolves to collapse-then-emit; witness-realization P4's claim_executor not-an-emit-target corrected to not-YET per census). - ts-effects-providers: operator ruling — effects are per-language library models (effect providers) emitted like everything else; TargetModel runtime_row class carries the interface; 2 of ~9 host-effect families landed (#7099), rest are rows not architecture. - ts-store-econ: the durable BUDGETED artifact-store tier + floor consultation is the single gate on the 2a flip (every family retained on no_cached_no_evict_carrier); resolved_graph_cache and #7129 eviction dissolve INTO it per kernel-D. - ts-material-ci: materialization kernel in CI (the fold both substrates consume); unkeyed-collapse watch-flag (0.6 percent vs historic 47). - ts-interp-delete: the terminal conditions, with the 2a re-pricing (loud in-PR agreement, no drip-feed windows) and cli_run hollowing explicitly OFF the interpreter critical path. Also: ts-native-flip-revert row updated with the landed divergence carrier receipt (v2.std.native_agreement) — re-flip now gated only on the store. ROADMAP.md regenerated via main_wet (only ROADMAP.md + authority changed; all other artifacts byte-identical). roadmap_authority witnesses green (frame/reset/subgroup/emit-refs). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg * Roadmap 2b rework per review: bind to v1_deletion_plan authority, real dependency edges, corrections + new 2c lens-enforcement group Every review claim was verified against the tree before accepting; all load-bearing ones held. Changes: - 2b is now explicitly a PROJECTION of gunbc.v1_deletion_plan (which exists and declares itself the plan authority — the prior block was a partial fork); new ts-authority-converge row extends the carrier with the execution-track bricks (observation contract, divergence root cause, materialization-provider interface, evaluator completeness, executor seams, quarantine rehearsal) instead of restating them here. - Edges now encode the actual dependency graph (RoadmapEdge is dependency-gating per roadmap_spawner node_dep_done, not containment): store-econ -> material-ci and the 2a flip; observation-contract -> flip; evaluator/effects/material/seams -> quarantine -> delete; zero-hand after delete as its own terminal milestone. - ts-native-flip-revert corrected: re-flip is NOT gated only on the store — the frontier dissolve_on requires the divergence root-caused with member + both values named plus a fresh warm per-host receipt (the loudness carrier names failures, it does not resolve them). - ts-effects-providers: the three conflated populations named apart (2 EmittedEffectFamily variants / 9 witness families / ~35 host-fed entries); work item is a typed operation-keyed census; boundary enforcement (host_run_boundary_admission pending) called out so the agency problem does not move into generated providers. - ts-store-econ: provider-interface-first ordering; artifact store, resolved_graph_cache, and #7129 schedule-retention become SIBLING provider rows under the materialization kernel, never one merged store. - ts-material-ci: eval/realize/materialize kept distinct (materialize is analysis-side per its own note; realize_pack advisory); the 0.6 percent unkeyed receipt bounded properly (run 30027001708 partial-run vs committed whole-run ~47.6 — different denominators, record not reprice). - New rows: ts-observation-contract, ts-evaluator-complete (reject arms + missing CPU-deadline/call-depth guards), ts-executor-seams (critical slice vs full hollowing), ts-quarantine (deletion dress rehearsal). - New group 2c (operator request): lens enforcement live in CI — per-lens disposition + receipt (zero inert lenses, not 55-blocking; complexity is AuditOnly/NoConsumerWitness today), fn-body visibility as the real dependency (42 contracts pending reflection; space complexity re-homes off src/v1 before terminal deletion), coverage re-enrollment priced through the D5 budget wall. ROADMAP.md regenerated via main_wet (only ROADMAP.md + authority changed); roadmap_authority witnesses green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg * Roadmap 2b/2c: absorb the #7135 adversarial pass — synthesis of both review sets, with two claims adjudicated against the tree Integrates every verified correction from the adversarial pass (stacked as #7135 on the pre-rework commit, now absorbed here): - 9-of-11 precision on the frontier retention reasons (complement + meet_join at agreement_red_on_main; the store gates the other nine families' FIRST flip, not the reverted pair's re-flip). - Cache-root truth: ci.yml pins GUNBC_NATIVE_CACHE_ROOT to the runner tool-cache (durable, R2-keyed); what's missing is budget/eviction authority + the executor-grain consult, not 'no store at all'. - Gate-1 gloss corrected to the carrier definition (GateEmitterFixedPoint = the emitter re-emits itself) + prereq_drift_ruling_2026_07_23 cited. - interpreter_surviving_roles named as the roles carrier; the un-rostered wet-workflow surfaces (serve/belt, main_wet, gunbc ci, pre-push, probe bins) become an enrollment obligation AND a delete condition. - Third carrier contradiction recorded (^hand_queue_drain: 7-files prose vs live 25-file roster; pins-not-drain-targets vs the collapse ruling). - 2a census staleness: 876 entries not 744, first_error_class still CensusPending; totality denominator must be derived (group 5a). - ts-store-econ SIZED (IntricacyHigh/VolumeMedium) with Accept + RED, provider shape as ONE CacheLookupResult contract with N sibling provider rows (store tier, resolved_graph_cache, recorded_fixture, #7129 schedule-retention, W3). - 2c upgraded to the five-row v2-door lane (M-L1 door / M-L2 treewide store-priced / M-L3 contract truth / M-L4 complexity scope), keeping this branch's disposition taxonomy and the space-complexity re-home rider; cross-edge ts-lens-treewide -> ts-store-econ. Two adjudications where the reviews conflicted, settled by direct read: (1) Filesystem Delete/List EXIST (filesystem_io.dag operation Delete; artifact_fs_delete/artifact_fs_list in the fs transport) — review 1 was right; the artifact_store_fs transport NOTE is the stale artifact, and ts-store-econ now says wiring-counted-eviction, not modeling. (2) the zero-hand edge direction: full zero-hand stays AFTER the delete (its own terminal milestone); the narrower ^hand_queue_drain brick precedes QUARANTINE per the carrier's prereq ruling — both encoded, neither review's blanket edge taken. ROADMAP.md regenerated via main_wet; roadmap_authority witnesses green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg * Roadmap 2b/2c: apply the 9bfe09c re-review — safe ordering edges, converge-gated execution track, hardened store REDs, link-grain quarantine, 2c totality wall + terminal - Edges: flip now child of census + seams + flip-revert (root-cause precedes the bulk flip); quarantine child of flip; evaluator-complete / executor-seams / effects-providers child of authority-converge (option b: the projection claim true by construction until the carrier gains its bricks). - Hand-drain contradiction resolved: the kernel-D/hand_queue_drain carrier FIXES are ts-authority-converge's deliverable; material-ci re-pointed; terminal zero-hand burn-down stays after the delete. - Census literals de-literalized: histogram carrier is the denominator authority (876->880 in one day proved the point); snapshots dated. - ts-store-econ RED battery hardened: verdict-equality primary + byte-purity on the keyed artifact (sound per C.2 #6576 seed emitter map_keys-free by construction), same-key corruption refuses on read (content_verified_on_read flips true), concurrent puts atomic; the row named as the ForciblySerial bottleneck (2a flip + lens M-L2 + kernel converge on it). - Quarantine at LINK grain: v1_interpreter omitted from the built artifact (cfg/feature or crate split) — source-inaccessible proves nothing about a linked module. - 2c: anchor precision (no lens on the compile DOOR; witnesses run elsewhere); M-L1 scoped to all THREE seed-path compile sites (PR gate, falsifier cold control, regen); M-L2 names W3 typed-module tier as the specific provider; M-L3 counts verified (55 ids / 47 contracts / 44 AuditOnly / 9 uncovered incl. the LIVE Determinism gate) + the registry-contract totality wall first; ts-lens-terminal added as the fan-in node with edges from treewide + contract-truth + complexity-scope. Verification pushbacks recorded: authored_wi sizes with acceptance: ManualAcceptance (not empty — the belt cannot dispatch bar-less); the seed emitter HAS a determinism guarantee by construction (C.2 #6576), so the byte-purity oracle stands on the keyed artifact. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg * Roadmap 2b/2c: apply the green-verification review — five fixes, none structural 1. Flip-revert row twice-corrected: the pair's re-flip gate is EXACTLY the frontier's own dissolve_on (root-cause + fresh warm receipt, NO store clause — the pair rides the cached leg); my earlier correction over-gated in the opposite direction from the original under-gate. One authority: the carrier's strings, never a roadmap paraphrase. 2. ts-effects-providers: the stale ~35 host-fed literal replaced with the classified truth (6 so far, 700 pending, eventual count unknown; histogram carrier is the authority). 3. M-L3 counts reconciled: 46 contracts (44 AuditOnly + 2 Blocking), consistent with 55 − 9; the 47 was a grep over-count. 4. Wet-surfaces roles-roster enrollment now OWNED: added to ts-authority-converge's brick list (it was delete-blocking with no owner). 5. Dispatchability: ts-authority-converge sized (IntricacyMedium/ VolumeMedium — it is the sprint's entry point and concrete carrier work); the 2c anchor-grouping edges removed so ts-lens-door is not gated behind an umbrella that never completes (edges are for real deps only — the 2b block already followed this rule). Trivia: evaluator module path corrected to v2.extdeps.runtimes.*; cli_run line-count de-literalized (~28k and growing); 2b label reframed 'decoupled from strong self-host' to match the content. Regen byte-idempotent; roadmap_authority witnesses green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg * Roadmap 2d + plan doc: progress & observation — process→outcome discipline, one event model, N renderers docs/plans/progress-observation-design.md: the five operator-signed laws (process→outcome no orphans; heartbeat carries identity; recursive dwell escalation; quiet at arm's length; every response true), the P0 event model (Refused distinct from Failed; BlockedOn DERIVED from governor facts; one glyph/material authority incl. the reward-animal rows), and per-context FORMAT CONTRACTS: CI log (append-only, heartbeat+escalation first-class — the reference implementation's gap), interactive TTY, receipt/JSONL (replayable; existing receipts become derived views), dashboard (schema-only), pipe. Reference implementation gunb-ai/gunb.ai tools/terminal studied BY EXECUTION (tests green; driven live in TTY/CI/failure modes): lift contention/nesting/boxes/reward; fix CI silence, Failed/Refused conflation, hand-mirrored emoji duals. Roadmap 2d: ts-obs-anchor + sized ts-obs-model (P0) + sized ts-obs-ci-renderer (P1, flagship = re-render the captured crawl window of run 30044816605) + ts-obs-tty (P2) + ts-obs-census-wall (P3), edges encoding P0→P1/P2→P3. Doc-graph bind added; reachability witnesses 4/4 and roadmap witnesses green; ROADMAP.md regenerated via main_wet. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg * Plan: CI two-tier placement redesign — the 5-second rule Records the 2026-07-24 operator decisions: placement by measured warm cost (≤5s rides the PR path, wet admissible if fast + hermetic-classified), DELETE the per-PR selection-control audit step (falsifier cadence is the surviving control), Rust seed stays tested-by-execution in CI. Dependency order D0–D5 with the post-merge #7129 P1s folded into D0 and the run_claims_in_process activation blockers into D1. Doc bound to gunbc.ci_spec.gunbc_ci_spec; dissolves when D3's placement axis lands. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg * Plan: single-PR delivery structure + expectation sheet + sign-off checklist Operator directive 2026-07-24: no staged drag-out — pre-PR probe does all measurement, one redesign PR lands D1+D3+D4+D5 atomically (single revert), D0 close-out routed to the #7129 worker and sequenced first (shared cli_run.rs). Before/after sheet with falsification bounds per row; §9 decision checklist for reviewer sign-off. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg * Plan: issue-closure checklist worked through by execution; three corrections Verification pass before operator review (2026-07-24): (1) D1 already LANDED on main — #7122 + #7128 pooled the 26 cold children to 6, verified by counting readiness probes in run 30052571652's ci log; plan re-framed, in-process activation split off as deferred D1b with its fail-open confirmed by direct read of cli_run.rs:9580. (2) D4 audit deletion now BLOCKED on falsifier health — the cadence is red 5/5 by crawl-timeout (run 30044928186: cgroup 16.1G pinned, swap saturated, 170m cap), so the per-PR audit is currently the only working selection control. (3) The 5s threshold reuses the existing fast-lane law carrier (thread-CPU budget, typed refusal) — no second authority. §10 checklist: 14 rows, each with status + how verified. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg * Plan + roadmap: apply the #7132 review round — fourth carrier contradiction, staleness, D5 brief in-tree All five findings verified against the tree before applying: (1) parity_window required_consecutive_green_windows=3 + frontier dissolve_on strings contradict the 2a re-pricing (no first flip writable with the falsifier red) — joins ts-authority-converge's stale-prose deliverables as the FOURTH contradiction; (2) ts-store-econ's '#7129 in flight' corrected to merged + PR-0 close-out; (3) rust-suite disposition miscite fixed at its authorities (design_document, ci_spec — DESIGN.md reprojects; actual decl commit_gate_rust_suite_removed_disposition); (4) roster rows corrected to post-pooling reality (6 = 1 union + 4 ingest-overlay by construction per ingest_pool_separation_note + 1 reads-class; batch-6 414s not 12.15m); zero-hand tag repointed at ts-seed-interim; (5) D4 leaves PR-1 — fast-follow micro-PR gated on first green cadence (§9.7). Implementer round folded in: D1b scope refinement (plain resolve_entry_graph — spawns removed, per-entry resolves not), 5s threshold-vs-mechanism caveat (§9.1), and §11 lands the DiffBaseline brief in-tree (previously chat-only). ROADMAP.md regenerated via main_wet. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg * Split hub-file token fixes out of this PR; record the batch-3 budget finding Run 30063529282 refused batch 3 at 24m59s vs the 22m budget: the one-token miscite fixes in ci_spec.dag + design_document.dag are hub files, so selection legitimately ran the full corpus (2,315 witnesses, ALL PASS, RSS healthy) — the honest full-corpus wall exceeds the budget. Attribution clean: same branch without the hub files was green (0d54cdc). Fixes reverted here to ride PR-1 (which pays full corpus anyway); DESIGN.md re-projected from its reverted authority. Systemic implication recorded: PR-1 necessarily touches CiSpec and will face the same wall — §9.8 decision (receipt-noted raise sized by the D2 probe) + checklist row 15. The budget wall itself worked as designed; no widen. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg --------- Co-authored-by: Claude <noreply@anthropic.com>
…ed budget Seven observed full-corpus batch-3 walls (1344-1629s) across five branches, every sampled failure with all witnesses passing and memory healthy; main 12/12 green through #7129's merge. A scalar wall-time budget conflates workload size (diff-proportional by design), host speed, and per-entry cost creep (the actual regression dial, stable ~1.57-2.0 s/entry). Interim: one signed raise to ~1680s on main's row; durable: re-denominated budget (overhead + units x rate[host-class]) riding PR-1's CiSpec work. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg
…ps, lens-door, observation UX contract (#7169) * Plan §9.8: fleet-wide budget diagnosis — no regression, mis-denominated budget Seven observed full-corpus batch-3 walls (1344-1629s) across five branches, every sampled failure with all witnesses passing and memory healthy; main 12/12 green through #7129's merge. A scalar wall-time budget conflates workload size (diff-proportional by design), host speed, and per-entry cost creep (the actual regression dial, stable ~1.57-2.0 s/entry). Interim: one signed raise to ~1680s on main's row; durable: re-denominated budget (overhead + units x rate[host-class]) riding PR-1's CiSpec work. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg * Plan: operator rulings — atomic PR-1 with lens-door reintroduction; two-constant clamp model Witness clamps: 5s hard max per witness (existing fast-lane authority, unchanged) + 1s expected-average as the aggregate coefficient (batch = overhead + units x avg; full corpus ~44min under the 55m cap). Hand-set budget rows delete; constants signed via the existing budget_note discipline. PR-1 is the atomic full rework (no migrations): placement roster + gauntlet split + DiffBaseline + derived clamps + ts-lens-door (v2-door routing, empty_complexity_report stamping deleted, complexity lens AuditOnly -> Blocking with planted-quadratic RED). Pre-PR probe gains the lens-audit inventory so the door flips knowing its red set. D4 rides PR-1 iff a green cadence run exists at landing. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg * Progress-observation plan: §6b addendum — interaction with the CI two-tier rework Model and laws unchanged; CI renderer contract gains three event classes (derived-clamp refusals with their arithmetic, placement dispositions, lens findings), heartbeat keys on clamp units, AttentionLevel grounds on the signed constants, pain point migrates to the gauntlet context, and P1 sequences after the atomic CI PR to avoid double-churning the floor's emit sites. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg * Progress-observation plan: atomic-PR ruling, human-legibility contract, §6c frontend relation One atomic PR (P0-P3 together, after the CI rework PR). Heartbeat: identity-first, vitals-suffix, human units, once/minute max; raw byte dumps are census violations — [floor-memory]'s current shape is the named negative example. §6c: register thesis shared with the site lane; glyph color roles re-ground on gunbc.design.* when it lands (dissolution trigger, not dependency); dashboard belt B = renderer N+1 of the same JSONL stream; gunb.ai terminal a future renderer of the shared schema. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg * Progress-observation plan: tone ruling — plain sentences, real emojis, clock pulse Arm's-length lines are readable sentences, never key=value chains (dense form lives in receipt boxes/files); glyphs are real emojis from the one glyph authority with the reward-animal rows kept; the periodic status line uses the clock, not the heart. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg * Progress-observation plan: selection prominence — the diff→runs chain is the preamble centerpiece Per-file attribution (touched file → selected entries/witnesses), skip count with the falsifier audit pointer, now-vs-later placement split, and widening named in plain language with the causing file. Same selection authority projected per file — no new telemetry. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg * Progress-observation plan: attribution grain is the declaration, not the file Under each touched file, the qualified names the diff actually touches (hunks intersect declaration spans) with change kind, then the witness count attributed at selection's real grain (module closure today, stated honestly); decl-grain selection shrinks the same display when the namespace lane lands it — the UI leads, selection catches up. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg * Progress-observation plan: change-kind coloring + typed no-op taxonomy Git-diff convention colors (green/yellow/red) as glyph-authority rows, textual kind tag always beside color. No-ops are a closed sum — docs-policy, uncovered (a visible coverage nudge), no-decls-touched, generated-artifact, deletion (widens, not a no-op) — a bare unlabeled 'nothing' is a census violation (the Option/None conflation pattern applied to UX). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg * Plan §8: two blessed stage collapses + best/worst-case envelope Regen job folds into the floor as a spec row (serial chain becomes build → ci → deploy; cold control stays a gauntlet row on main); the two receipt gates fold into merge admission. Envelope: leaf PR 6-8 min; whole-repo diff ~35-41 min honest wall (clamp ceiling ~44m, 55m cap), with the cold-build and memory-pathology tails named and the shrink path owned by store-econ/native-flip + W3. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg * Plan §8: delivery restructure — #7162 grows to hold everything Operator ruling: PR-0/PR-1 split dissolved; #7162 absorbs all remaining pieces. Build order: clamps first (self-greening — the floor reads CiSpec from the PR tree). D4's gate restated for the growing PR: a branch falsifier run is the deletion receipt (main-cadence green impossible pre-merge by construction); one green cold run post-D0 triples as D0 acceptance, D4 receipt, and cold-side probe timings. D5's Env.Get mock is its own named part, finished in-PR. Probe: worker-driven workflow_dispatch on fleet slots, serial, >=2 hosts. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg * Parse: interpolation-body errors name the context + the literal-brace escape; witness locks escape semantics The ${...}-in-strings gotcha, root-caused: interpolation triggers on '{' + identifier (the dollar is irrelevant), and a failed interpolation-body parse escaped as a bare expression error ('expected RParen, found Colon') with no pointer to the existing \{ escape — which works, verified by execution (the principled shell form is "$\{VAR:-default}"; no bare-dollar workaround needed). parse_interp_parts now wraps body-parse failures with the interpolation context and the escape hint. Witness battery (4 claims, green by execution) locks the escape semantics via discriminating lengths. STAGED: stage0 regen for the 02_parse change is fail-closed BLOCKED on a main-head breakage this work exposed — regen_stage0's v2-self-compile leg cannot resolve name_resolution_policy_is_namespace_only from 04_env/04_sigs (calls landed in #7093; resolution broken by the 09:0x emit-import-closure wave). Pre-existing on the clean tree, verified by stash + --verify. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg * Parse: close the interpolation fallback fail-open; regenerate stage0; retract the main-breakage alert CORRECTION: main was never broken — the regen 'breakage' was this session's stale debug binaries (name_resolution_policy_is_namespace_only is a native builtin registered post-#7093; a fresh build resolves it, and main is green 12/12 through the 09:0x wave). The prior commit's STAGED note is superseded here. The real second defect, found by reproducing the worker's exact error shape: parse_interp_parts' fallback arm returned SUCCESS on an unexpected token after an interpolation expression (a fail-open — a well-formed node handed back mid-string), letting the caller trip later with the context-free 'expected RParen, found Colon'. The arm now refuses with the interpolation context + literal-brace hint. Verified by execution: the worker's shape now reports the hint; regen_stage0 --verify is byte-clean (regen_divergence_count=0 — no legitimate interpolation in the closure relied on the silent arm); the escaped form evaluates to ${GITHUB_BASE_REF:-origin/main} exactly; 4/4 escape witnesses PASS. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg * DESIGN §5: the workaround rule — an absorbing fallback executed by the author Operator ruling 2026-07-24: noticing you are implementing a workaround IS the line-stop signal — back up, reassess, root-cause or flag for help; the only landing states are the real fix or a declared scaffold with a named dissolution trigger. A workaround is an unmarked scaffold; the marking is the entire difference. Added to the recurring-failure-modes roster as 'unmarked workaround'. Receipt: the ${…}-in-strings dodge — the bare-$ respelling concealed the existing \{ escape and two real parser defects; stopping the line surfaced all three within the hour. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg * Dashboard: raw-text serialization fix + progressive disclosure + register corrections Root cause of the dead strikethrough (operator screenshots 2026-07-24): inline <style> text was HTML-escaped, emitting '.node-superseded > .title' — an inert selector in every browser. Per the HTML spec's raw-text elements (script, style), std.markup's MarkupMedium gains raw_text_tags and emits their text raw; try_serialize_html_source refuses fail-closed when raw-text content contains its own close sequence (same escape class as the dispatch-button inline-script incident — the style copy was never fixed). Page: rows render their LEAD (first ' — '/'. ' segment) with the full brief behind a native <details> disclosure (188 blocks; zero JS). Style: .status Width→MinWidth (the 'superseded' chip overflowed its fixed box into the title); .roadmap/.daily-workspace gain auto side margins (centered); dispatch-btn carries the figure-role border accent (actions carry the accent; status stays quiet). Witnesses: 6 new page claims incl. the unescaped-combinator check and the raw-text refusal RED; 10/10 green by execution; markdown/jsx media unchanged (raw_text_tags: []) and main_wet byte-stable. Named follow-up (belt B lane): deploy refreshes files but the serve path's artifact/process refresh is unproven — the live page lagged tree styling; a served-page fingerprint check belongs in live_deploy. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg * Plan: the roadmap as a daily workspace — readable, observable, tactile Three pillars with exists/missing stated honestly: P1 readability (largely landed 2026-07-24, section-collapse residue); P2 observable dispatch — the stateful workflow: GET /sessions projection from belt B's existing observe half, live row states, Stop/re-dispatch verbs (absorbs the filed ts-dispatch-redispatch), progress depth via the observation lane's stream (renderer N+1 by contract); P3 the feel register — gunbc.design.motion tokens + the acknowledgment law (total assignment, censused like unthemed colors), dashboard as first consumer on existing state flips, sound a named later axis. Doc bound to roadmap_page_for_authority. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg * UX plan: the dispatch button's full lifecycle + the analog root principle Operator-directed exemplar: one control end to end. The story: rest → pressed (ack on DOWN, act on UP) → requested (still, distinct — no pulse; the keyframes wall holds) → spawned (settle beat, morphs into the workflow-stage chip) → working (live stages from P2a, changes animate, steady states still) → done (settle + re-arm; re-dispatch fix in scope) → refused (blocked-travel dip + typed reason). Every edge a tokenized row, totality censused. Root principle recorded for gunbc.design.principles: simulate real analog behavior — every control an individual physical instrument (car-knob rule): travel, mass, detents, mechanical state; still-until-touched is analog honesty; sound = mechanism click, later axis. Register inventory: hover/press rows exist; missing = transform responses, settle_spring easing, lifecycle edges, sessions read. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg * UX plan: binding end-to-end contract for the dispatch exemplar Six person-observable checkpoints; the consumption rule (no register row lands without its consumer in the same PR); the single-line-item workflow representation (stages as detent positions, not a progress bar; history as belt-fact projections); everything else in Pillar 3 explicitly parked; two PRs total with PR-A independently shippable as the anti-shelf-ware test. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg * Observation plan: atomic ruling reaffirmed — completeness is the merge bar Operator 2026-07-24, against the P0-carve-out argument: one PR, P0-P3 entirely, after the CI rework. The controlling rationale is completeness (only finished work merges — landed vocabulary with no renderer is the consumed-by-nothing state the consumption rule forbids); the shared-emit-site rationale is secondary and not load-bearing. #7168 grows to P0-P3 rather than merging alone. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg * Plan §11: D5 discharged — superseded by #7146's gunbc.diff_baseline on main Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg --------- Co-authored-by: Claude <noreply@anthropic.com>
…s debugging it surfaced (supersedes #7162) (#7216) * D0 retention-truth close-out: unpin compile-clean memo, register all-hit keys, arm from loader closure The three post-merge retention defects from the ci-two-tier-placement-redesign §5 review (routed to the #7129 worker) plus the two §7 acceptance controls. Sequenced first: the falsifier cannot go green — and no downstream placement row can cite true retention receipts — until these hold. D0.1 — compile-clean aggregate memo unpin. The whole-tree gate resolved through resolved_graph_from_sources_with_index, pinning the aggregate ResolvedGraph (hence every TypedModule) in resolved_graph_memo for the process lifetime — a large slice of the measured 9.2GB resident floor. Thread a ResolvedGraphMemoShare::{Memoize,Ephemeral} flag: the gate resolves Ephemeral (no aggregate pin); per-entry discovery keeps memoizing. The per-module typed-cache warming that IS the gate's purpose is unaffected. D0.2 — prewarm all-hit registration. try_reconcile_all_cache_hits assembled and returned on all-hit WITHOUT index_record_schedule_module, so a prewarmed run armed retention referencing nothing (completion reported evictions while removing nothing). Record each confirmed hit in the probe, same key forms as the slow path. D0.3 — arm from the loader's exact closure (the #6985 Class-B root, third appearance). Arming used selection_adjacency; the discovery loader load_sources_for_entry_with_pool reaches wider via qualified-projection references from import-bearing files, so those modules were re-cached after eviction and never re-evicted or counted — an invisible resident leak. Arm from the loader itself (not a re-derived BFS that could become a fourth divergence); cost-neutral because the loader memoizes into entry_closure_sources, which discovery reuses. Removed the now-dead selection_closure_live_paths_with_facts. D0.4 — the two §7 acceptance controls. index_schedule_entry_completed dropped the resolved-graph pin unconditionally, so the eviction-disabled retain-all baseline understated peak retention; gate it on evict_enabled. The E2E control armed BEFORE prewarming (the order-blindness that let D0.2 pass green), so it never exercised the all-hit probe; restructure to prewarm -> clear graph memo -> arm -> re-resolve through the probe, and add a real-index retain-all RED. Verified green by execution: 7/7 schedule_retention tests, incl. the two restructured REDs (E2E arm-after-prewarm; real-index retain-all). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TUqWZP4HTVyUfW4qRqWya1 * D3 mechanism: two-tier CI placement axis (PrTier | Gauntlet) with fail-closed admission The placement-axis half of ci-two-tier-placement-redesign.md D3, buildable ahead of the D2 srv warm-cost probe. Placement is modeled as DATA (Placement = PrTier | Gauntlet), never per-site prose, with a FAIL-CLOSED admission law: a check is admissible as PrTier only with (a) a measured warm-cost receipt within the fast-lane budget AND (b) a hermetic/ephemeral classification; unmeasured or unclassified => inadmissible as PrTier, so its only valid placement is Gauntlet. No row rides the fast path by taste. The 5s threshold is REUSED from the single fast-lane authority (gunbc_ci_fast_lane_eval_budget_ms, v2.workflow.ci_floor_plan) — never a second 5s definition (DESIGN §3). Verified green by execution (claim_batch, 4 witnesses): - Gauntlet always admissible - a within-budget hermetic PrTier admissible - RED control: an over-budget (6000ms > 5s) PrTier is refused - RED control: an unclassified PrTier is refused The controls pin the threshold discriminatingly (1600ms admits, 6000ms refuses) and the classification gate (Hermetic admits, Unclassified refuses). Deferred to PR-1 (D2-gated): filling the roster of real checks with measured receipts (flipping rows to PrTier as srv warm-cost lands), wiring the law onto the live check rows, and the Gauntlet workflow split (D3b). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TUqWZP4HTVyUfW4qRqWya1 * D5 DiffBaseline: dissolve the origin/main literal into a typed single authority Per ci-two-tier-placement-redesign.md §11. Introduces DiffBaseline (MergeTarget | PushParent | OperatorOverride{ref}) as the single authority for "which git ref a diff/merge selects against", grounded on the extdeps.git atoms (GitRef, git_remote_ref_parts). resolve_diff_baseline is a pure, fail-closed fold over injected env values — a PushParent with no parent ref REFUSES rather than fabricating a ref. Live consequence fixed (site 1, floor selection): a stacked PR now selects against its real merge target (origin/$GITHUB_BASE_REF), not origin/main. DiffPolicy.base becomes a DiffBaseline; floor_diff_observe.floor_resolved_base resolves it at eval time from GITHUB_BASE_REF, fail-closed to UnifiedDiffFail (the floor widens to the full corpus) on an unresolvable base — never a silent wrong selection. Fork dissolution (no behavior change) — sites 2/3/4 re-ground the same literal onto the authority: merge_admission_produce (merges into main), roadmap_dispatch_actuator (branches from main), ci_workflow Push/PR triggers (main). The ci_merge_base_ref alias and the dead ci_merge_base_diff_range are deleted. Also carries the parked miscite fix (rust_tests_removed_disposition -> commit_gate_rust_suite_removed_disposition) in DESIGN.md / design_document.dag / ci_spec.dag, per plan §3.3. Verified by execution: ci_diff_baseline_witness_test (6/6, incl. the discriminating stacked-PR pair and the PushParent-refuses fail-closed control); ci_spec_witnesses (fetch renders "origin $GITHUB_BASE_REF"; single authority); roadmap_dispatch_actuator_witnesses. ci.yml + DESIGN.md regenerated via main_wet (drift clean; the two floor/regen fetch lines now expand $GITHUB_BASE_REF). floor_diff_observe_witness_test runs green in the floor's wet mode; its eval-time env reads are unmockable under claim_batch strict-hermetic, a PRE-EXISTING harness limitation confirmed by a clean-tree stash run of the same witness (this change adds no new hermetic red). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TUqWZP4HTVyUfW4qRqWya1 * Progress/observation P0: the event model, five laws, one glyph authority P0 of the progress-and-observation lane (docs/plans/progress-observation-design.md, operator-signed 2026-07-23; §6b/§6c doctrine from #7169 folded in). Model only — no renderer, no emit site touched. ObservationEvent = subject (a typed containment path: run ⊃ batch ⊃ entry ⊃ module ⊃ phase) × Begin | Step{k,n} | Concluded{outcome} × measured facts. Outcomes are a closed sum with Refused DISTINCT from Failed — the reference implementation conflates them, which is how a deliberate refusal reads as a crash. Grounded on existing authorities rather than minted: - ancestry reuses std.effect_grant.path_is_prefix (one prefix relation, not a second walk) - over-budget arithmetic calls std.temporal_effect.stall_budget_verdict - change kind projects from std.change.KeyedDiffHunk — no second added/modified/removed enum - glyphs extend std.symbols + extdeps.render.glyphs rows (the one table), never a fork - module_path/source_path carry std's existing representation (std.decl_ref's), with convergence to QualifiedName/SourceRef declared, not assumed Derived, never hand-set: AttentionLevel from a supplied basis (the signed clamp constants — no threshold is invented in this module); BlockedOn from SchedulerHold, which is held in lockstep with the seed governor's HoldReason by execution; T from the heartbeat period the seed actually sleeps, declared a Scaffold with the measured quiet-time distribution as its dissolve-on. Construction over validation: the no-op sum is closed (docs-policy | uncovered | no-decls-touched | generated-artifact | departed-path), so a bare unlabelled "nothing" is unwritable rather than censused after the fact; uncovered derives a visible nudge, departed-path is typed as a widen and not a no-op. Green by execution, with discriminating REDs proven by perturbation: - 28 model conjuncts + 6 lockstep conjuncts PASS - orphaned law row (enforced_by names a missing declaration) → RED - Refused/Failed collapsed onto one glyph → RED (both distinctness and collapse laws) - glyph-table row perturbed → presentation moves → RED (single authority, by execution) Compile-clean attributed: the closure's 47 errors are pre-existing in std/measure.dag (46) and std/effect_grant.dag (1) — identical counts compiling those entries alone; zero attributable to this change. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Review 42157: collapse the duplicate display tables into one authority Addresses the blocking finding on the three coproduct predicates, taking its stronger alternative (dissolve into the canonical surface) rather than only its weaker one (add a disposition receipt). The finding was right about the real defect: observation_class_is_intrinsic_anomaly was a second hand-written table beside observation_presentation, and a witness asserted the two agreed. That witness was validation standing exactly where construction was available — it conceded the tables could disagree and promised to notice. Fix: ObservationDensity (RoutineCollapsible | SummaryAlwaysShown | AnomalyExpanded) is now the one table. collapsible, expands_fully and intrinsic-anomaly are all derived projections of it, so disagreement is unwritable rather than detected. The three display states stay distinct — the run summary is neither routine nor an anomaly, which a single boolean would have forced it to borrow. Disposition receipts added for the remaining structural readers, matching the cited materialization_ladder pattern: outcome/class, subject/grain/hold, and selection no-op. Each states why it is Terminal and names its discriminating corpus rather than asserting terminality. Witness roles now separated and both proven by execution: - w_density_is_the_single_display_authority — the content check; reds when a class's density changes (verified: ClassRefused → RoutineCollapsible reds it, and reds ONLY it, since the projections cannot disagree) - w_presentation_projects_density_rather_than_restating_it plus the two collapse witnesses — construction guards; red when the presentation stops projecting density (verified: hardcoding collapsible: true reds all three) Full suite green: 30 model conjuncts, 6 lockstep conjuncts. Compile-clean unchanged — 47 errors, all pre-existing in std/measure.dag (46) and std/effect_grant.dag (1), zero attributable here. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Review 42166: ground PSI avg10 on std.measure.BasisPoint The finding is correct and the hard-blocker applies: avg10_centi was a percentage magnitude with a scale carried on bare Nat, and the note beside it self-justified the conflation rather than tracking it. Fix consumes an EXISTING carrier rather than minting one, which the corpus had already asked for in advance. std.measure.basis_point_dissolve_on warns: "else a third dimensionless-ratio use-case mints a third nickname" — this module is exactly that third use-case, so minting PerMille or a Percentage quantity would have walked into the failure the row names. BasisPoint's own note declares its semantic axis as utilization ratios, which is what a PSI stall share is. Resolution is exact rather than truncated: the governor reads one decimal of a percentage and a basis point is a hundredth of a percentage point, so 37.5 percent is 3750 with nothing lost. Percent (Dimensionless, One) would have truncated it. Note rewritten to state the grounding and the deliberate non-mint, replacing the self-justification. When the Ratio<Scale> unification that dissolve-on calls for lands, this field follows Percent and BasisPoint onto it with no change of meaning. Suite green: 31 model conjuncts, 6 lockstep conjuncts. Compile-clean unchanged — 47 pre-existing errors in std/measure.dag (46) and std/effect_grant.dag (1), zero attributable here. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Piece 3: derived per-batch floor clamp — delete the static wall-budget list Per ci-two-tier-placement-redesign.md §9.8 (operator 2026-07-24). Replaces the hand-set gunbc_ci_floor_batch_wall_budget_seconds list — a scalar wall budget that conflated workload size (diff-proportional selection), host speed, and per-unit cost creep — with a per-batch clamp computed at run time: clamp_ms = overhead_seconds*1000 + runtime_unit_count * per_unit_ms. The load-bearing row is the discovery witness batch (index 2): 300s + 1000ms per witness, so a full corpus of ~2316 witnesses clamps at ~44min (under the 55-min step cap, with headroom over the observed 1344-1629s walls) while a runaway reds proportionally, instead of the fixed 1320s that redded legitimate hub-file PRs. Fixed-count gate batches carry rate 0 at their measured basis; index 3 (wet corpora) stays a declared fixed overhead pending the D2 probe's wet-per-witness rate. Authority: gunbc.ci_spec FloorBatchClamp + gunbc_ci_floor_batch_clamp_params (index-aligned to the 7 batches; the cover-schedule witness pins the alignment) + gunbc_ci_floor_batch_clamp_note (carries the raise discipline from the kept static-era note). The 5s per-WITNESS max is unchanged — still the single gunbc_ci_fast_lane_eval_budget_ms authority, never redefined here. claim_executor reads the two index-aligned param lists fail-closed, derives the per-batch unit count from batch_results (corpus_witnesses for discovery aggregates, 1 per gate row — the runtime datum the static list ignored), computes the clamp at enforcement, and refuses over-clamp as a typed FLOOR-BATCH-OVER-BUDGET (never a widen). The GUNBC_FLOOR_BATCH_BUDGET_TIGHTEN_MS RED-control hook now lowers the COMPUTED clamp. The receipt emits batch_N_units / batch_N_clamp_ms / verdict; its unit test is updated. Both run_walk call sites carry the new param. Verified by execution: build clean; ci_floor_plan_witnesses green (the three new clamp witnesses + cover-schedule). The receipt verdict unit test and the fixture RED control (budget_red_control_plan; TIGHTEN_MS=0 -> clamp 0 -> the FLOOR-BATCH-OVER-BUDGET refusal) are the e2e enforcement confirmations; the fixture's control witness triggers a whole-tree emit that OOMs alongside a compile in this container, so both run as a clean post-commit confirmation. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TUqWZP4HTVyUfW4qRqWya1 * Finish #7146 adoption: regen ci.yml from merged authority, drop orphaned D5 witness The merge that adopted #7146's landed gunbc.diff_baseline (and dropped my redundant D5 gunbc.ci_diff_defaults) left two remnants: - .github/workflows/ci.yml carried an auto-merge artifact — the regen step and floor step fetched `origin $GITHUB_BASE_REF` (my dropped D5's bare-var form) instead of `origin main` (#7146's authority, which resolves the diff baseline at floor eval-time via resolve_diff_baseline, not at fetch time). Re-running `gunbc ci` regen re-derives ci.yml from the merged ci_workflow.dag, restoring the `origin main` fetch. - src/v2/test/claim/ci_diff_baseline_witness_test.dag imported the deleted gunbc.ci_diff_defaults module (my D5 authority), which would break the corpus compile. Its 6 witnesses are strictly superseded by #7146's landed dag/test/claim/diff_baseline_witness_test.dag (11 witnesses, with stronger fail-closed semantics on PR absent-base). Deleted as dead weight. Co-Authored-By: Claude <noreply@anthropic.com> * P1: the CI-log renderer, with the captured crawl window as its acceptance Second phase of the atomic P0-P3 observation PR (operator ruling: only finished work merges; a landed event model with no renderer is vocabulary nobody can see). gunbc.observation_ci_render projects the std.observation stream into append-only log lines. It computes nothing and holds no telemetry source — every number it prints arrives in an event or a heartbeat sample the process already had — which is precisely what makes replaying a real captured run possible rather than a synthetic fixture. FLAGSHIP ACCEPTANCE, green by execution: the fixture is run 30044816605's actual log, not a reconstruction. Its heartbeat at t=33m carried current=16107200512 swap=34359738368 psi_some_avg10=9.01 and named no subject at all, while the process sat inside v2.compiler.normalized_tree for 606984ms and disclosed that only at walk end. Re-rendered through the escalation law the same window produces named activity: identity-first heartbeats in human units (15.0 GiB, not the raw byte dump), the quiet module surfaced at T, and the memory-reclaim cause surfaced at 2T. Contracts from section 6b in force: plain-sentence tone, real emojis from the one glyph authority with the clock pulse, identity before vitals, durations on every outcome line, refusals restated at the end so log truncation cannot hide them, and relayed subject text neutralized through the existing GitHub guard so a child's stderr cannot mint workflow commands in the parent run. Law 4 made structural: line placement is DERIVED from attention, so a refusal cannot be written into a collapsed group — the group is exactly where a reader will not look. Escalation has two rates: reveal depth grows linearly (one tree level per threshold) while emission points double (T, 2T, 4T), so a window that stays quiet escalates without becoming a per-minute drumbeat, bounded by construction. Three REDs proven by perturbation, as the ruling requires: - planted silent phase (escalation never emits) reds responsiveness - an orphaned Begin reds the watchdog - a Refused placed inside a collapsed group reds Review 42203 (three findings, all correct, all fixed): - ci_gibibyte_tenths respelled the GiB scale factor as a literal; it now consumes std.measure.gibibyte_scale_factor_bytes, and the duration helper consumes seconds_per_minute plus a new milliseconds_per_second added beside its siblings in that authority. A unit authority forked inside a formatting helper is easy to miss because it looks like arithmetic. - the run summary picked the refused glyph whenever refusals+failures>0, so a failures-only run rendered as refused — collapsing at the last line exactly what the outcome sum exists to establish. Failures now dominate the glyph, refusals keep their own, both counts stay in the text. - an unavailable duration silently vanished from concluded lines, breaking the model's own rule that an absent measurement names its cause. It now says so. Each fix carries a witness; the summary fix carries its own RED. Suite green: 31 model, 6 lockstep, 18 renderer conjuncts. Compile-clean unchanged at 47 pre-existing errors, zero attributable here. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * P2: the interactive TTY renderer, a sibling projection of the same carriers Third phase of the atomic P0-P3 observation PR. gunbc.observation_tty_render projects the SAME std.observation stream the CI renderer projects — a sibling, not a successor and not a second model. The two differ only where the medium differs: a terminal can be repainted, so routine progress overwrites one line in place and stays quiet; a CI log cannot, so it appends. Everything they share — the event vocabulary, the density authority, the glyph table, the duration/byte/percent projections, the hold-cause text — is imported from the CI renderer or the model, never re-derived. A witness proves the sibling property by execution: the same event drives both surfaces and moves together. The three upgrades over the reference implementation are INHERITED from the shared carriers, not re-earned: outcome lines carry durations, Refused is distinct from Failed, and dwell escalation is recursive. The reference has none of the three; the TTY renderer gets them for free by projecting the same model. Law 4's asymmetry, expressed here as cursor action rather than group placement: repaint-vs-scroll is DERIVED from attention, so a refusal cannot be repainted away — overwriting it would erase it the instant the next line arrived, the terminal form of burying it in a collapsed group. Required preamble (no anonymous process), BlockedOn inline with named remaining (a bounded estimate prints the time; an unknown one prints why, never a fabricated ETA), and the reward animal on Final drawn deterministically from the one glyph authority so replay is preserved and a non-emoji terminal degrades to a word. Also in this commit: the self-host regen of the seed. P1 added milliseconds_per_second to dag/std/measure.dag, a seed-emitted module, so src/v1/stage0/src/std_measure.rs is regenerated to match — the required same-PR regen for a generated-artifact source edit. Fixed point verified by rebuilding regen_stage0 from the new seed and re-running to zero drift. Suite green: 31 model, 6 lockstep, 18 CI-renderer, 10 TTY-renderer conjuncts. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * P3: the emit-site census wall Fourth and final phase of the atomic P0-P3 observation PR. gunbc.observation_emit_census is the census authority. Every place the floor emits a progress line is either a projection of the observation event stream or a counted frontier row with a reason and a dissolve-on — the same discipline the site lane uses for unthemed colours. EmitSiteDisposition is a closed sum, so a site cannot be half-classified, and there is no third arm for a site the census has not looked at: the roster's completeness is what the witness checks against the seed. The roster carries the structured-tag emit families that exist regardless of the CI rework: [floor-memory], [typecheck-attribution], [gantt], [governor], [measurement]. The named negative example the operator called out — the [floor-memory] raw byte dump — is a rostered frontier row, so the census already carries the very site it exists to kill, with its dissolve-on naming the P1 heartbeat projection that replaces it. Sequencing per the ruling and design section 6b: the CI two-tier rework rewrites the floor's emit sites, so the exhaustive per-print wall over the ~75 raw eprintlns in claim_executor is a declared frontier gated on this PR rebasing over that rework and re-censusing. Censusing sites about to be rewritten is the double-churn the operator ruled out. What lands now is the census model, the roster, and the executable hygiene witness — never a hidden zero: five families migrated-pending, the raw-print residue counted, and the witness holding the roster against the seed so it cannot rot into a lie. Executable, not inert: the witness reads the live seed and reds when a rostered marker has vanished (staleness — proven by a RED control) or when a frontier row lacks a real dissolve-on. The [floor-memory] shape is checked positively — still present, still classified frontier — so the census cannot quietly drop it. This completes P0-P3. Full suite green by execution: 31 model, 6 lockstep, 18 CI-renderer, 10 TTY-renderer, 6 census conjuncts, each with discriminating REDs proven by perturbation. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Piece 3: name the clamp coefficient's measurement basis (operator addition, 2026-07-24) The 1000ms aggregate coefficient now records its basis in gunbc_ci_floor_batch_clamp_note: host class (srv arm64 self-hosted, capped) x the adaptive governor's realized worker width, denominated against the observed 0.58-0.70 s/witness (the 1344-1629s full-corpus fleet envelope over ~2316 witnesses). Naming the basis makes a future width or fleet change a deliberate re-sign of the constant, never a rediscovered fleet-wide red; the ~1.4-1.7x headroom over the observed top rate is exactly the >=~1.6x runaway the clamp catches, with sub-threshold creep owned by the gauntlet's per-cadence s/unit receipt. Co-Authored-By: Claude <noreply@anthropic.com> * Probe (①/②): emit a per-gate warm-cost TSV from the floor's existing timings Instruments claim_executor with write_gate_warm_cost_receipt — one row per gate/claim (eval wall + resolve + combined warm_ms) and a discovery row carrying the per-witness rate — derived from the ClaimResult timings the walk already records (operator ruling 2026-07-24: instrument the existing floor, no throwaway probe workflow). Written to target/floor-gate-warm-cost-receipt.tsv and mirrored to the log as [gate-warm-cost] rows so the placement probe lifts it from get_job_logs on a fleet run. This is the placement roster's measurement basis: a gate rides PrTier only if its measured warm cost is within the 5s fast-lane budget, else fail-closed to Gauntlet (v2.workflow.ci_placement). Every floor run now auto-emits it; run cold-then-warm on >=2 hosts and the roster records value + host basis. Verified green-by-execution locally (single-claim row); the discovery-row path verifies in the next full-corpus CI floor. Fail-closed on a write error, consistent with the other floor receipts; never a verdict term. Co-Authored-By: Claude <noreply@anthropic.com> * Flagship replay as a green witness — the before/after made executable The operator's "show me": proven-by-witness without a visible sample is the fluent-but-unseen trap. dag/test/claim/observation_crawl_replay_test.dag renders the captured crawl window of run 30044816605 through the P1 CI renderer as one assembled block and asserts it by execution: - names the module where the capture was silent ("still in witness discovery: entry 214 of 602, now typecheck v2.compiler.normalized_tree", surfaced at T, the memory-reclaim cause at 2T) - uses human units, never the raw byte dump (15.0 GiB, not 16107200512) - ends in a named refusal summary, not a silent 55-minute timeout observation_crawl_after_block() is the exact function the PR body's after-sample is produced from, so the pasted before/after is a projection of a green run rather than prose. Every input number is read off the real log. The earlier gunbc/observation_crawl_demo.dag (a run-entry that returned a String and so errored on the ProcessExit contract) is replaced by this witness — a green check is worth more than a run-entry that prints then fails. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * Wiring flip (1/n): install the output policy BEFORE the naming walk — kill the [file] firehose The floor's [file] read firehose (2265 lines / ~99% of the log, measured by execution) was the pre-plan naming-hygiene walk reading the whole source tree at the OutputDecision Full default, because install_output_policy ran AFTER the walk (claim_executor.rs order). gunbc.output_policy already models Instrumentation => Suppressed at Normal (CI's default verbosity) and ShellTrace => Condensed — the walk just never saw the policy. Fix: install the policy (and group syntax) FIRST, before the naming walk and every subsequent corpus read, so all host-effect traces are funnelled per the .dag authority. Verified by execution on the minimal smoke plan: [file] read 2265 -> 0, total log 2613 -> 24 lines, claim still PASS (exit 0). The Ambient semantics hold — the policy's divergence rule (ExpectedOutcome/ObservedOutcome) still expands a captured stream on failure, so a red effect is never silenced; only the green firehose is. This is the highest-leverage lever of the observation-emit census flip (the echo class the census targets). Follow-on commits route the display families ([floor-memory], [gantt], [governor], [measurement], [t+..]) through the observation stream as Ambient projections (the ✅/🕐/🚫 format matching #7168's "after" block). Co-Authored-By: Claude <noreply@anthropic.com> * Wiring flip (2/n): render floor phase marks through the observation authority Step 2 of the flip (format), after step 1 (the [file] firehose, volume). The prelude phase marks are the visible display class in the short regen job's log; they now render through the single-authority observation renderer instead of a raw [t+…] byte string the seed would fork the format into. before: claim_executor: [t+86.1s] naming-hygiene walk complete after: ✅ naming-hygiene walk done in 48 seconds - New seed→.dag boundary gunbc.observation_seed_render: primitive args in, a rendered line out — exactly as cli_run.install_output_policy calls output_policy.resolve_channel_policy. A phase concluding is modelled as a Concluded event on a PhaseSegment subject, projected by ci_event_line ∘ ci_render_line, so the FORMAT stays single-authority in gunbc.observation_ci_render and the seed constructs no format of its own. - The raw [t+{:.1}s] eprintln is DELETED, not suppressed (grep-clean for the print). §5: on a renderer-unreachable failure the arm names the degradation loudly and never reproduces the old marker. - Per-phase walls (delta since the last mark), not a running t+, so the log itemizes which prelude phase is slow — the step toward the per-phase receipt keys the ci_spec prelude-coverage-hole follow-up (row a) calls for. - Green by execution: phase_mark_renders_through_the_observation_render_authority resolves the adapter through a real interpreter and asserts human units + the completed glyph + NO [t+ marker (the discriminating RED). The seed→.dag resolve is memoized, so the renderer resolves once and later marks are cache hits. Rust-called-.dag-unimported has precedent (output_policy.dag). Next in the series: the rostered census families. floor-memory (the flagship byte dump) needs its subject feed plumbed first so it renders honestly (entry X of Y, never a fabricated 0 of 0), then gantt/governor/typecheck-attribution, each flipping its census row (CountedFrontierSite → MigratedToObservation) with the witness restructured to assert the raw marker is gone — the "witness fixes" step of flip → witness fixes → roster. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TUqWZP4HTVyUfW4qRqWya1 * Witness fix: roster the observation stack's one wildcard site (non_fold_residue) The progress-and-observation merge (#7168) added observation_ci_render.dag, whose ci_hold_cause_text names the two memory-pressure SchedulerHold variants specifically and gives the other five a generic cause via a top-level wildcard arm — a non_fold_residue site. It landed unrostered because per-PR affected-set selection predict-skips the corpus-read nfr witness (the masking class the roster's dated rows document), so it reds only on a cold whole-corpus sweep (falsifier / merge-to-main), not on the selected PR floor. That is the census wall doing its job on its own author. Roster it (gunbc.non_fold_residue, one FrontierRow, reason + dissolution trigger toward a total match), matching the established masking-class fix and preserving the observation author's design. Green by execution: observation_hold_cause_wildcard_is_rostered asserts the live roster now carries dag/gunbc/observation_ci_render.dag::ci_hold_cause_text via the same host reader the corpus scan uses — reds if the row's key drifts from the scan's {rel}::{fn} key or the hand edit malformed the 126-row list. design_register_lift_parity (the other cold-red thought to be surfaced by the merge) is NOT touched: this branch's gunbc.site.* inputs are byte-identical to main and recent main-push runs are green cold, so it is green here too — not attributable to this PR. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TUqWZP4HTVyUfW4qRqWya1 * Wiring flip (4a/n): the floor-memory heartbeat's seed oracle + golden strings Foundation for migrating the [floor-memory] byte dump to the observation heartbeat. Adds gunbc.observation_seed_render.seed_heartbeat_line: the seed→.dag boundary that takes the primitives the heartbeat thread has (elapsed, batch label, entry position, memory vitals) and projects them through the one renderer (ci_heartbeat_line ∘ ci_render_line) — identity first, human units, no raw byte dump. The subject is batch-grain by construction: the floor walks entries in parallel, so there is no single active module to name, and the primitive interface carries none — never a fabricated per-module "now typecheck X". Green by execution: seed_heartbeat_line_renders_identity_first_in_human_units pins the exact bytes for two samples through the real interpreter: 🕐 33 minutes in — still in witness discovery: entry 214 of 602. memory 15.0 GiB, swap 32.0 GiB, pressure 9.0% 🕐 500ms in — still in self-host fixed-point: entry 0 of 2. memory unreadable (cgroup field unreadable), swap 0.0 GiB, pressure unreadable (cgroup field unreadable) The first is the captured crawl window re-rendered from the seed's own vitals (raw byte value absent); the second proves an unreadable cgroup field names its cause, never a fabricated zero (observation law 2 / §5). These golden strings are the oracle the Rust mirror is proven byte-equal to in 4b. Why a Rust mirror next, not an interpreter call: the heartbeat runs on a detached liveness thread in a memory-constrained context — resolving the renderer there would build a duplicate module index, consuming the very memory it watches (§2), and the thread exists to stay alive when the main interpreter is busy. 4b adds that mirror (proven == this oracle), plumbs the subject feed, wires it, deletes the byte dump, and flips the census row. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TUqWZP4HTVyUfW4qRqWya1 * File finding: shell.Env.Get realized as a printenv subprocess (transport-decomposition lane) Operator-directed finding (2026-07-24), do-not-fix-here. Records in the residual-shell census (§0b) a class distinct from that doc's shell-EMISSION axis: modeled ops whose interface shape is right but whose single hardwired transport is a shell escape where a NATIVE in-process handler is correct — the verbatim §3(b) N×M-adapter tell. shell.Env.Get (extdeps/shell/shell.dag:42) reads an env var the process already holds in its own environment by spawning `printenv` (wet_env_var, v1_interpreter.rs:5096). Reading your own environment is not a host effect; std::env::var is the native handler, chosen when locality is OnTarget, with shell/ssh reserved for a var on another host. Sibling: shell.Which.Check (`command -v`), already in the census. One root, three lanes. Not a floor-time lever (~ms/spawn); filed so the deficit is counted and prioritizable (§6), never absorbed into "it's only a few ms." Its native read is the lane's cheapest first consumer (a pure in-process read, no host_effect_apply even). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TUqWZP4HTVyUfW4qRqWya1 * Wiring flip (5/n): shell-echo §5 split — routine Ambient, failure Anomaly self-describing The [shell]/$ echo class still printed at Normal after the firehose fix: it is the ShellTrace channel at Condensed, not the Instrumentation channel that [file] read rode. But naive "suppress ShellTrace at Normal" is a §5 fail-open — the failure stderr block rides the SAME channel via trace_emit(), so Suppressed would silence failures too. That Condensed was load-bearing. Root (operator's naming): one channel carrying two content classes with OPPOSITE attention — routine scaffolding (Ambient) and failure evidence (Anomaly) — a state-space conflation at the channel grain, exactly what the observation model dissolves by deriving attention per event, not per channel (law 4: routine collapses, anomaly expands). The fix uses the two EXISTING mechanisms, each governing its class — no third decision mechanism: - Routine ($ argv pre-spawn echo + [shell] done exit=… count) → the ShellTrace CHANNEL → Suppressed at Normal (Instrumentation's debug-only shape), Full at Verbose. - Failure evidence (stderr block) → the effect_stream DISPOSITION (SurfaceContent) ALONE, not the channel, so suppressing the routine echo cannot silence a failure. Two upgrades the disposition-gated block gains, both §5-correct now that the count is silent at Normal: 1. SELF-DESCRIBING — the block carries its own `$ <argv>`, so the failing command never scrolls away from its stderr (the pre-spawn echo it used to borrow from is gone at Normal). Strictly better than what suppression would have taken away. 2. SURFACES ON EMPTY STDERR — the block names the exit even when the command wrote nothing, because the routine count that used to carry the exit is now silent. Proven by execution: four-corner effect-stream suite kept; new discriminating RED at_normal_a_failing_effect_surfaces_its_command_a_passing_one_is_silent (passing → None; failing → `$ <argv>` + stderr) + stderr_block_surfaces_on_surface_content_even_with_empty_stderr. Channel witness updated (w_shell_trace_routine_is_debug_only: Suppressed at Normal). Convergence named in output_policy.dag: when shell effects become observation events, trace_emit(channel) stops being the gate and derived attention replaces this split. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TUqWZP4HTVyUfW4qRqWya1 * Revert "Wiring flip (5/n): shell-echo §5 split" — approach was wrong, unbreak the branch This reverts commit 60a4496. Two defects, the second fatal to the approach: 1. Parse break (caught late): the witness carried `//` comments, but daglang has NO line-comment syntax — documentation is `data …_note: String` only. build_module_path_index scans every .dag at install_output_policy startup, so the parse error panicked the whole floor, not just that witness. LESSON: verify .dag by execution before pushing; a Rust-lib test does not exercise the .dag parse/resolve path. 2. The approach itself was wrong (the real reason for the full revert). Making ShellTrace Suppressed at Normal does not just silence the routine echo — effect_stream_disposition is GATED BY channel_decision: match channel_decision(channel, verbosity) { Suppressed => StreamSuppressed // failures silenced Condensed => divergence_disposition(…) // divergence surfaces, agreement counts Full => SurfaceContent } So Condensed-at-Normal is load-bearing TWICE (trace_emit AND the divergence disposition), and host-effect grouping keys on the same channel. Suppressing it is a §5 fail-open (a real failing effect's stderr goes silent at Normal); the Rust test passed only because it read the hardcoded EFFECT_STREAM_POLICY_FALLBACK, masking the installed-policy break. The alternative (route routine → Instrumentation, keep ShellTrace Condensed) leaves empty `##[group]` brackets and buries the failure block inside the collapsed section. FINDING for the redo: the channel↔disposition↔grouping coupling IS the "one channel, two content classes" conflation the operator named — and there is no clean immediate fix that does not touch it. The correct fix decouples the failure disposition from the routine channel verbosity (the "bigger lift" flagged as needing a design steer), which lands back at the operator's "Hold — I'll steer". The self-describing failure-block design (carries its own argv, surfaces on empty stderr) is sound and preserved in 60a4496's history for reuse. Branch returns to the green b35a4b3 state. Shell-echo goes back to HELD pending the disposition-decoupling design decision. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TUqWZP4HTVyUfW4qRqWya1 * Wiring flip (4b/n): floor-memory heartbeat via render_heartbeat_line_mirror Flagship of the observation wiring flip: replace the [floor-memory] raw byte dump with the identity-first 🕐 heartbeat, proven byte-equal to the 4a seed oracle (seed_heartbeat_line). - render_heartbeat_line_mirror: pure Rust mirror of ci_heartbeat_line ∘ ci_render_line — the heartbeat thread cannot call the interpreter (duplicate module index under the memory envelope it watches). Discriminating RED render_heartbeat_line_mirror_matches_seed_oracle pins byte-equality on the crawl-window and unreadable-field goldens. - HeartbeatFeed (cli_run): process-global batch label + entries done/total, armed only when entry_total is known and non-zero (never a fabricated 0-of-0). Updated at batch-enter and at the existing index_schedule_entry_completed per-entry point (SingleClaim path increments per claim result). Discovery fills the total once the roster's entry-group count is known. - Delete the byte dump; keep the regime-disclosure line (marker stays for census hygiene). Flip floor_memory_site → MigratedToObservation; restructure census/lockstep witnesses (frontier 5→4, dump shape asserted gone). - Also: strip invalid // comments from output_policy_witness_test.dag that the shell-echo §5 commit left (dag has no // comments — parse Slash). Co-Authored-By: Cursor <cursoragent@cursor.com> Co-authored-by: Brian Searls <briansrls@users.noreply.github.com> * cargo fmt: claim_executor + cli_run after floor-memory 4b / main merge CI build failed at the fmt --all --check gate (assert_eq! wrapping + HeartbeatFeed Mutex.lock() chain). No behavior change. Co-authored-by: Brian Searls <briansrls@users.noreply.github.com> * Wiring flip: [gantt] → Begin/Concluded PhaseSegment observation projection Compile-path trace_mark and GUNBC_FLOOR_GANTT emit through phase_begin_line / phase_concluded_line mirrors (byte-equal to the seed oracle; interpreter render from inside compile would recurse). Census row MigratedToObservation; raw t_ms/rss_mib shapes gone. Frontier 4→3. Verified via claim_batch on observation_emit_census_witnesses. Co-authored-by: Brian Searls <briansrls@users.noreply.github.com> * Wiring flip: [governor] → ci_hold_cause_text / StatusBlocked observation projection HoldReason emits through seed_governor_hold_line (mirror render_governor_hold_line_mirror); hard/creep/receipt/startup lines lose the raw [governor] key=value shape. Census MigratedToObservation; frontier 3→2. Mirror↔oracle byte equality for PsiPressure and CurrentHighWater. Verified via claim_batch + memory_governor unit tests. Co-authored-by: Brian Searls <briansrls@users.noreply.github.com> * cargo fmt: claim_executor after governor hold oracle RED Co-authored-by: Brian Searls <briansrls@users.noreply.github.com> * Fix runtime_rust.dag: escape Rust format braces for daglang parse daglang treats {ident} inside string literals as interpolation; the gantt mirror's format!("{glyph}…") (and use std::sync::{Mutex,…}) panicked the regen self-compile. Escape as \{…\} so the emitted Rust keeps real braces. Emitter twin resynced; byte-equal to v1_rt.rs. Co-authored-by: Brian Searls <briansrls@users.noreply.github.com> * Wiring flip: [typecheck-attribution] → ModuleSegment+PhaseSegment observation Per-module typecheck Begin/Concluded via typecheck_*_line mirrors (render_typecheck_*_line_mirror); 2s pathology threshold preserved. Census MigratedToObservation; frontier 2→1. Mirror↔oracle RED for the captured crawl fixture module. Verified via claim_batch. Co-authored-by: Brian Searls <briansrls@users.noreply.github.com> * Wiring flip: [measurement] + shell-echo → ObservationEvents (one pass) Measurement peak-RSS/cgroup dumps project through ci_measurement_rss_line (seed_peak_rss_line ↔ render_peak_rss_line_mirror; identity-first, human GiB). Shell host-effects become ObservationEvents: Ambient Begin/Done still gated by ShellTrace; Anomaly Failed gated by effect_stream disposition alone (never silenced by ShellTrace Suppressed), with law-4 idempotent group_end, self- describing `$ argv (exit=N)`, and empty-stderr surfacing. ShellTrace/ disposition tables left unread for the interim Condensed-at-Normal split. Census: measurement + shell MigratedToObservation; tagged frontier count 0; 76 raw eprintln residue recounted. Standing check: claim_batch census witnesses PASS before push. Co-authored-by: Brian Searls <briansrls@users.noreply.github.com> * Fix GeneratedArtifact name collision in observation_model witnesses Whole-tree compile-clean failed: bare SelectionNoOp.GeneratedArtifact collided with v2.std.artifact.GeneratedArtifact and gunbc.generated_artifact.GeneratedArtifact. Mint via selection_noop_generated_artifact in the defining module so the variant resolves unambiguously. Co-authored-by: Brian Searls <briansrls@users.noreply.github.com> * Observation aesthetics: named-intent shell, glyph discipline, census bidir, failure-receipt miss Operator live-log review (run 30142403230) — four pieces in one pass: - Shell subjects are typed service.op intents; argv only in Failed.error. Ambient ShellTrace is Suppressed at Normal (silent scaffolding); Anomaly still surfaces via divergence alone (Quiet no longer forces StreamSuppressed). - Governor receipt uses StatusPulse (not Done glyph); peak RSS / governor / cgroup wrap in one "floor receipts" group. - Census roster grows four CountedFrontierSite rows ([floor-drain], [gate-warm-cost], [receipt], [file]) with a bidirectional hygiene witness. - Undeclared *_failure_receipt companions (NoMainFunction) treat as empty detail instead of stuffing failure_receipt_refused onto ordinary Bool(false) reds. Co-authored-by: Brian Searls <briansrls@users.noreply.github.com> * WIP: Floor #6848: memoize the per-entry bare-reference fixpoint so post-flip * WIP: Floor #6848: memoize the per-entry bare-reference fixpoint so post-flip * WIP: Floor #6848: memoize the per-entry bare-reference fixpoint so post-flip * WIP: Floor #6848: memoize the per-entry bare-reference fixpoint so post-flip * WIP: Floor #6848: memoize the per-entry bare-reference fixpoint so post-flip * Silence Ambient shell on gunbc run; roster #7205 resolve/assembly split tags Merge-admission stamp is `gunbc run`, which never installed output_policy — so ShellTrace fell back to Full and every Ambient Begin/Done still printed despite named-intent subjects. Install policy + group syntax at handle_run startup (same as claim_executor). Census grows [resolve-split]/[assembly-split] frontier rows so #7205's new tags stay bidirectional. Co-authored-by: Brian Searls <briansrls@users.noreply.github.com> * WIP: Floor #6848: memoize the per-entry bare-reference fixpoint so post-flip * Re-merge #7205 tip + native shell.Env.Get (kill printenv Anomaly clutter) Pull the two new #7205 commits (export_index canonical = fold element — kills the O(|bindings|^2) rescan). Route OnTarget shell.Env.Get through wet_env_var instead of printenv so optional floor_diff injections (GUNBC_CI_DIFF_*) no longer paint ❌ Anomaly Failed when unset — reading this process's env is not a host effect (§3(b) / shell-to-dag census 0b). Co-authored-by: Brian Searls <briansrls@users.noreply.github.com> * infer_semantics: unstale the slice control after #7196 admitted list slicing #7196 (bb4347d, on main) deliberately extended `check_slice_access_node` to admit ordered element collections — adding `base_is_list`, widening the refusal arm to `base_is_string || base_is_list`, and returning the base type rather than String on the list arm. `invalid_slice_returns_compiler_error_type` still pinned the withdrawn refusal, so it asserted one diagnostic where the compiler now correctly produces none: assertion `left == right` failed left: 0 right: 1 The witness went stale; the compiler did not. Repointed the negative control at a `Map` base — `ordered_element_collections()` (std_types.rs) holds `List` alone, so a Map is neither String nor an ordered element collection and must still refuse — and added the positive control #7196 admitted but never witnessed: a `List<Int>` slice yields no diagnostic and preserves `List`. Reproduced locally before the change (identical left 0 / right 1) and green after. Both controls proven live by perturbation: restoring the `List` base reds the negative control, expecting `String` reds the positive one. Note on how this reached main green: the witness never ran there. It is a binary witness whose transport (dag/tools/infer_semantics_witness_transport.dag) declares no dependency on v1_compiler_infer_access.rs, so the affected set cannot see the edge; main's run at bb4347d observed an empty diff and skipped 1761 of 2373 witnesses, this one among them. That selection escape is a separate defect and is not addressed here. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013GELyMsZrGgZRrxte2TCsk * gunbc run: add --arg name=value, the missing parameter channel at the .dag seam `Commands::Run` was zero-arity by construction: `run_in_context` (v1_interpreter.rs:1543) ends in `call_function(ctx, &item_node, &[], &env)` — an empty argument slice — while `run_in_context_with_args` has sat twenty lines below at :1564 the whole time, already used internally by claim_executor.rs:166. Only the CLI flag was missing. The consequence is repo-wide and stated in the corpus itself (dag/gunbc/roadmap_belt_actuate.dag:689): "gunbc run --function cannot pass an argument (there is no --arg flag), so the node id enters through the environment". Every value that must reach a `.dag` entry crosses as an environment variable instead — 34 live GUNBC_* names across 77 read sites, including intra-process uses where sender and receiver share a PID (floor_skip_discovery_witness.rs:112-127 set_vars a synthetic diff and reads it back in the same process). The environment wins by economics, not design: adding a modeled parameter costs an edit to `cli_run`'s 29,626 lines of SeedRetained hand-Rust, adding an env var costs one line on each side, and `NamespaceTree` (dag/std/effect_grant.dag:26-31) has no environment arm, so no grant bounds it and no lens counts it. Named-only by construction: a `.dag` entry's parameters are named, so positional order across the CLI boundary would be an unchecked coincidence. A missing `=` or an empty name refuses with exit 2 before the compile runs (§5) rather than guessing a position, and one malformed spec refuses the whole list — a partial parse would silently drop a caller's argument. Values enter as `Value::Str`; no coercion is fabricated here. One path, not two: with an empty --arg list `run_in_context_with_args` passes the same empty slice `run_in_context` did, so the zero-arity path is unchanged rather than branched around. Threaded through the emission authority (src/v1/05_emit_rust.dag:10270 variant, :10495 match arm) and its seed mirror in v1_compiler_emit_rust.rs so regen stays a fixed point. Proven by execution against the built binary, not by typecheck: --arg node_id=roadmap-7 -> ExitSuccess, exit 0 --arg node_id=wrong-node -> callee received "wrong-node" (the value transports, not merely the flag parses), exit 1 --arg node_id -> exit 2, "expected `name=value`" --arg =orphan -> exit 2, "empty parameter name before `=`" --arg ok=1 broken also=2 -> exit 2, whole list refused no --arg -> zero-arity path unchanged Plus six unit tests (three of them RED controls) and `05_emit_rust.dag` compiled through the real pipeline: 0 blocking errors. Known gap, not papered over: the unit tests run under `cargo test`, which left CI on 2026-07-11 (gunbc.commit_workflow rust_tests_removed_disposition). An enrolled floor witness for this channel is a follow-on. Retiring the parameter-shaped env vars onto this flag — GUNBC_BELT_NODE_ID, GUNBC_CI_DIFF_*, CI_FLOOR_EXIT — is also follow-on; this commit adds the channel, it does not yet migrate the callers. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013GELyMsZrGgZRrxte2TCsk * CI floor: give re-homed witnesses a real scheduled lane (FalsifierCadenceJob) Batch 4 breaches its clamp on every run of this PR — 571556ms (srv3-01) / 613864ms (srv2-02) against clamp_ms=420000 at units=74, authority gunbc.ci_spec gunbc_ci_floor_batch_clamp_params[3]. Both batch-4 groups PASS; it is the wall, not a witness. Per the operator ruling, six declared rows move off the per-PR floor to the 4-hour falsifier cadence: the three wave1_gate1_d_* rows (141s + 29s + 27s) and the three affected-set provenance walls (14s + 13s + 13s), measured in the run-30148859947 slow-witness tables. That removes ~237s of eval, landing batch 4 near 334-377s under the unchanged 420s clamp. The vehicle is NOT gunbc.ci_layer_roots falsifier_rehomed_bin_wet_rows. That roster is specifically the bin_witness_wet_entries per-row-budget overflow (constructor bin_wet, budget datum bin_witness_wet_per_row_wall_budget_seconds) and does not model CommitWitnessClaim rows; re-homing through it would mint a second re-home authority. Instead this extends the axis that already answers "where does this check run" — the enrollment surface — with a fourth variant, FalsifierCadenceJob, plus the batch that reads it. The batch lands in the SAME change as the surface deliberately: a surface tag with no consumer is enrollment-by-illusion, which is the state ~54 files under test/claim/long/ are already in (excluded from discovery at dir grain, not walked by the falsifier, enrolled nowhere) and it would present as a clean green diff. gauntlet_lane_enrollment_witness_test reds per-PR if a row ever sits on the surface without reaching a batch. Two entries split at the check_fn rather than moving whole, so each concern keeps per-PR coverage at the cheap grain and loses only the wet grain: affected_set_provenance_producer keeps its four <=161ms fns on the floor, parse_binding_fidelity keeps witness_resolve_distinct_param_bindings_holds. FOUND BY THE WALL, first execution: the doc-reachability witness (doc_graph_has_no_orphan_docs, doc_graph_has_no_dangling_links) rode surfaces: [GitPrePushHook] alone — enforced only by a mechanism this repo has already ruled is not an enforcement authority (opt-in per clone, bypassable with --no-verify, absent in container worktrees, proven ineffective by #6658). Orphaned docs and dangling links had no wall on any CI path. Fixed by adding the cadence surface, NOT by widening witness_enrollment_is_scheduled to accept the hook — widening the predicate until the failure disappears is the absorbing fallback, and would have re-buried the finding that surfaced it. Placement (PrTier | Gauntlet) is the intended end-state authority and is recorded as the dissolve-on, not wired here: PrTier is unwritable without a WarmCostReceipt whose measured_ms is within the 5s fast-lane budget, so wiring it onto all 36 CommitWitnessClaim rows needs a per-row measured receipt and the D2 warm-cost probe has not run. Fabricating those receipts is the fail-open the placement law exists to forbid; defaulting the unmeasured rows to Gauntlet would de-enroll all 36 at once. Encouraging convergence: the 5s law selects exactly the twelve rows measured over 5s and admits every other batch-4 row at <=1s, so placement and this surface agree on today's roster. dag_compile_clean_perturb_receipts_holds is deliberately NOT re-homed. It was retained by the 2026-07-23 ruling by name because it measured 53s, under the 60s per-row budget; it now measures 141s. Re-homing a row that got 2.7x slower answers the wrong question and would zero the deficit's frequency by construction. Its growth is diagnosed separately. Proven by execution: all three files compile clean (0 blocking errors); gauntlet_lane_enrollment_witness_test 3/3 green in 3ms, inside the fast lane. Both claims proven live by perturbation — reverting one re-home reds _rehomed_rows_are_cadence_enrolled_holds, and _is_never_bare_deenrollment_holds was RED against the live roster before the doc-reachability fix and green after. The RED control discriminates a synthetic bare de-enrollment. commit_witness_claim_roster_holds (the #7060 stale-pair class, live) PASS. No generated-artifact drift: the ymls invoke plan functions, so batches compute at run time and the falsifier picks up the new batch. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013GELyMsZrGgZRrxte2TCsk * CI floor: operator-signed interim clamp raise, batch 4 420s -> 540s Signs the margin ruling for the budget family, not just this number. A clamp was doing double duty: merge-refusal threshold ("this must not merge") and growth detector ("something got slower — look"). Tight margins serve the second job and demonstrably worked — perturb's 53s -> 141s growth was caught precisely because the clamp was tight. But they make the FIRST job fire on host roulette, and a breach meaning "you landed on srv2-02" trains the on-call to rerun, which is crying-wolf wearing budget clothes. Policy signed here: clamps are sized to cover MEASURED fleet spread, so a breach means content grew, never which host answered. The growth-detector job moves to per-row trend receipts on the falsifier cadence — that piece is what makes a wider clamp safe, and it is sequenced next behind the perturb diagnosis. Basis for 540: post-re-home projection 377s (worst observed wall 613864ms minus the ~237s the six re-homed rows carried) x 1.2 worst observed spread = ~452s, + ~20% policy margin = 540 (whole-minute grain). Run ids: 30148859947 @ 619bba5 wall_ms=613864 units=74 srv2-02; 30163496549 @ 9f87967 wall_ms=571556 units=74 srv3-01 — identical content, 7.5% apart, which is the spread this funds. Enrollment that grew the batch: NONE. Batch 4 shrank this cycle (units 74 -> 68). The raise buys spread coverage on a batch that got smaller. Not the forbidden widen: batch 4's per_unit_ms is 0, which the clamp note already calls "a declared calibration gap, not a hidden default". 540 funds that gap with a dated, dissolving interim rather than leaving a flat rate to fire on variance. It refuses exactly as before — only the threshold moved, on a stated measurement, not to make a red go away. Dissolve-on: the perturb diagnosis lands (141s = 38% of the remaining batch; returning it toward its 53s basis puts worst case near 350s, under even the retired 420) AND the D2 per-unit rate replaces the flat clamp. The wet-receipt 600s budget (the 707s falsifier red) has the same disease — ten-day-stale basis, zero spread allowance — and the policy above governs it, but its NUMBER is deliberately not moved here: it is gated on its own sccache-vs-growth attribution so the dosing lands with a measurement rather than by analogy. Host spread is not weather: srv1/srv2 still run pre-#7213 sccache units and are typed expected-latent-defective until re-provisioned, so part of the 7.5-20% collapses when the fleet lane re-converges them. Proven: ci_spec compiles clean; witness_floor_batch_clamp_params_cover_schedule, _overhead_all_positive, _rate_all_nonneg all PASS. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013GELyMsZrGgZRrxte2TCsk * Extend the falsifier batch-count pin for the FalsifierCadenceJob batch 779e9dc appended gunbc_falsifier_cadence_witness_batch to gunbc_falsifier_batches() without extending falsifier_plan_structure_holds, which pins the schedule's batch count: let expected_batches = 1 + wet + probe + silent_pick + rehomed (length(xs: batches) == expected_batches) && ... So length was expected_batches + 1 and the witness returned false, redding ci_floor_plan_witnesses and with it batch 3 on run 30166208268. The pin worked exactly as designed — it exists to red when a batch is added without being declared, and that is what it did. Note what this masked: batch 3 failing stopped the walk before dependent batches, so batch 4 never ran on that run and the re-home + 540 clamp are still UNMEASURED in CI. The floor-batch-wall receipt read "3 batch(es), 0 over budget" — green on the batches that ran, not evidence about batch 4. The fix is not a count bump. falsifier_cadence_witness_batch_holds mirrors the silent-pick sibling and checks the batch's actual shape: SelectionApplied, zero scan_dirs, entry count matching falsifier_cadence_witness_entries(), Wet execution mode, spawns_host_compiler, and NOT heavy_whole_tree_resolve. The rehomed sibling is only counted, never shape-checked; this one is both. Proven live by perturbation, not just by going green: flipping the cadence batch's execution_mode from Wet to Hermetic reds falsifier_plan_structure_holds. Verified green together with ci_floor_optin_roster_witnesses, ci_corpus_discovery_flip_witnesses, and all three gauntlet_lane_enrollment_witness_test claims. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013GELyMsZrGgZRrxte2TCsk * Decode \xNN in .dag string literals — no authored colour had ever rendered process_escapes resolved exactly six escapes (\" \\ \n \t \{ \}) and fell through on everything else to concat("\\", next), preserving the backslash. So "\x1b" was never an ESC byte: it was the four characters backslash-x-1-b. Every ANSI code this repo authored in .dag emitted as literal text — extdeps/render/ansi.dag csi_esc, extdeps/render/terminal.dag's reset, and gunbc/ci_render.dag's red/reset. That is the `\x1b[38;5;196m🔥` seen in the TOP SLOWEST WITNESSES table of run 30167957464, which read as a renderer leaking colours onto the CI path and was neither: the raw GitHub log carries real escapes everywhere else, so the defect was the decode, not the target. Fixed at the authority (src/v1/01_tokenize.dag), not the generated seed, via the already-registered from_code_point builtin — no new builtin. The seed file is regenerated by regen_stage0; it is `// Generated by v1 compiler`. Regen produced exactly this one file's delta, so the self-host fixed point held across the change. The witness that should have caught this could not. It compared one undecoded literal against another (code == "\x1b[38;5;34m"), so both sides were equally wrong and it agreed with itself throughout — the vacuous-oracle shape DESIGN §5 names, a check satisfiable by editing the declaration while the realization lies. Its two replacements test properties of the DECODE rather than of the spelling: the first character's code point is 27, and the decoded string contains no backslash. Neither can be satisfied by editing a literal on either side. Both were proven RED against the pre-fix binary before regen was paid for, and green after. Unknown-escape passthrough is knowingly RETAINED, and marked rather than left silent: 🟡 dissolve-on tokenizer_unknown_escape_strict_close. Refusing today would red 142 occurrences across 38 files — overwhelmingly regex fragments (\' 28, \. 19, \| 13, \/ 12, \B 10) that intend the backslash to survive — so the strict close needs a raw-string carrier to migrate onto first, and lands with a corpus-wide compile receipt because it changes parse semantics for every lane that compiles through this tokenizer. Not the four sites a \x-only count suggests. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013GELyMsZrGgZRrxte2TCsk * Layer 1: bind ExpectedOutcome from the call site, not the transport v1_interpreter.rs carried `let expected = ExpectedOutcome::ExpectSuccess` hardwired at dispatch_shell, with a comment saying where the declaration should live was still open. It is now read from the call site. The whole downstream apparatus already existed and was pinned — gunbc.output_policy's four corners, outcome_diverges, the Rust mirror in EFFECT_STREAM_POLICY_FALLBACK. Only the binding was missing, which is why output_policy.dag:105 could already describe the payoff in writing. WHERE IT LIVES, and the two homes that look right and are not: param_env is wrong because param_env IS the request: content_hash_service_inputs iterates op_node.params and looks each up there, so a service-op `input {}` would join the digest and two invocations differing only in what the caller expected would become different cache identities for the same request. The transport is wrong less obviously, and this is the trap. The nearest local precedent — transport_stdin, transport_response_format via find_property — points straight at it. But dispatch_service_wet receives the transport from op_node.transport.or(service_node.transport): the extdeps service-op DECLARATION, shared by every caller. Hanging the expectation there makes it a per-operation fact, so a red control and a genuine check both calling shell.Test.IsFile could not differ — and caller policy declared in extdeps is the DESIGN §3 layer inversion the original comment warned about. It would have compiled and read as green while being wrong twice. So it is a reserved argument on the call node, partitioned out in eval_method_call before bu…
Summary
v1-run-stability throughline M2 — the retention keystone (shelved milestone, trigger fired). Two mutually-enabling halves: exact, schedule-derived eviction of the executor's per-module typed state, and the in-process claim vehicle that fold-in unlocks. The memory thesis is now proven by a live floor run; a grain fix (below) addresses the wall-time that run exposed.
Deliverable 1 — schedule-derived eviction (LANDED, proven by execution)
The executor holds the whole discovery schedule before running a witness, so per-module retention is exact, not heuristic: each module's retained typed state (typed-module result, normalize/ownership diagnostic memos, parse-body + source-hash entries in the process-shared
MultiEntryIndex) is refcounted by the count of remaining scheduled entries whose closure reaches it, and dropped the moment that count hits zero.dag/gunbc/executor_schedule_retention.dag; the Rust realization mirrors it andschedule_retention_policy_matches_modeled_authorityreds on drift.[floor-drain]receipt.resolved_graph_memoentry strong-Rc-pins the veryTypedModules per-module eviction drops, so entry completion also drops that memo pin (graph_evictionson the receipt).GUNBC_SCHEDULE_RETENTION_EVICT=0emits a loudSCHEDULE-RETENTION EVICTION DISABLEDline at arm time.Grain fix — whole-batch arming (after floor run 30053227964)
That run is the acceptance receipt, and it split cleanly.
Memory thesis proven. Peak RSS 9.24 GB, cgroup peak 10.7 GB — under the 15 GiB
memory.high— with zero swap, zero throttle events, zero memory pressure across the full 48-minute floor, witnesses clearing in tens of ms. The prior run pegged ~16 GiB + 3–9 GB swap + ~4,785 throttle events and was killed at the 55-min cap. That regime is unreachable now. This is the Tier-1 memory receipt, green.But it ran in a degenerate grain, and traded memory for time. The Adaptive width=1 inline drain calls the row-runner once per entry-group, so arming inside the row-runner handed each cycle a one-entry schedule (
ARMED: entries=1on every line): refcount 1 on every module, whole closure evicted the instant its entry finished. That collapsed "keep a shared module resident until its last consumer" into "cold-recompute the shared compiler core once per entry." The cost surfaced as a fail-closed refusal —FLOOR-BATCH-OVER-BUDGET batch=3 wall_ms=2471075 budget_ms=1320000— 41 min against the 22-min budget (never a widen), with 253-module closures re-resolving in 23 s and 280-module in 32 s, over and over.Fix (this push): hoist the arm out of the per-group row-runner to the two call sites that own the long-lived process index and know the whole schedule — Serial (the single call), and the Adaptive width=1 inline drain (once, before the entry-group loop). A shared module's refcount now spans every entry that reaches it and it stays resident until its genuinely-last consumer; only an entry's unique tail evicts.
ScheduleRetentioninternals are untouched — only the grain moves, per-entry → whole-batch. All 11 schedule-retention lib tests stay green (incl.schedule_eviction_drops_at_refcount_zero— shared survives to last use — andschedule_eviction_end_to_end_on_real_index).Grain-fix receipt (actuals from the next run replace predicted; a miss is a diagnosis receipt):
entries=1× 694 groupsentries=694× 1If the wall stays high with RSS bounded and the grain fixed, the residue is algorithmic, not memory-shaped — the pre-registered PR-C diagnosis fork, with the memory variable cleanly removed.
Census sync (same push). The census count lives in four hand-synced copies; the emit transport reconciles the module constant + TSV at regen but never the test file's literal/note. A prior regen bumped the module 880→881 (this branch's
executor_schedule_retention_test.dag) while the test kept its hardcoded== 880, sowitness_entry_eligibility_census_count_holdscompared 881 == 880 and reded — a latent drift this PR's affected set was the first to run the witness against. Merged current main, regenerated the TSV/histogram against the merged tree (emit tool authoritatively reports 881), and synced the two hand-copies the transport does not own. All three census witnesses (_count_holds/_carrier_paths_holds/_witnesses) PASS by execution.Deliverable 2 — single-binary claim execution (MECHANISM landed + proven; live fold-in staged)
cli_run::run_claims_in_processis the in-process claim vehicle (pooled by entry, one resolve per closure, per-witness discipline viarun_claim_measured, declared envelope threaded through unchanged). It is proven verdict-identical to the spawnedclaim_batchpath —claim_in_process_matches_spawn_verdict, both directions.It ships DORMANT — this PR does not replace the spawned child. Routing the six runtime-present
run_gunbc_claimstransport sites needs an interpreter-reentrancy builtin whose own CI run is the verification this session cannot produce, so the live fold-in is a named follow-on PR, not attempted here (§5 — an unverified, floor-affecting, envelope-touching change is not landed). Folding claims in is safe only because Deliverable 1 now bounds the retention the child reclaimed by dying.RED controls — all green by execution
schedule_eviction_disabled_retains_everything_but_still_countsclaim_in_process_matches_spawn_verdictschedule_underflow_refuses_typedretention_unknown_is_counted_per_module_onceschedule_eviction_drops_at_refcount_zeroMultiEntryIndex(arm → resolve → complete → real cache drop)schedule_eviction_end_to_end_on_real_indexschedule_retention_policy_matches_modeled_authorityWhere they run: the Rust RED controls run under
cargo test— local-only by policy (nextest was removed from CI 2026-07-11; the whole Rust suite is a local dev check). The modeled-policy assertions DO execute in the CI floor as discovered hermetic witnesses (schedule_retention_exposes_no_tunables/schedule_retention_policy_is_fail_closed). The CI-executed consumer of the mechanism is the live-floor acceptance run (the merge gate).Merge gate
cli_runon the current tip.ARMED: entries=<N>once (not per-group), and no admission/verdict changes. The census witnesses must be green (verified locally; the live floor confirms).Non-goals (unchanged)
No timeout/envelope changes; no disk-cache arming (the named follow-on this PR unlocks); governor width>1 not delivered; the
walk_memobatch-walk retention and the D2 live fold-in are named follow-ons. The Adaptive plural/shared-store worker path keeps its current behavior (no schedule eviction) as a declared PR-βSpacePackedfrontier.