Skip to content

Required CI bankrupted to a declared compiler gate: the witnesses lane prepares the roster's closure, not the tree; rust unit tests in their own job; the un-required phases declared as a rung drop - #9663

Merged
briansrls merged 30 commits into
mainfrom
session/neat-tern-658-required-gate
Aug 29, 2026

Conversation

@briansrls

@briansrls briansrls commented Aug 29, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Required CI is bankrupted to a fixed, small compiler gate. The witnesses lane no longer prepares the whole tree (4,260 modules, ~87 min end to end); it prepares the closure of a declared roster — v2.test.* plus ~20 test.claim.* compiler modules, v2.workflow.required_floor.required_gate_prefixes — and folds only the claims inside it. Everything outside is DeclinedOutsideRequiredGate, counted, and left to receipts. Rust unit tests run in their own job. The probe / v2-emission / emit-compile / partition-crates / generated-artifact phases leave the required set (declared as rung drop required_gate_bankruptcy, 2026-08-29); regen stays.

Measured at 4c2beb5 on the GitHub runner — the first green run under the gate: witnesses lane 15m12s (job wall) = ~3 min build/setup, gate closure 45 s + 27 s (entry index built once, closure 2,021 modules, bare_pulled=50), strict preparation 6m33s over 2,019 modules, fold ~4.5 min over 2,830 planned claims (3,427 sites; 366 declined-long, 167 cost-debt, 64 outside-gate). planned=2830 executed=2830 passed=2754 known_red_held=27 route_gap_held=49 failed=0 interrupted_before_verdict=0 … verdict=FloorClean unexpected_failures=0. Build lane 11m03s, of which regen is ~10 min (the v1 emitter is 6 min of that). rust-unit-tests first ran on 4c2beb5 and was cancelled by its own timeout-minutes: 60 with 204 of 682 tests finished (compile 2m49s): ~126 of the lib "unit" tests each build a fresh multi-entry index over src/v2+dag (measured on srv2 under nextest: 97 tests over 60 s, ~197 single-thread minutes, self_compile_all_modules 505 s), the runner executed them serially, and 44 of them fail on rot no CI had ever run into (cargo test was never a CI step before this PR). Now: those tests carry #[ignore = "live-corpus: …"] (the crate's manual: convention; enumerated by cargo test -p v1-compiler --lib -- --ignored --list, named in the rung-drop row's population), and the unit population runs green in ~9 s after the compile (srv2: 535 passed / 0 failed / 140 ignored). The 15 failures inside the unit population are repaired at their authorities — see the second list below — including two real production defects and one v1 typecheck defect.

What the gate exposed (each fixed here, none hidden)

  • The reference-closure index was a once-per-process cache keyed on module count; the gate prepares two subjects (policy closure → roster → gate closure). Now keyed by subject digest, bounded to 2.
  • The floor evaluated gunbc.output_policy and floor_naming_hygiene by name from the policy module's frame; that only worked because the whole-tree reference closure happened to reach them. Each authority is now evaluated in its own module's scope; all three are explicit closure seeds.
  • Loader/scope divergence: the entry loader bare-scans only import-free sources, while claim_scope_for follows bare references from every module. Under the whole tree the flat bare-name channel hid it; under the gate vacuity_test refused NoSuchFunction one hop per run. The gate closure now runs the loader's own bare scanner over every module to a fixpoint (bare_pulled=50). gunbc run on such entries is still broken on main for the same reason — not fixed here.
  • Rosters (expected-red, route-gap + expectations, cost-debt) are joined only over identities inside the gate; outside-gate rows are withheld with the same accounting as cost-debt withholding (39 / 154+66 / 122 rows, printed).
  • One route-gap row is now budget-refused before reaching its effect → cost-debt roster (cost debt wins). Three lens_module_gate_witness "live" rows PASS under the narrower corpus on both hosts → removed from expected-red; the narrowing is stated in the commits.
  • A positional bill: the src/v2/lens pool-root module_path_index fill (~1.07 s) was charged to whichever lens_module_gate_witness live claim ran first, interrupting a different one in each of three consecutive runs. Preparation now evaluates the declared producer (v2.lens.registry.completeness.lens_registry_completeness_live_facts) once in its own module's scope and adjudicates the fill as a preparation warm (ModulePathIndexBuild/lens-pool-roots); no cost-debt row for a claim that only paid someone else's fill.
  • Eleven claims that are interrupted before verdict on the gate-bounded subject on both hosts, run after run, plus the four bootstrap_footprint_anchor claims at 474–505 ms against the 500 ms ceiling, join the cost-debt roster as proven chunk 12 (with the reason annotated on the chunk).

Test plan

  • claim_executor --required-ci --required-lane witnesses and --required-lane build on srv2 (12 lanes, logs ~/gunbc-gate/witnesses-lane*.log) and on CI at every push; final CI run on this head is the acceptance.
  • cargo test -p v1-compiler --lib in the new rust-unit-tests job (unit population only; the live-corpus class is --ignored).
  • dag/test/claim/discovery_census_witness_test.dag: new w_site_outside_the_required_gate_is_declined arm.

What the first cargo test exposed (each fixed at its authority, none hidden)

  • Real defect, Anchor a relative source root the same way in both module-index builders #9548: try_index_source_root_into_module_index keyed files by the walked path — absolute once the root was anchored — while the strict builder keys through module_index_path_key; the primary-precedence index disagreed with the strict one on every path. Same authority now; primary_precedence_pool_fills_only_absent_modules was the discriminating RED and stays.
  • Real defect, Close the remaining receipt-continuity production bypass: parse merge-base event data, enforce exact append-only prefix, hash every field #7791: try_build_module_index carried if root_idx > 0 { continue; } ahead of its collision refusal, so a module declared in two roots shadowed silently in the builder named strict. Guard removed; overlay callers have build_module_index_primary_precedence. duplicate_module_path_across_roots_refuses_loudly was the RED.
  • v1 typecheck defect, Compiler floor — one declared-type inhabitance authority, two grammar positions wired, ten declared #9194: declared_type_inhabitance reads params as generic type parameters, which is exactly what a callable formal carries, so every higher-order call produced a counted DeclaredTypeInhabitanceUndecided with a false reason. direct_call_argument_inhabitance_diags now excludes callable formals like its sibling relation. .dag edit + regenerated mirror (two regen passes: the test blob lives inside the emitter).
  • Stale authority rows after the Reorganize dag/gunbc files into domain-specific subdirectories #9637 reorg: 12 entry literals in gunbc.ci_layer_roots, 2 in gunbc.offline_local_recipe repointed; the rows whose subjects 611fd02 / source_has_suspect renders an unreadable source as clean: typed not-established across both roster_gate twins #9206 deleted are gone. The three witness_deferral_freeze rows for relocated witnesses are deleted, not repointed — that gate defines relocation as growth (FrozenPathDeferralGrew, compared at the merge-base on CI) and the roster may only shrink. gunbc.non_fold_residue gains its 22 missing sites and loses 4 stale ones; its .dag twin then passes (leaves floor_expected_red) and sits at 629 ms against the 500 ms ceiling (joins cost-debt chunk 12).
  • Deleted subjects: cli_run::floor_witness_a_prove (runner, prove test and fixtures left with FLOOR-Y); the docs/probes/census_extra_excludes.txt pin tests and helpers (Bankrupt the measurement corpus: delete docs/probes whole, boards and instruments alike #9132).
  • Test rot: a revision-addressed git show literal the reorg rewrote to the post-reorg path; a method-existence witness anchored on a Primitive() frontier row that no longer exists.
  • Runner-only collision (first CI run of the unit population, dc3ca52: 533 passed / 2 failed / 9.59 s): resolve_host_tool_program_tests wrote a fixed-name directory under temp_dir(), which is the host's shared /tmp on a self-hosted runner; a directory another runner slot's uid left behind made the write PermissionDenied. The probe root now carries the process id.
  • Early aborts: four tests were "fast" only because they died on a missing path; repaired, they read the live tree for 2–4 minutes and join the live-corpus class. One of them (merge_base_authority_projection_matches_jsonl_carrier) still fails after 210 s with unknown RoadmapAcceptanceEvent variant <invalid-symbol> — receipts-lane rot, recorded here.

Not done here: the receipts workflow for the un-required phases (push-to-main, non-blocking) and the roster narrowing that would drop the ~250 gunbc.* modules v2.test.* drags in. Program issue for the next step: #9664. Also left for follow-ups: test.claim.expectation_frontier_witness_test names the deleted long-lane file (outside the gate); the affected-set kernel (floor_diff_edits_from_diff_text, rerun_frontier_nodes_for_entry, …) has had no production consumer since FLOOR-Y and should go with its remaining fixture-dependent tests.

Brian Searls and others added 2 commits August 29, 2026 01:37
…eted, and give the six witness-bin TypeEnv initializers the unit_variant_index #9656 added

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

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

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013G3t66QwKJFK5w8jXxMXP2
@briansrls briansrls closed this Aug 29, 2026
Brian Searls and others added 3 commits August 29, 2026 01:52
…its own import closure, with the other four phases and the product witnesses moved off the merge path

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013G3t66QwKJFK5w8jXxMXP2
@briansrls briansrls reopened this Aug 29, 2026
Brian Searls added 11 commits August 29, 2026 02:04
…leted artifact registry entries go with them
…and all-bins steps gone, rust-unit-tests job added), DESIGN.md and design-ledgers.md (the rung-drop row), .gitattributes (js_site rows gone)
…hen the merge took main's cli_run.rs wholesale)
…ges to a fixpoint), not the import headers: stripped modules reach their providers by reference, and the header walk left 1,190 names unresolved
…ation rows landed with #9641 and now refuse every PR as stale
…mporting only a child of the declaring module still binds the parent's declarations
…valuated in a frame over the prepared subject
Brian Searls and others added 7 commits August 29, 2026 03:24
…, bounded to the two subjects a floor process prepares by design — the gate's policy-closure preparation and the gate closure are two subjects in one process, and a once-per-process index refused the second (ReferenceIndexSubjectChanged built_for_modules=47 observed_modules=1952, CI and srv2 at 066725c)

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

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

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013G3t66QwKJFK5w8jXxMXP2
…ate-bounded subject refused at output-policy install because resolve_channel_policy had only ever resolved by pool-membership coincidence — the flat bare-name channel found gunbc.output_policy because the whole corpus was loaded, not because the policy closure references it

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

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

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013G3t66QwKJFK5w8jXxMXP2
…scope: the floor installed the output policy and the naming-hygiene predicates from the policy module's frame, which reached gunbc.output_policy only by the accident of the whole-tree reference closure — under the gate-bounded subject the module was loaded and the name still refused

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

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

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013G3t66QwKJFK5w8jXxMXP2
…ed gate — an enrolled identity whose module the gate never loads is withheld with the same accounting as cost-debt withholding, not refused as stale; and two modules that reached rust_target_model_staging by bare reference now import it, because the loader follows bare references only for import-free modules while the claim scope follows all of them

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

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013G3t66QwKJFK5w8jXxMXP2
…le, with the loader's own scanner, to a joint fixpoint with containment ancestors — the loader's both-closure bare-scans only import-free sources, while the claim scope the fold builds over the subject follows bare references from all of them; and route-gap expectations located outside the gate are withheld like the roster rows they join

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

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

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013G3t66QwKJFK5w8jXxMXP2
…ess join, route-gap expectations honour cost-debt withholding, and emit_on_demand_classical_not_native_one_build_holds moves to the cost-debt roster — it is budget-refused before it reaches the host effect its route-gap enrollment expects, on both hosts

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

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013G3t66QwKJFK5w8jXxMXP2
…r the gate-bounded subject both PASS on CI and on srv2, and the floor refuses a passing enrollment as STALE-QUARANTINE

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

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013G3t66QwKJFK5w8jXxMXP2
@gunbai-bot gunbai-bot Bot changed the title I need some help planning my "get out of bankruptcy/v1 debt" strategy Required CI bankrupted to a declared compiler gate: the witnesses lane prepares the roster's closure, not the tree; rust unit tests in their own job; the un-required phases declared as a rung drop Aug 29, 2026
Brian Searls and others added 3 commits August 29, 2026 05:20
…join the cost-debt roster as proven chunk 12 — the same eleven on the GitHub runner and on srv2, run after run

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

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013G3t66QwKJFK5w8jXxMXP2
…ted at 1076ms the run after its sibling was withheld, because the 1.07s pool-root module_path_index fill is billed to whichever consumer runs first

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

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013G3t66QwKJFK5w8jXxMXP2
…ion by evaluating the declared producer once in its own module's scope — the 1.07s fill was a positional bill that interrupted a different lens_module_gate_witness live claim in each of three consecutive runs — and the two fill-only rows leave cost-debt chunk 12

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

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013G3t66QwKJFK5w8jXxMXP2
Brian Searls and others added 2 commits August 29, 2026 06:16
… with the src/v2/lens pool-root index warmed in preparation it passes, as its two siblings did once they stopped paying that fill

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

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013G3t66QwKJFK5w8jXxMXP2
…74–505ms CPU on three consecutive CI runs with no fill billed to them, so the 500ms ceiling decides them run by run

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

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013G3t66QwKJFK5w8jXxMXP2
@gunbai-bot
gunbai-bot Bot marked this pull request as ready for review August 29, 2026 06:53
Brian Searls and others added 2 commits August 29, 2026 09:52
…prepare or build over the live tree carry a live-corpus ignore reason and leave the required run, and the rot the first-ever `cargo test` exposed is repaired at its authorities, not hidden

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

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

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

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013G3t66QwKJFK5w8jXxMXP2
…st's shared /tmp on a self-hosted runner, and a fixed directory name collided with one another runner slot's uid left behind — PermissionDenied on two tests that had never run in CI before

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

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013G3t66QwKJFK5w8jXxMXP2
@briansrls
briansrls merged commit b726547 into main Aug 29, 2026
2 of 3 checks passed
@briansrls
briansrls deleted the session/neat-tern-658-required-gate branch August 29, 2026 10:04
gunbai-bot Bot pushed a commit that referenced this pull request Aug 29, 2026
…nd, not a fixture that can be cut; release one row on a preparation receipt

INSTRUMENTED BEFORE REPAIRING, AND THE MEASUREMENT REFUTED THE EXPECTED FIX.

live_deploy.emit was dispatched as a fixture cut: production-sized subjects
whose witnesses could run against a minimal typed fixture. Partitioning one
apply witness locally (claim_batch, per-witness cpu_ms) says otherwise. Of its
3249ms, building the Pipeline is 2978ms and emitting it is 270ms; inside the
build, plan and membership_effects together are 5ms. Three hypotheses were
tested and killed by scaling probes rather than by reading: a quadratic
accumulator in orch_emit_steps_from (K=20/40/80/160 steps measure
72/108/176/325ms, linear); cost in statement count or byte size (2/4/8/16
statements all ~125ms; one word of 100..1600 chars all ~119ms, flat both ways);
and a duplicated derivation in the memory-cap block (1183ms and 1166ms alone,
1287ms together -- the interpreter already memoizes it).

What it actually is: ~21ms per DISTINCT emitted bash command over a ~100ms
base, with identical commands free. The srv1 apply script is ~30 distinct
commands and retract ~13, which is the 3.4s/1.3s ratio -- their command counts,
not their byte sizes. So the only lever a minimal fixture has on this cost is
shrinking the emitted command set, and that set IS what these witnesses assert.
Cutting it would weaken the production subject, so no fixture is cut here.

RELEASED, ONE IDENTITY, ON A PRODUCER RECEIPT RATHER THAN A COST READING.

v2.test.languages_consumer_census.corpus.per_language_row_ratchet
.corpus_per_language_row_ratchet_holds leaves the proven roster. Its 645ms was
an unbracketed shared build of the languages consumer census -- invisible to
the marginal basis, so it read as own work. gunbc#9680 moved that build into
FloorPreparationPhase as LanguagesConsumerCensusBuild, and main run 33263972922
at 6515d6f announces phase=languages-consumer-census-warm state=completed
cpu_ms=460 decl_rows=72 provenance=built-by-preparation. built-by-preparation
is the load-bearing field: preparation found the memo cold and paid for it, so
no claim is billed. Removal only; the roster gains nothing.

Its own 0ms readings are explicitly NOT the evidence. The row reads 0ms on two
main runs and 642ms over budget on a third, and measures 679ms in isolation
here -- the 0s are borrowed from whichever row built the census first and the
642 is the whole build billed for touching first. Releasing on a 0 would be the
charged-basis error this roster was rebuilt once to correct, in mirror image.

NOT RELEASED: inert_carrier_universe_is_nonempty presents identically (0-1ms,
1183ms over budget, 1270ms isolated) but inert_carrier_data has no preparation
warm, so deleting its line hands 1.2s to a sibling under the ceiling today. Its
trigger is named as a capability: the artifact built and adjudicated in
preparation, or bracketed so the marginal basis can net it.

THE ROSTER'S OWN COUNT HAD ROTTED AGAIN. The header read 274 and the population
block 225+51=276 against a roster of 290. Nothing was wrong with the roster;
every wrong figure was prose copied beside it, the same defect this file
corrected once before. Corrected to 289 post-release, with the per-population
figures left as enrolment-time provenance and the decay named.

A COST INSTRUMENT THAT IS RE-DERIVABLE RATHER THAN TRANSCRIBED.

test.claim.floor.bash_command_serialization_cost_model carries four claims
differing only in K (1/2/4/8 distinct commands). They assert the serializer is
total -- every command handed in comes back out, and all four go RED under a
dropped-command mutation (verified, then restored). Their real output is the
cpu_ms column in required_floor_claim_cost.tsv: intercept is the fixed per-call
setup, slope the marginal cost of one more distinct command. Measured here
104/121/163/241ms -- slope ~20ms, intercept ~92ms. K stops at 8 so this file
cannot enrol itself on the shrink-only roster it exists to measure, and the
annotation records what the four rows cannot see: they vary K within one claim,
so a cross-claim cache would leave them near-unchanged while collapsing the
corpus, and that saving must be read from module totals instead.

A 4b ROW FOR THE MEMORY-CAP GATE, FILED RATHER THAN "FIXED".

deploy_memory_cap_script_author_precedes_shadow_revert returns
list_length(units) > 0 && script == ordered. The unit-count conjunct is valid
and kept. The ordering conjunct rebuilds the author-then-revert composition
from the same two producers the production script was composed from, so at the
production call site it is tautological and the gate is decided entirely by the
unit count. The ordering is genuinely checked only where a fixture supplies a
script the gate did not build, and those two REDs execute -- so the function is
not decoration and is not deleted. Next rung is construction: one producer
emitting author-then-revert as a single composed value, so a wrong order has no
writable form.

Held, not done: the 33 live_deploy.emit rows wait on the proven same-key
emission cache (FLOOR-EMIT-SAME-KEY-FILL). All 21 apply witnesses emit a
byte-identical script, so a cache surviving across claims collapses them to one
payer; a second memo built here would fork that lane's mechanism.

Also found, not fixed and not mine: gunbc.discovery_census and its witness are
non-exhaustive over RequiredFloorDisposition's DeclinedOutsideRequiredGate arm
(added by gunbc#9663) and do not compile. Required CI cannot see it -- the
module is outside the required floor's universe post-#9663, and run 33263972922
disposes zero discovery_census rows.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BotWMhkrZSo3Hcy1K68Mt9
gunbai-bot Bot pushed a commit that referenced this pull request Aug 29, 2026
…ry share-install arm refuses instead of skipping (review: a skip memoizes nothing under a green floor)

Post-#9663 the floor prepares the gate roster's closure plus the declared
runtime-authority seeds, and v2.workflow.floor_pure_producer_share was reached
by name without being a seed — so on the required lane the warm phase would
have printed state=skipped and admission stayed empty: a green over a flag
that never ran. The module is now the fourth seed, and
install_pure_producer_share is fail-closed at every arm: roster module absent
=> PureProducerShareRosterOutsidePreparedSubject; a warm row whose module left
the subject => PureProducerShareProducerModuleOutsideSubject (a stale row,
deleted not unwarmed); warm evaluation failure => PureProducerShareWarmFailed;
store refusal => PureProducerShareWarmNotStored. Enrolled REDs run the real
install over synthetic prepared subjects: no-roster-module refuses (never
skips), a carried roster warms into the store, a stale warm row stops the line.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NMo66BJucv9gA46tgQ5tAk
gunbai-bot Bot added a commit that referenced this pull request Aug 29, 2026
…nd, not a fixture that can be cut; release one row on a preparation receipt (#9687)

* FLOOR-EMIT-RECOMPUTATION: the cost is 21ms per distinct emitted command, not a fixture that can be cut; release one row on a preparation receipt

INSTRUMENTED BEFORE REPAIRING, AND THE MEASUREMENT REFUTED THE EXPECTED FIX.

live_deploy.emit was dispatched as a fixture cut: production-sized subjects
whose witnesses could run against a minimal typed fixture. Partitioning one
apply witness locally (claim_batch, per-witness cpu_ms) says otherwise. Of its
3249ms, building the Pipeline is 2978ms and emitting it is 270ms; inside the
build, plan and membership_effects together are 5ms. Three hypotheses were
tested and killed by scaling probes rather than by reading: a quadratic
accumulator in orch_emit_steps_from (K=20/40/80/160 steps measure
72/108/176/325ms, linear); cost in statement count or byte size (2/4/8/16
statements all ~125ms; one word of 100..1600 chars all ~119ms, flat both ways);
and a duplicated derivation in the memory-cap block (1183ms and 1166ms alone,
1287ms together -- the interpreter already memoizes it).

What it actually is: ~21ms per DISTINCT emitted bash command over a ~100ms
base, with identical commands free. The srv1 apply script is ~30 distinct
commands and retract ~13, which is the 3.4s/1.3s ratio -- their command counts,
not their byte sizes. So the only lever a minimal fixture has on this cost is
shrinking the emitted command set, and that set IS what these witnesses assert.
Cutting it would weaken the production subject, so no fixture is cut here.

RELEASED, ONE IDENTITY, ON A PRODUCER RECEIPT RATHER THAN A COST READING.

v2.test.languages_consumer_census.corpus.per_language_row_ratchet
.corpus_per_language_row_ratchet_holds leaves the proven roster. Its 645ms was
an unbracketed shared build of the languages consumer census -- invisible to
the marginal basis, so it read as own work. gunbc#9680 moved that build into
FloorPreparationPhase as LanguagesConsumerCensusBuild, and main run 33263972922
at 6515d6f announces phase=languages-consumer-census-warm state=completed
cpu_ms=460 decl_rows=72 provenance=built-by-preparation. built-by-preparation
is the load-bearing field: preparation found the memo cold and paid for it, so
no claim is billed. Removal only; the roster gains nothing.

Its own 0ms readings are explicitly NOT the evidence. The row reads 0ms on two
main runs and 642ms over budget on a third, and measures 679ms in isolation
here -- the 0s are borrowed from whichever row built the census first and the
642 is the whole build billed for touching first. Releasing on a 0 would be the
charged-basis error this roster was rebuilt once to correct, in mirror image.

NOT RELEASED: inert_carrier_universe_is_nonempty presents identically (0-1ms,
1183ms over budget, 1270ms isolated) but inert_carrier_data has no preparation
warm, so deleting its line hands 1.2s to a sibling under the ceiling today. Its
trigger is named as a capability: the artifact built and adjudicated in
preparation, or bracketed so the marginal basis can net it.

THE ROSTER'S OWN COUNT HAD ROTTED AGAIN. The header read 274 and the population
block 225+51=276 against a roster of 290. Nothing was wrong with the roster;
every wrong figure was prose copied beside it, the same defect this file
corrected once before. Corrected to 289 post-release, with the per-population
figures left as enrolment-time provenance and the decay named.

A COST INSTRUMENT THAT IS RE-DERIVABLE RATHER THAN TRANSCRIBED.

test.claim.floor.bash_command_serialization_cost_model carries four claims
differing only in K (1/2/4/8 distinct commands). They assert the serializer is
total -- every command handed in comes back out, and all four go RED under a
dropped-command mutation (verified, then restored). Their real output is the
cpu_ms column in required_floor_claim_cost.tsv: intercept is the fixed per-call
setup, slope the marginal cost of one more distinct command. Measured here
104/121/163/241ms -- slope ~20ms, intercept ~92ms. K stops at 8 so this file
cannot enrol itself on the shrink-only roster it exists to measure, and the
annotation records what the four rows cannot see: they vary K within one claim,
so a cross-claim cache would leave them near-unchanged while collapsing the
corpus, and that saving must be read from module totals instead.

A 4b ROW FOR THE MEMORY-CAP GATE, FILED RATHER THAN "FIXED".

deploy_memory_cap_script_author_precedes_shadow_revert returns
list_length(units) > 0 && script == ordered. The unit-count conjunct is valid
and kept. The ordering conjunct rebuilds the author-then-revert composition
from the same two producers the production script was composed from, so at the
production call site it is tautological and the gate is decided entirely by the
unit count. The ordering is genuinely checked only where a fixture supplies a
script the gate did not build, and those two REDs execute -- so the function is
not decoration and is not deleted. Next rung is construction: one producer
emitting author-then-revert as a single composed value, so a wrong order has no
writable form.

Held, not done: the 33 live_deploy.emit rows wait on the proven same-key
emission cache (FLOOR-EMIT-SAME-KEY-FILL). All 21 apply witnesses emit a
byte-identical script, so a cache surviving across claims collapses them to one
payer; a second memo built here would fork that lane's mechanism.

Also found, not fixed and not mine: gunbc.discovery_census and its witness are
non-exhaustive over RequiredFloorDisposition's DeclinedOutsideRequiredGate arm
(added by gunbc#9663) and do not compile. Required CI cannot see it -- the
module is outside the required floor's universe post-#9663, and run 33263972922
disposes zero discovery_census rows.

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

* The population count stops being prose and becomes a producer (review 57425)

The review approved but observed that the new prose still hand-transcribes
289/240/49 while the header itself flags transcription as this file's recurring
debt. That is correct, and the fix is small enough that leaving a self-aware
note in its place was the wrong call.

floor_cost_debt_proven_population, floor_cost_debt_censored_population and
floor_cost_debt_population_report fold the SAME chunks floor_cost_debt_roster
folds, so they cannot drift from the roster the floor consults -- there is no
second representation. Every population figure is removed from the header and
the population block; both now name the producer instead. The enrolment-time
225/51 stay, labelled as provenance rather than present size, because each
records what one measurement enrolled.

Executed, not just compiled: the entry point returns
`floor_cost_debt population: proven=240 censored=49 total=289`, matching an
independent parse of the chunk functions. The invocation recipe is in the
annotation, including that `gunbc run` REFUSES a non-ProcessExit return and
prints the String in the refusal -- correct behaviour, since a report is not a
verdict.

No witness pins these against a literal, and the annotation says why: a
merge-blocking assertion that the population equals a number copied from this
same tree is the change detector DESIGN section 5 forbids, collapsing to
measure() == measure() the moment its update is automated. The monotone debt
contract -- identity-grain, shrink-only, stale rows refusing -- is what guards
the roster; a size assertion would add nothing and break on every legitimate
release.

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

* The cost instrument did not execute: home it under v2.test. so the gate actually reaches it

Caught on run 33269267512 by neat-swift-219 and confirmed here: the four
cost-model claims produced ZERO rows in required_floor_claim_cost.tsv and zero
rows in the disposition artifact. required_gate_prefixes does not carry
"test.claim.floor." -- the similar-looking "test.claim.floor_resolve_realization_witness"
is a different, undotted prefix -- so test.claim.floor.bash_command_serialization_cost_model
never entered the prepared closure at all.

That makes the previous commit's instrument the exact failure DESIGN section 5
names: the annotation told a reader to read these rows out of an artifact that
had no such rows, and the mutation RED that qualified them had been run locally
only. Worse than an absent file, because the prose would have been cited as
coverage.

The subject is v2.workflow.bash_command_fold_serialize, so the witness belongs
in the v2 tree: moved to src/v2/test/claim/floor/, module
v2.test.floor.bash_command_serialization_cost_model, which the existing
"v2.test." prefix already covers. Widening required_gate_prefixes to admit the
old path was available and is refused -- the gate's population is not something
a new witness enlarges for its own convenience -- and the annotation now records
that refusal so the next author does not reach for it.

Retargeted while moving: it now calls bash_fold_serialize_stmts_semi directly
instead of going through gunbc.shell_command_text, so the witness carries no
dag/ dependency and names its actual subject. The refusal arm is explicit -- a
Rejected or diagnostic-carrying serialization yields the empty string, so the
containment check reds rather than passing vacuously.

Re-verified after the move, not carried over: four PASS at 114/133/181/272ms,
all under the 500ms line, and all four RED under a dropped-command mutation
then green again on restore.

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

* Floor discovery refuses a test-marked decl outside *_test.dag: restore the suffix

Run 33270279332: `REQUIRED-FLOOR REFUSAL cause=FloorDiscoveryRefused --
`test`-marked decls must live in `*_test.dag` files`. The previous commit moved
the module into the v2 tree and dropped the `_test` suffix from the FILE name,
which floor discovery refuses. The four artifact-upload errors in that run are
downstream of it -- the TSVs were never written, because the floor never got
past discovery.

The file is `bash_command_serialization_cost_model_test.dag` again. The MODULE
stays `v2.test.floor.bash_command_serialization_cost_model`: the suffix is a
constraint on the file, not the module path, and the tree carries both spellings
(`per_language_row_ratchet_test.dag` declares
`v2.test.languages_consumer_census.corpus.per_language_row_ratchet`, while
`inert_carrier_test.dag` keeps its `_test`). Only the file name was wrong.

WHY LOCAL GREEN DID NOT CATCH IT, recorded because it will recur: `claim_batch
--entry <file>` executes the claims in a file it is handed and performs none of
the floor's DISCOVERY, so the naming law that governs enrolment is unreachable
from the local instrument. A file can pass every claim locally and refuse the
whole lane at discovery. Re-verified after the rename anyway: four PASS at
104/120/158/237ms.

Confirmed in the same run, and it is the premise of this PR's release: the
languages preparation warm fires on THIS head too --
`phase=languages-consumer-census-warm state=completed cpu_ms=507 wall_ms=509
decl_rows=72 provenance=built-by-preparation`.

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

---------

Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
gunbai-bot Bot pushed a commit that referenced this pull request Aug 29, 2026
…repared frame through a positive portable-value tier; roster module seeded into the required closure (#9686)

* FLOOR-TARGET-MODEL-FILL: stop rebuilding emit target models per claim — a declared cross-claim pure-producer share, warmed in preparation, receipted through [floor-shared-fill]

The required floor builds a fresh evaluation frame per claim, so the eval-frame
memo dies at every claim boundary and every emit-path claim re-derives the same
pure target models from scratch: rust_target_model_staging() measured ~125ms of
re-derivation per claim, a one-word bash serialize ~110ms of word-independent
fixed cost, and main's floor receipts carry a ~280-340ms fixed base on every
v2.test.emit.* row (run 33263972922) against the operator's 500ms per-claim CPU
ceiling — a runner-variance-sized margin, which is how run 33258845841 refused.

This generalizes the existing prepare_grammar cross-claim arm into the tier its
own dissolve-on note asked for: a cross-claim pure memo keyed on fn-node
identity + a content hash of the full argument row, with admission held to a
DECLARED roster (v2.workflow.floor_pure_producer_share) — warm rows are nullary
and evaluated once in floor preparation (a warm that fails or refuses to store
stops the line); claim-forced rows fill on first touch, with the fill netted
from the paying claim on both clocks and every fill/hit reported through the
existing [floor-shared-fill] ledger under cache=cross_claim_pure_share.
PortableValue learns to carry a module-scope fn by shared-graph reference
(closures stay refused), and a per-frame hit cache bounds reconstruction to
once per claim. Store honesty: effectful, unportable, over-cap and duplicate
stores refuse to the recompute path, counted, never to a wrong value.

Measured on this tree (claim_batch, two entry groups = two fresh frames, the
floor's shape): rust_target_model_staging 125ms -> 19ms in the consuming frame;
a one-word bash serialize claim 105ms -> 65ms wall / 33ms charged CPU; the
paying frame's own charge nets to ~0ms CPU for the warm rows. Every rostered
row was verified to actually store (instrumented one-off run, 9/9 stored).
Enrolled RED: shared_fill's a_rostered_producer_fills_once_and_serves_later_claims
runs the real evaluation path over two fresh InterpContexts on one resolved
graph — same key across two claims must ledger ONE fill with the second claim a
consumer, two keys must ledger two fills, and an un-rostered producer must
leave no row and never be served.

Also wires the previously uncalled print_eval_recompute_trace into claim_batch
(GUNBC_RECOMPUTE_TRACE=1 only) — the instrument this lane used to locate the
bash fixed-cost owners was inert until called.

Does not touch any ceiling, the cost-debt roster, or the required gate shape.

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

* Bind the share roster and observer lifetime to the prepared frame (register/clear both reset all three)

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

* The roster module joins REQUIRED_FLOOR_RUNTIME_AUTHORITY_MODULES; every share-install arm refuses instead of skipping (review: a skip memoizes nothing under a green floor)

Post-#9663 the floor prepares the gate roster's closure plus the declared
runtime-authority seeds, and v2.workflow.floor_pure_producer_share was reached
by name without being a seed — so on the required lane the warm phase would
have printed state=skipped and admission stayed empty: a green over a flag
that never ran. The module is now the fourth seed, and
install_pure_producer_share is fail-closed at every arm: roster module absent
=> PureProducerShareRosterOutsidePreparedSubject; a warm row whose module left
the subject => PureProducerShareProducerModuleOutsideSubject (a stale row,
deleted not unwarmed); warm evaluation failure => PureProducerShareWarmFailed;
store refusal => PureProducerShareWarmNotStored. Enrolled REDs run the real
install over synthetic prepared subjects: no-roster-module refuses (never
skips), a carried roster warms into the store, a stale warm row stops the line.

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

* Serve-cache portability: total typed reification at publication (ServeCacheValueNotPortable with path), fields re-sorted under the consuming interner, Fn portability deleted by ruling, roster pruned by measured reuse

Run 33269961629 refused with six emit no-such-field errors on served values. The
executed root cause is FIELD ORDER, not field loss: fields_get binary-searches
on Symbol ordinals, ordinals are per-interner encounter order, and
value_from_portable_ctx preserved the ORIGIN frame's field order — sorted under
frame A, unsorted under frame B, so every read missed. Reconstruction now
re-sorts Record and Variant fields under the consuming interner, with a
regression control that reads every field of a served record via fields_get
under a deliberately reordered interner.

Per the operator ruling on this class: PortableValue::Fn(Rc<Node>) is DELETED —
a raw evaluator node embeds origin-resolved identifiers and is an origin-bound
resource, not portable content. Publication into the store is now TOTAL:
portable_value_from_ctx_at refuses at the first non-portable child with a typed,
located ServeCacheValueNotPortable{path_into_value, encountered_kind}, counted,
and surfaced verbatim by the warm path's line-stop. Enrolled REDs: a fn-carrying
record refuses at store with path=.transform kind=OriginBoundNode; nested
contamination names .a[0].function; the same args under a different fn identity
miss; serve and the per-frame hit cache both verify the full portable argument
row before serving (hash collisions degrade to recompute, never a wrong value).

Roster re-derived from the run's own [floor-shared-fill] evidence:
rust_target_model/staging leave the warm roster (their value carries a fn at
.produced_decl_support.render; re-enrol trigger named in the .dag: carry the
render transform as declared rows), and formal_production_for_lhs_exact leaves
claim-forced (1,635 fills for 113 consumer claims - a non-sharing producer is
cache population, not a saving). The surviving rows all measured real reuse:
grammar_relation_row_for_emitted 150 fills/175 consumers,
formal_productions_from_catalog_node 16/45, bash_fold_relation_row_witness
49/36, bash_fold_serialize_node 65/26, bash lex/productions 35/44 consumers.

The six emit identities stay enrolled on the floor as this class's permanent
regression controls; they are not rostered as expected-red.

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

* Seed-growth justification for the cross-claim pure-producer share (gunbc.cross_claim_pure_share_seed_growth; enrolled in seed_growth_justification_roster)

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

* Review 57446: admit by resolved declaration identity, not bare name; real byte budget on the cross-claim store

F1: the roster's qualified spellings now resolve to their fn nodes at install
(a frame per rostered module over the prepared subject); the interpreter admits
by that node set, so a bare-name homonym in a non-rostered module is never
eligible, and an unresolvable row stops the line
(PureProducerShareProducerUnresolved). Enrolled RED: a homonym outside the
roster identity does not store.

F2: the retention bound is now an actual byte budget (256 MiB) on the reified
portable entry — arguments and values, collision buckets included — computed at
publication where reification is total, refused counted when crossed. The entry
cap remains as the population bound. Enrolled RED: an over-budget store refuses
counted while a within-budget store still lands.

Roster .dag doc updated to state both contracts.

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

* Review 57451: complete the seed-growth receipt — the roster is the full mechanical census of new declarations

Derived item-by-item from the declaration diff against origin/main; the one
exclusion (cfg(test)-only byte-budget override) is stated in the receipt.

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

---------

Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant