Repository navigation
One tree, one resolve: floor stages consume the compile-clean computation (levers 2/3/8 of #7106) - #7122
Conversation
Log-diff receipts on fleet runs decompose workflow vs ci-job wall time and name discovery resolve, self-host gates, and #7030 effectful recovery as the dominant buckets. Co-authored-by: Cursor <cursoragent@cursor.com>
Re-derive run 29976989996 and five comparison arms; name per-stage duplicate work (per-entry resolve walks, ingest re-scan, cheap gates after compile) and price top levers in minutes without floor behavior changes. Co-authored-by: Cursor <cursoragent@cursor.com>
Unblocks doc_reachability pre-push gate for the measurement-only audit PR. Co-authored-by: Cursor <cursoragent@cursor.com>
…PR diff The layering batch-1 red on 652ec65 was caused by our redundant cli_run.rs NFR backfill (already landed on main as #7114), which forced a whole-tree compile-clean on .rs and a heavier batch-1 path. doc_graph_roots bind row checked: import-bearing file, module_path in string literal — no new layering edge (not 7080-class). PR diff vs main is now docs + doc_graph only. Co-authored-by: Cursor <cursoragent@cursor.com>
…tion (redundant-work ledger levers 2/3/8) STEP-1 model (gunbc.ci_materialization ci_floor_resolve_receipt_note, Receipt 5): the compile-clean receipt's typed store — the main-thread process_shared_index the eager install warms — is the consumable fact; later floor stages consume it, and a stage that cannot be served is counted, never a silent re-walk. Declared cold-resolve count 4 -> 3 consciously (the note's own rewire discipline); ci.yml regenerated to match. Lever 3 (executor realization): batch_unit_lane clause (c) — a resolve-group sharing an (entry, execution_mode) some batch resolves on the memo path is colocated there, so the batch-0 cheap-gate group rides the store the eager compile-clean install warmed instead of re-deriving the same closure cold on a spawned thread (where thread-local process_shared_index is invisible); the compile anchor and emit-host then consume its walk_memo context as hits. No schedule fact added or reordered (#7088 batch-0 ordering untouched). Lever 2 (transport realization): run_gunbc_claims pools ONE gunbc child per call (gunbc.Cli.RunClaims; argv grammar gunbc.cli_invoke.cli_claim_spec 'ENTRY::FUNCTION', decoder parse_pooled_claim_spec — one grammar, both directions) instead of one child per claim row: N rows over K distinct entries pay one pool build + K entry resolves against the child's per-process shared store (resolve_entry_graph), full-ledger conjunction preserved by construction. Residue (one pool build per call; overlay manifests are composed input) counted in the redundancy ledger; dissolve-on the W3 cross-process content-keyed store. Dead per-claim argv helper gunbc_claim_run_args deleted (zero consumers). Lever 8 (partition authority): CompileCleanPartitionBoundary.entry_roots = witness_layer_roots — the roster enumerates exactly the tree the whole-tree gate compiles, never witness_layer_roots.first() ('dag' only). Closes both directions of the roster-subset asymmetry: src/v2-only .dag diffs scope to their entry closures instead of falling to the no-shard-intersection whole-tree baseline (run 29976989996's shape), and a dag-rooted touch now selects affected src/v2 importers on scoped runs. Totality glob follows the boundary (both roots; join fixed for newline-trimmed shell stdout). Every fail-closed arm unchanged. Proven by execution: executor lane tests (promotion + RED control + mode keying); pooled claim-spec grammar tests; floor_fast_plan_scopes_src_v2_entries_ both_directions on the live tree; live-tree shard totality over both roots; pooled overlay run of the real_ingest leg (3/3 PASS — stub supersession through the pooled resolve path); typed-op witnesses incl. RunClaims red control; cargo fmt clean. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F2Rc3TWb8FFexdVQDNbb44
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F2Rc3TWb8FFexdVQDNbb44
|
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. |
|
CI-trigger anomaly + dispatched run. GitHub created no Workaround in place: Generated by Claude Code |
…the bin_witness_wet roster typed_witness_invocation_test.dag is discovery-excluded by pattern; every fn in it rides the explicit bin_wet roster. The two pooled-op witnesses added with gunbc.Cli.RunClaims landed excluded-but-unrostered and the floor refused loudly (WITNESS ADMISSION REFUSAL cause=UnexecutedDeferredWitness count=2, run 29993198712) — the admission invariant working as designed; these rows give them their executing consumer. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F2Rc3TWb8FFexdVQDNbb44
…dence (run 29995111208) Green pull_request floor on this branch, same probe format as the #7106 baseline: compile_clean 3.58 -> 2.89, cheap gates 10.15 -> 4.65, compile-gate consume 27s -> 8ms (walk-memo hit), ingest 12.15 -> 5.24, reads_real_bytes 3.30 -> 3.13, discovery unchanged by design (lever 1 out of mandate); resolves_total 3 == declared 3 (the resolve-receipt gate's own green line). Ledger rows cheap_gates_batch1 / compile_gate_consume flip to consumes-receipt; source_root_ingest_gate to necessary-first-touch (pooled), each with this run id as evidence. Batch-4 exec-corpus anomaly (52min, the interp_recorded_fixture row) is footnoted in the row's class and attributed in the PR thread — not a mandated stage; bisection in progress. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F2Rc3TWb8FFexdVQDNbb44
|
Acceptance receipts — run 29995111208 (pull_request, green, srv1-04) vs baseline 29976989996:
TSVs updated on the branch ( One anomaly, not in any mandated stage: batch 4's 55-row exec corpus went 1.3 → 53.2 min, dominated by Merge-readiness per the brief: floor green ✓, verdict-identical ✓ (all gates/witnesses PASS; the one prior red was the Phase-0(b) admission wall correctly catching two unrostered rows, fixed in Generated by Claude Code |
|
#7120 interaction (branch now carries it via Generated by Claude Code |
|
Falsifier landed: red, main-side, OOM. Run 29999281277 (main@ Two consequences: (1) the batch-4 anomaly attribution stays open — the OOM kills the falsifier before its corpus can read the Generated by Claude Code |
…-caching-xn4ynp # Conflicts: # docs/plans/ci-floor-time-45-72-band-attribution.md # docs/probes/ci_floor_lever_ranking_2026-07-23.tsv # docs/probes/ci_floor_phase_attribution_2026-07-23.tsv # docs/probes/ci_floor_redundancy_ledger_skeleton_2026-07-23.tsv
…agent history sweep, receipts throughout)
docs/plans/resolve-regression-journey.md answers the operator's 2026-07-23
question ('what fundamentally keeps regressing? we have fixed resolve
several times and it comes back worse') from a 65-event dated fix ledger
over origin/main since 2026-06-25 plus the in-tree receipt docs, with an
adversarial verification pass:
- The measured trajectory: ~8m floor (pre-flip) -> discovery flip x12
demand (#6438, 2026-07-09) -> timeout bounce 30..270 raised to fit ->
#6848 (+18m time AND the 1GB/process parse baseline, RSS 6.5->20GB,
2026-07-20) -> mechanism-correct follow-ups recovering less than priced
(M1 ~0% on capped hosts) -> the 4h memory.high crawl -> #7120/#7122/#9.
Three mechanisms wear one trend line: added demand, retention to the
cap, cap lost.
- The five grains of one duplication (per-thread/-entry/-run/-process/-PR),
discovered serially, fixed independently, no shared already-computed
authority — instance-patching as validation where construction
(ComputationIdentity) is the fix.
- Verified: NO floor-time regression gate exists (the 5s law is enforced
but scoped to eval; the regression mass lives in the exempted infra
carve-out); 5+ merges since 07-01 added corpus-denominated work with
zero merge-time cost pricing.
- What ends it, in order: the cost wall (budget refusal + regression
gate), the identity authority, the retention lane, cost pricing at
merge.
Registered in doc_graph_roots (reachability suite 7/7 PASS by execution).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016fdkaGGLUKpLRwwqxp5sLg
…hild class); interim gunbc-run claim grammar deleted as a duplicate; interp_recorded per-PR enrollment reverted R1 (child-pool lever, walls honored): run_gunbc_claims realizes as ONE claim_batch child per call — claim_batch's own pre-existing pooled --entry/--function grammar, one shared MultiEntryIndex per process, per-claim verdicts NAMED by its PASS/FAIL-per-function loop, no short-circuit, exit nonzero iff any failed. The gunbc run --claim flag, gunbc.Cli.RunClaims op, and the ENTRY::FUNCTION spec grammar this branch had introduced are deleted: claim_batch already owned the pooled-claims surface (one grammar, not two). Cheap-gate transports consolidate to one call per GATE (layering 7 rows -> 1 child, was 7 cold children; extdeps 5 -> 1, was 5; the former cross-call && short-circuit inside a gate is deliberately removed — every claim reports on every run, stated in the transport notes). The pooled child stays a SEPARATE process by design — never in-executor evaluation (the executor is the 16GiB-pinned process; the child dies and frees). extdeps' private roots datum dissolved into witness_layer_roots (a nickname). R2 (batch-4 disposition at the witness grain): interp_recorded_fixture's per-PR enrollment REVERTED to OfflineLocalRecipe — its ~13+ claim_batch children each cold-index the whole workspace root (2556s on run 29995111208, the dominating row of the 53.2min batch-4 wall); too heavy for the falsifier wet lane's 600s receipt budget as-is, so local-recipe with a pooled/scoped re-enrollment dissolve-on rather than an enshrined nightly refusal. Proven by execution: pooled child 10/10 PASS over 4 entries in one process (incl. the argv-shape witness pinning claim_batch_claims_argv's exact output); RED control exit 1 with the failing claim NAMED and later rows still reporting; ingest overlay leg 3/3 through the claim_batch loader (stub supersession held); whole-tree --target dag compile green; artifact drift clean; cargo fmt clean; executor lane + scope-plan test batteries green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F2Rc3TWb8FFexdVQDNbb44
…5m fits the 55m cap; wet 53.2->10.82; cheap 3.08 and ingest 6.90 land as counted residue vs the 2min targets) Fresh phase-attribution row from the post-rework pull_request run 30009199696 (head 6fe8d02, all gates green, resolves_total 3 == declared 3, peak 15.0GiB cgroup-post): ci_job 99.2->61.1min, floor step 49.5min under the 55min cap; wet wall 53.20->10.82min from the interp_recorded de-enrollment (surviving pools 20+54 rows, eval 9.35min serial). The two R1 acceptance targets MISS and are recorded as counted residue in the redundancy ledger, mechanism named per row: cheap gates 4.65->3.08min (2 pooled children at ~88s/~64s — each claim_batch child pays a corpus-denominated MultiEntryIndex build regardless of roster size); source_root_ingest 5.24->6.90min, a +1.66min REGRESSION vs the interim vehicle (4 children at ~82-118s; the claim_batch child costs ~25-30s/process more than the deleted gunbc-run vehicle — loader-parity gap on top of the shared corpus-denominated index). Dissolve-on for both: the W3 cross-process content-keyed store (or claim_batch loader parity), never a silent re-widen. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F2Rc3TWb8FFexdVQDNbb44
…ections 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
… 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>
Attribution of where a gunbc run / claim_batch invocation actually spends wall clock, measured on the fleet and re-derived locally by stack sampling. Headline, from run 30485116707 job 90691769205 re-derived to the second: the merge-admission gate spends 108.1s to perform 0.09s of work. 103.7s of that is spent BEFORE the declaration begins evaluating — 38.8s of source load, 4.3s of compile, and a 64.9s gap between compile.analyses finishing and the declaration starting. The tax is fixed, not entry-dependent. A probe module whose entire body is ExitSuccess, resolving 9 sources with 82ms of total compile, costs 80.6s CPU-bound against --source-root dag. Adding a 16x larger entry closure (9 -> 144 sources) moves the wall ~7%. Widening the source roots to 2,677 files measured FASTER than 1,428, so the cost is not file-count-linear. gdb sampling (24 stacks) attributes it to two whole-corpus passes that run before the entry's sources are touched: build_module_path_index_uncached -> parse_module_binding -> tokenize (~40%, full-tokenizes every .dag file to read one module header line), and extend_sources_to_both_closure_fixpoint -> tree_bare_census_for_root -> pool_parse -> tokenize plus census_with_resolved_fn_sigs (~55%, the #6848 bare-reference fixpoint, still live, a whole-tree parse plus inference per invocation). Both caches are process-local, so every new process pays in full. The same disease appears at the per-entry grain inside the floor: ~33.5s between affected-set arming and witness verdict (four consecutive cycles: 33.52/33.73/33.23/33.6s) of which compile is ~0.64s and the witness evaluation itself is 0.1-0.5 milliseconds. Corrects ci-floor-time-45-72-band-attribution.md section 9 on mechanism: its "~25 serial cold children" is historical — run_gunbc_claims now batches claims into one claim_batch invocation, so #7122's pooling landed. That doc's rank-1 lever was already marked STALE and its section 4 asked for a re-diagnosis of the discovery walk; section 4 here is that re-diagnosis. Pricing levers against the old mechanism would repeat the exact staleness failure that doc closes with. Measurement only — no behavior change in this note. Scoping stated: the CI attribution to those two passes is by analogy to the local sample, not measured on a fleet host; confirming it needs a sampler on the runner. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N7LfCpidMuDjV3FxYUHv1K
…7446) * Demote the affected-set selection control to the falsifier cadence Measured on the per-PR ci job: 10m09s median (n=6 green runs, range 8m41s-10m32s) — 29.9% of the ci job and 22.4% of the PR critical path, against the 80s local figure gunbc_ci_selection_control_step_note cited when the step was wired per-PR in 2026-07-10. The gap is the fleet-pressure envelope becoming the realized cost, not an outlier. The suite is hermetic: both diff channels are injected fixtures (GUNBC_CI_DIFF_UNIFIED / GUNBC_CI_DIFF_NAME_STATUS), so it reads no per-PR state — running it per-PR and running it on a schedule test the same thing. That is what makes it cadence-relocatable at all. It now rides gunbc.falsifier_workflow beside the compile-clean and native-cache cold controls, ordered BEFORE ci_floor_peak_pre_step so its residency is not attributed to the floor's cgroup peak receipt, and before the 170m falsifier step so a broken selector reds in minutes. Coverage delta, stated rather than elided: a reintroduced widen (the cli_run.rs entry_file_touched class) now reds within one 4h cadence window instead of before its own merge — the same window ci_spec_discovery_flip_note already accepts as the bound on a selection miss, on the same lane. This is a RETURN TRIGGER, not a dissolution: re-enroll per-PR when the suite runs in seconds. The cost is the 25-cold-child class (ci-floor-time-45-72-band-attribution.md section 9), so per-gate pooled children or witness-realization to native bins is what buys it back. Backstops stay the exact step-sum + prelude on both sides: ci 115 -> 100, falsifier 290 -> 305. Witnessed by execution: selection_control_rides_falsifier_not_per_pr_ci (asserts the step name is present in expected_falsifier_yml and absent from expected_ci_yml) with a discriminating RED control — re-adding the step to the ci job steps list fails the witness, reverting greens it. ci_workflow_witness_holds pins the ci backstop at 100 and explicitly rejects the old 115; falsifier_backstop_is_step_sum_plus_prelude carries the relocated term. Generated-artifact drift gate green (byte-idempotent fixed point); both workflow YAMLs parse. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N7LfCpidMuDjV3FxYUHv1K * Measurement receipt: the pre-evaluation whole-corpus invocation tax Attribution of where a gunbc run / claim_batch invocation actually spends wall clock, measured on the fleet and re-derived locally by stack sampling. Headline, from run 30485116707 job 90691769205 re-derived to the second: the merge-admission gate spends 108.1s to perform 0.09s of work. 103.7s of that is spent BEFORE the declaration begins evaluating — 38.8s of source load, 4.3s of compile, and a 64.9s gap between compile.analyses finishing and the declaration starting. The tax is fixed, not entry-dependent. A probe module whose entire body is ExitSuccess, resolving 9 sources with 82ms of total compile, costs 80.6s CPU-bound against --source-root dag. Adding a 16x larger entry closure (9 -> 144 sources) moves the wall ~7%. Widening the source roots to 2,677 files measured FASTER than 1,428, so the cost is not file-count-linear. gdb sampling (24 stacks) attributes it to two whole-corpus passes that run before the entry's sources are touched: build_module_path_index_uncached -> parse_module_binding -> tokenize (~40%, full-tokenizes every .dag file to read one module header line), and extend_sources_to_both_closure_fixpoint -> tree_bare_census_for_root -> pool_parse -> tokenize plus census_with_resolved_fn_sigs (~55%, the #6848 bare-reference fixpoint, still live, a whole-tree parse plus inference per invocation). Both caches are process-local, so every new process pays in full. The same disease appears at the per-entry grain inside the floor: ~33.5s between affected-set arming and witness verdict (four consecutive cycles: 33.52/33.73/33.23/33.6s) of which compile is ~0.64s and the witness evaluation itself is 0.1-0.5 milliseconds. Corrects ci-floor-time-45-72-band-attribution.md section 9 on mechanism: its "~25 serial cold children" is historical — run_gunbc_claims now batches claims into one claim_batch invocation, so #7122's pooling landed. That doc's rank-1 lever was already marked STALE and its section 4 asked for a re-diagnosis of the discovery walk; section 4 here is that re-diagnosis. Pricing levers against the old mechanism would repeat the exact staleness failure that doc closes with. Measurement only — no behavior change in this note. Scoping stated: the CI attribution to those two passes is by analogy to the local sample, not measured on a fleet host; confirming it needs a sampler on the runner. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N7LfCpidMuDjV3FxYUHv1K * Receipt: the invocation tax is allocation throughput, not repeated work Second measurement pass, correcting this note's own first pass and its lever ordering. Reading the corpus is not the cost: 8,505,296 bytes across 1,428 files in 0.044s cold (193 MB/s). Parsing the same content runs at ~0.5 MB/s on real corpus files and ~0.16 MB/s on dense generated code — 400-1200x slower than reading it, against 50-500 MB/s for a competent tokenizer. Three hypotheses tested and refuted by execution: - Quadratic in file size: NO. Holding content constant at ~4,800 fn decls and varying granularity, a 30x file-size increase costs 1.5x, not 900x (8x600=2.23s, 24x200=1.86s, 80x60=1.57s, 240x20=1.45s, 800x6=1.61s). Cost is linear in total bytes at a bad constant. - Linear in file count: NO, it tracks bytes. - The non-ASCII is_ascii() fallback: NOT DOMINANT. Corpora differing only in one marker character inside a string literal measure 1.339s vs 1.264s and 2.681s vs 2.857s — a 0-7% penalty, though 35% of real .dag files take that path. What it actually is: allocation. 15 of 18 resolved innermost-frame samples (~83%) land in the allocator or memcpy — _int_malloc, libc_free, tcache_get_n, malloc_consolidate, checked_request2size, memcpy_avx512, and Arc::make_mut. char_at returns a heap-allocated String PER CHARACTER and is called per character from the scan loop, alongside im::Vector persistent collections doing copy-on-write. This is the model/realization fork at the string layer: modeled value semantics transliterated into the seed instead of realized as byte-cursor operations over a UTF-8 slice. That reframes the is_ascii() branch (11 sites in the seed, 8 in v1_rt.rs). It is a silent content-dependent performance fallback — nothing typed, counted, or located, so the slow arm's frequency is zero by construction and never ranks for fixing — and a second representation of "index into a string". Deleting the fallback buys ~7%; deleting what it is a fallback FOR, the String-per-character interface, is the ~400x lever. Same edit, and a byte cursor is encoding-correct for both arms so the branch disappears rather than being optimized. Lever ordering corrected accordingly: caching the whole-corpus passes was the wrong first move — it would preserve a 0.16 MB/s parser behind a hit rate. DESIGN section 6's bare-minimum-cost standing rule says a proven cost-shape defect is always fixed regardless of realized n; this is that proof. Fix the constant, then cache what remains. Section 10 records this note's own corrections, including that two earlier probe configurations were measuring a parse abort rather than a parse (a '//' comment before the first item declaration panics for_each_parsed_module_binding); every timing in 4.1 is now guarded by an explicit parsed/PARSE-ABORT assertion. Measurement only; no behavior change. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N7LfCpidMuDjV3FxYUHv1K * Root-cause the parse quadratic: one unmigrated function, not the .dag move Supersedes section 4.1's "linear, not quadratic; non-ASCII ~7%". Those probes used generated files with NO string literals, so they exercised only the migrated scan path. Re-measured with one literal per file, warmed, the per-doubling ratios approach 4x (2.41, 2.80, 3.06, 3.59) and non-ASCII is a consistent ~2.1x on top; throughput collapses 627 -> 134 KB/s ASCII and 430 -> 63 KB/s non-ASCII. The .dag migration is correct and should not be reverted. src/v1/01_tokenize.dag carries SourceRef with a pre-decoded code-point array, and the whole main scan (source_code_point, source_len, source_substring, source_scan_while, source_skip_ws) indexes it directly — O(1) per step, no ASCII special case. Emission is faithful: the model's 6 char_at sites map one-to-one onto the generated .rs. What did not come along is process_escapes_loop, which takes source: String rather than SourceRef/source_chars. Per character it calls string_length and char_at, each rescanning the whole literal (is_ascii, then byte index or chars().nth(pos)) giving O(L^2) per literal with the non-ASCII arm O(pos) and un-SIMD; and it does list_push(acc, ch) into an im::Vector (v1_rt.rs aliases Vector as Vec), so each push is copy-on-write through Arc::make_mut. It runs unconditionally on every string literal from all six scan_string arms. Why this corpus loads it: 30% of corpus bytes (5,841,277 of 19,732,620) are inside string literals; 38 files carry a literal over 2,000 chars; the worst is 14,178 chars in design_document.dag, and all top-10 are non-ASCII because they are prose notes with em-dashes. 15 of the 20 largest files are non-ASCII. Why no wall caught it: 01_tokenize.dag is in no lens roster (it appears only as a NameResolutionGap frontier row in a plan doc), though a recursive list_push accumulator is exactly the complexity_accumulator_copy class. And the text_lookup_work_counter instrumentation — itself emitted from .dag, with an honest cost model naming the quadratic — is feature-gated to src/v1/tests and is called from substring only (v1_rt.rs:287,291), never from char_at. The counter watches the migrated path; the quadratic lives in the unmigrated one. Fix shape recorded: give process_escapes_loop the interface the rest of the file already uses, fold the accumulator, then point the counter at char_at and roster the module so the next unmigrated interface reds by execution. Measurement only; no behavior change. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N7LfCpidMuDjV3FxYUHv1K * Receipt: the complexity lens is drivable per-file, infeasible corpus-wide Answers whether the repo's own complexity lens can be run manually over src/v1 and src/v2 entirely. Mechanically yes, at current cost no. Driving it: v2.lens.complexity_accumulator_copy.roster_gate takes an arbitrary live-tree path (file_gate / file_suspect_count / file_refusal_count) via the offline_roster_gate_claim_batch_recipe shape. The probe module used was deliberately not committed — any *_test.dag under a source root is picked up by CI's discovery walk, so landing it would add ~3-minute live-tree witnesses to every PR. Result by execution: file_suspect_count("src/v2/compiler/01_tokenize.dag") == 0 FAILS. The lens finds copied-accumulator suspects in the v2 tokenizer, confirming section 11's static reading of lex_repeat_step / lex_delimited_step, where list_append(left: state.lexeme, right: consumed) runs once per character giving O(L^2). Not obtained: exact counts and the src/v1 figures — the bracketing run was stopped before completion and is recorded as such. Cost: 34,208 ms resolve plus 184,828 ms witness (3m05s) to analyze ONE 556-line file. Extrapolated serially that is ~67 hours for src/v1+src/v2 (1,298 files) and ~140 hours for the whole corpus (2,726) — and linear extrapolation understates it, since cost is superlinear in file size and the largest file is 12,961 lines against a 237-line mean. This is the unstated reason the roster gate is operator-ruled OFFLINE with a two-file roster; the scope was cut to what the cost allowed and that reduction is not legible as a coverage gap anywhere. The self-referential finding: ingest_findings parses its target with the v2 parser interpreted under v1, so every audited file pays both quadratics at once. The complexity lens cannot be run over the corpus because of the complexity defect it exists to detect — which settles sequencing, since fixing the parsers is what makes whole-corpus enforcement affordable. Two coverage gaps named: Unclassifiable refusals ride the Accepted channel and never gate (which would explain how the v2 tokenizer compiles while the lens still finds something in it), and src/v1/*.dag never reaches the gate at all because the seed is compiled by v1 via regen_stage0 rather than through v2's compile door — the latter stated as a topology hypothesis, not yet executed. Measurement only; no behavior change. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N7LfCpidMuDjV3FxYUHv1K * Accept review corrections: retract the char_at-per-character claim in place External review of this note landed five corrections. Four accepted and applied AT THE POINT OF THE CLAIM rather than appended, because an error that is only superseded in a later section still misleads whoever reads the earlier one. 1. char_at is NOT called per character by the ordinary tokenizer scan. Verified by inspection: all six char_at sites in src/v1/01_tokenize.dag are process_escapes_loop (3) plus all_hex_upper_in_range, sentinel_prefix_matches, sentinel_suffix_matches. The ordinary scan converts once via chars(source) and indexes SourceRef.source_chars through source_code_point / source_scan_while. Section 4.1's sentence claiming per-character char_at from tokenize_loop/scan_next_token is retracted in place. The consequence is load-bearing: the dense-code benchmark has no meaningful string-literal content and still measures ~0.16 MB/s, so char_at cannot explain the ordinary path's cost at all. 2. "Allocation-bound, not algorithm-bound" was too broad. Corrected: the ordinary path is allocation-bound and linear; the string path is allocation-bound AND quadratic. 3. The first lever is renamed from "byte-cursor ops" to frontend CONSTRUCTION realization. Rc<Token>, Rc<ScanResult>, make_token's text clone, per-token owned String, and the Rc<im::Vector> path-copying accumulator are distinct allocation sources the char_at framing obscured. 4. The "fix the constant, then reduce invocations" sequence was too serial and is retracted. The cost model is multiplicative, so deleting exact duplicate producers (merge-admission fusion, the doubled regen_stage0 --verify, no-op heal) proceeds in parallel. The distinction kept: deleting duplicated work is always in order; persisting the result of slow work is what should wait. The fifth is accepted with a scope note. The 0-7% non-ASCII figure is measured on the ordinary path, which never calls char_at; on the path that does, section 11 measures 46% at L=4,000 and 111% at L=64,000, growing with literal length as an O(pos) chars().nth predicts. Both figures are needed. Also contributes a resolve-split receipt from the section 12 lens run, which is differently shaped from the ~96%-reconcile_assembly diagnosis the review cites: load=34,651ms dominates with parse=1,400ms and reconcile_assembly=3,253ms on a cold single-entry claim_batch leg. Recorded rather than reconciled — it supports the review's own point that cold process starts and pooled floor entries are separate lanes, and demonstrates why every probe must record binary, execution leg, source roots, and corpus identity. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N7LfCpidMuDjV3FxYUHv1K * Register ci-invocation-fixed-tax-attribution in the doc graph The run 30503392667 ci job red was exactly 3 doc-reachability witnesses: the receipt doc landed with no in-edge, so doc_graph_has_no_orphan_docs (both surfaces) and doc_graph_is_clean returned false — the no-parallel- ledger wall doing its job on this branch's own addition. The bind row anchors the doc to gunbc.ci_workflow's gunbc_ci_selection_control_step_note — the demotion disposition this receipt is the measurement basis for — with the dissolution trigger the doc's own header declares (pre-evaluation passes persisted or derived from the containment tree; the demotion's return trigger consumes its measurements). Verified by execution locally: doc_graph_has_no_orphan_docs PASS on both dag/test/claim and src/v2/lens surfaces, doc_graph_is_clean PASS, ci_workflow_witness_holds PASS, falsifier_backstop_is_step_sum_plus_prelude PASS. Generated artifacts byte-stable under main_wet regen with a binary rebuilt from this tree (which also carries origin/main merged in, clearing the heal skew on this branch and picking up the upstream BUILT_FROM heal remedy). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N7LfCpidMuDjV3FxYUHv1K * Correct the demotion's carrier claims, pin placement structurally, condense the receipt Accepts the operator review of this branch. Three corrections to claims that were stated more strongly than the evidence supports, plus the structural witness the presence test could not express. DETECTION WINDOW. The note claimed a reintroduced widen "reds within one 4h cadence window". That is too strong and is retracted. The falsifier is queue-not-cancel with a 230-minute job backstop class, and the selection control sits after the prelude and release build, so a change landing just after a run has passed that control waits for that run's remainder, plus queued-run startup, plus the prelude and build in the next run — a sum that can exceed one cadence period. The honest contract is "detected by the next COMPLETED falsifier control", with the worst case derived from those terms. What bounds the damage is unchanged and restated: a widen is bounded by the status quo, and the divergence is counted when detected, never absorbed. RETURN TRIGGER. It named a mechanism — "per-gate pooled children" — that had already landed while the suite still measured minutes, so the note was prescribing a stale fix as its own re-entry condition. Replaced with an OUTCOME: re-enrol per-PR once a named receipt shows the entire control step, spawn to verdict, on the CI fleet rather than a local host, consistently below a seconds-scale ceiling across a full falsifier window. Whichever mechanism buys that is the lane's business, not this note's. STRUCTURAL PLACEMENT WITNESS. The existing test asserts the step name appears in falsifier.yml and not ci.yml. That proves the cadence moved but passes for every permutation of the same steps, while the placement is load-bearing twice over: the control must sit AFTER the release build, because it executes the release-built floor_skip_discovery_witness and has nothing to run before it, and BEFORE the cgroup peak pre-read, because that pair brackets the floor's memory measurement and a step inside the bracket attributes its own residency to the floor's peak receipt. Three witnesses now pin it over the Step LIST, reusing step_display_name — the accessor gunbc.ci_materialization already reads steps through — rather than re-matching the Step coproduct. Exactly-once is asserted in both directions: one occurrence on the falsifier, zero on the per-PR ci job. Proven discriminating by execution, both defects injected: - control moved inside the peak bracket: the two order witnesses FAIL while the old presence test still PASSES — the review's point demonstrated - control enrolled twice: the exactly-once witness FAILS while the old presence test still PASSES RECEIPT CONDENSED, 592 -> 198 lines. Its ranked-lever table had gone circular, naming byte-cursor string work as lever 1 while its own later sections had both located the real root in one unmigrated frontend function AND explicitly accepted "frontend construction, not byte-cursor ops" as the correct lever name. The ordering is now frontend construction first, with byte-cursor realization named as downstream of it and the fuller lever (SourceCursor, TokenBuilder, FrozenTokenStream, span-carrying token text) stated rather than hidden behind the char_at framing. Every accepted correction is preserved in place, including the retracted char_at-in-ordinary-scan claim, the allocation-bound scope split, the two-sided is_ascii figures, the parse-abort probe discipline, and the contributed resolve-split. The six-pass investigation remains in this file's git history. The doc-graph dissolution text is updated to the outcome-based trigger so the bind row and the carrier agree. Verified: doc_graph_has_no_orphan_docs, doc_graph_is_clean, ci_workflow_witness_holds, falsifier_backstop_is_step_sum_plus_prelude, falsifier_concurrency_queues_not_cancels, falsifier_yaml_projection_evaluates, falsifier_artifact_path_is_workflow_file, and the four selection-control witnesses all PASS. Generated artifacts byte-stable: no workflow yaml drift. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01N7LfCpidMuDjV3FxYUHv1K --------- Co-authored-by: Claude <noreply@anthropic.com>
One tree, one resolve: the floor's later stages consume the compile-clean computation (levers 2, 3, 8 of #7106)
Baseline: #7106's TSVs (
docs/probes/ci_floor_{phase_attribution,redundancy_ledger_skeleton,lever_ranking}_2026-07-23.tsv) — merge #7106 first; this branch carries its docs-only baseline until then (a main-merge after #7106 lands collapses the overlap).STEP 1 — Model (the code below is derived from this)
The consumable fact, associated — not minted. The compile-clean pass's output is modeled where the floor's duplicate-computation debt already lives:
gunbc.ci_materialization's counted-resolve law (ci_floor_resolve_receipt_note, Receipt 5).FloorCompileCleanReceipt::Compiledmeans the main-threadprocess_shared_index— the typed resolved-graph store the compile-wall-endgame W3 lane names, and the duplicate-work/ComputationIdentity census already rows asPROCESS_RESOLVE_STORE— is warm forwitness_layer_roots. Later floor stages consume that store. In ComputationIdentity vocabulary: the whole-tree resolve is ONE materialization; every later same-input resolve in the same process isShareatStructurallyIdenticalgrade (fixed snapshot, same roots — the purity assumptionwalk_memoandtyped_module_cachealready ship on); a stage that cannot be served is a counted necessary-first-touch, never a silent re-walk. The module-identity lane contributes the key language (path⇄module binding, content-hashSourceRef) — joined, never fused, per its own §6 alignment note.Stage classification (the #7106 redundancy ledger's own vocabulary):
V2Tree/DagTreetagging, v2-modeled ingest activation over host-supplied bytes — facts the v1 compile receipt cannot carry by design)Each fix is an extension of ONE existing authority:
gunbc.ci_materialization's counted-resolve law: declared count 4 → 3 (Receipt 5, the note's own "the rewire PR declares the count's drop consciously" discipline). Realization:claim_executorbatch_unit_laneclause (c) — any resolve-group sharing an(entry, execution_mode)that some batch resolves on the memo path is colocated there, so one entry resolves exactly once per walk, against the store the eager compile-clean install warmed. Derived from the plan's declared profiles only — no schedule fact added or reordered (CI fail-fast: cheap-gate early batch (SIMPLE declared membership + dissolution trigger) + event-scoped stop policy #7088's batch-0 ordering untouched;witness_cheap_gates_only_in_early_batchstill pins it).tools.host_prelude; the ingest gate's walk is the module-identity lane's named cost):run_gunbc_claimspools one child per call viaclaim_batch's pre-existing--entry/--functiongroup grammar (argv authoritytools.host_prelude.claim_batch_claims_argv, shape pinned by thetyped_claim_batch_pooled_argv_shape_holdswitness — no new claim grammar minted; see R1) instead of one child per claim row. Verdict-identical by construction: claim_batch's own loop runs every row (no short-circuit), each failure a namedFAIL <function>line, exit nonzero iff any failed — the same conjunction the per-process fold computed. Residue named, counted, with dissolve-on: one pool build per call + one closure resolve per distinct entry (ledger rows), dissolving on the W3 cross-process content-keyed store.tools.dag_compile_clean_partition): the boundary derives from ALLwitness_layer_roots— exactly the tree the whole-tree gate compiles — never.first(). This closes BOTH directions of the roster⊂compiled-tree asymmetry: src/v2-only.dagdiffs no longer widen to whole-tree (the baseline run 29976989996's exact shape), and adag/stdtouch now selects its affected src/v2 importers on scoped runs (previously covered only by the falsifier cold control). Every fail-closed arm unchanged: non-selectable paths, departed paths, affected-set refusals, and the no-shard-intersection residue all still widen to whole-tree loudly; the cold control still forces whole-tree.Hard rules held
falsifier.yml,gunbc_falsifier_batches, or the cold-control envs. The cold control (GUNBC_CI_COMPILE_CLEAN_COLD_CONTROL=1) still forces whole-tree and remains the standing staleness detector for exactly the selection this PR widens.(source_roots, entry)— theBatchUnitdoc's own construction argument); FIX 2 preserves the per-rowrun_claimsemantics and the call-level conjunction; FIX 3 only widens/narrows which entries COMPILE, with all refusal arms intact. Acceptance oracle: verdict-identical floors.Test plan
cargo test -p v1-compiler --bin claim_executor— lane promotion + RED control (without the heavy same-entry declaration the group spawns, the pre-fix behavior) + mode-keyingcargo test -p v1-compiler --lib—floor_fast_plan_scopes_src_v2_entries_both_directions(live tree: src/v2-only touch → Scoped incl. its own entry; dag/std touch → selects src/v2 importers); existing whole-tree guards (mixed .rs, departed, docs-only) unchangedclaim_batchexecution: ONE child, 4 entries, 10/10 PASS (FIX-3 witnesses + pooled-argv shape witnesses); RED control: unknown function → namedFAIL no_such_claim_zzzline, later rows still reported, exit 1gunbc ciregen (declared-count line) — drift gate stays green5b9e08a)memory.max, 4 consecutive runs predating this branch), disjoint from selection staleness — hold released; re-arms if a future red is selection-class1b68104): floor step 49.5 min — fits the 55-min cap; ci job 99.2→61.1 min; batch-4 collapse delivered (wet 53.20→10.82); resolves_total 3 == declared 3; peak 15.0 GiB. Cheap 3.08 and ingest 6.90 MISS the ≤2-min targets — counted residue rows in the redundancy ledger, mechanism named (see R4 below), never silenceRework addendum (R1–R4, 2026-07-23)
R1 — child-pool lever adopted (the §9 cold-child class).
run_gunbc_claims' realization is now ONE pooledclaim_batchchild per call (claim_batch's own pre-existing--entry/--functiongroup grammar — no new claim grammar; the interimgunbc run --claimflag,gunbc.Cli.RunClaimsop, and theENTRY::FUNCTIONspec grammar this PR had introduced are deleted as a §3 duplicate of that pre-existing surface). The cheap-gate transports consolidate to one call per GATE: layering 7 rows → 1 child (was 7 children), extdeps 5 rows → 1 child (was 5); ingest keeps one child per overlay root-set (4 — composed inputs). Walls honored: (a) the pooled child stays a separate process — never in-executor evaluation (the executor is the 16 GiB-pinned process of the crawl; the child dies and frees); (b) per-claim verdicts survive pooling via claim_batch's own loop — every row runs (no short-circuit), each failure is a namedFAIL <function>line, exit nonzero iff any failed. Pooling deliberately removes the old cross-call&&short-circuit inside a gate (a clean-tree failure previously skipped the scanner receipts): strictly more reporting, stated in the transport notes rather than landed silently.R2 — batch-4 anomaly: typed disposition, named at the witness grain. The 53.2 min wet wall's dominating row is
interp_recorded_fixture_witness_test.dag::interp_recorded_fixture_keystone_holds(2556 s on run 29995111208). Mechanism at source grain: the witness drives ~13+claim_batchchildren each invoked with--source-root <workspace root>— every child cold-indexes the entire repo, serially. That is a cold corpus-scan on the merge path (my earlier comment's attribution to "#7107's native-routing flip" is retracted — the PR-name was polluted squash-message history; the receipt now names the witness and its transport class, not a PR). Disposition per the enrollment discipline: too heavy for the falsifier wet lane's 600 s per-receipt budget as-is, so the per-PR enrollment reverts toOfflineLocalRecipewith a dissolve-on naming the re-enrollment precondition (fixture-scoped roots / pooled lifecycle children, measured under the destination lane's budget).R3 — falsifier hold released, replaced with the class-named check. The red's class from the failed job log of run 29999281277 (main@
63feea0): exit 137 — cgroup kill atfloor_peak_post=17179869184, exactly the 16 GiBmemory.max, during the predict-only cold corpus; 4th consecutive red (21:12/03:16/06:32/11:59), all on trees predating this branch. Disjointness from this diff: the class is memory-capacity on the falsifier's whole-corpus cold walk; this PR (a) removes a duplicate co-resident whole-tree index (memory-reductive), (b) reduces child-process count, (c) leaves the falsifier's compile-clean cold control forced-whole-tree (its env arm precedes selection). It is not a selection-staleness signal — the class the window exists to catch — so the hold is released; if a future falsifier red is selection-class (a counted divergence), the hold re-arms and merge-recommend waits on it.R4 — re-measure (run 30009199696, all green). Floor step 49.5 min — under the 55-min cap; ci job 99.2 → 61.1 min; wet wall 53.20 → 10.82 (the interp de-enrollment, surviving pools 20+54 rows at 9.35 min eval); resolves_total 3 == declared 3; peak 15.0 GiB cgroup-post. The two R1 targets miss and land as counted residue (ledger rows updated in
1b68104):claim_batchchild pays a corpus-denominatedMultiEntryIndexbuild regardless of roster size (the full pool is load-bearing for bare-reference binding today, Import strip residual: 2 lens test files + FunctionCall homonym qualification (full src/v2 strip gated on loader repoint) #6985 Class B, so it cannot be narrowed per-roster).gunbc run --claimvehicle (~78 s/child) is a claim_batch loader-parity gap (~25–30 s/process), named in the ledger row.Dissolve-on for both: the W3 cross-process content-keyed store (or claim_batch loader parity with the gunbc-run entry path). Net-vs-baseline both levers remain wins (cheap 10.15→3.08, ingest 12.15→6.90).
🤖 Generated with Claude Code
https://claude.ai/code/session_01F2Rc3TWb8FFexdVQDNbb44