Skip to content

get main CI green - #6352

Merged
briansrls merged 9 commits into
mainfrom
session/crisp-bear-170
Jul 7, 2026
Merged

briansrls merged 9 commits into
mainfrom
session/crisp-bear-170

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Auto-opened by session-dashboard for session crisp-bear-170.
Pushing to session/crisp-bear-170 advances this PR.

Worker attestation

Before flipping this PR to ready for review, confirm each item:

  • Title describes the change (not the session id or branch).
  • PR body summarises what and why (replace the TODO below).
  • Tests run: name the command (e.g. npm test, cargo test) and the result.
  • If this closes a work item, the body contains a Closes #N directive.
  • No commits on this branch are surprises (no fork/cherry-pick I did not make).
  • No secrets / credentials / large binaries staged.

Summary

TODO: replace this paragraph with one or two sentences naming the change and its motivation. Reviewers read this first.

Test plan

  • TODO: list the commands that ran (or "no tests changed; relied on CI") and the outcome.

@gunbai-bot
gunbai-bot Bot marked this pull request as ready for review July 7, 2026 04:32
@gunbai-bot
gunbai-bot Bot marked this pull request as draft July 7, 2026 04:32
briansrls and others added 3 commits July 7, 2026 04:33
…ale-binary no-count refusal)

The ci_regen_ratchet required job failed because ci_release_build_line built
only claim_executor+gunbc, while regen_stage0 was left to ensure_regen_stage0_built's
build-if-absent path. On the self-hosted runners target/release/ persists across
jobs, so a stale regen_stage0 (pre-dating the regen_divergence_count contract) was
reused, emitted no count, and tripped the fail-closed no-count refusal. cargo build
is source-change-aware, so listing --bin regen_stage0 in the shared release step
guarantees a fresh binary. Also surface the captured shell stdout in the gate's
ExitFailure reason so the located refusal (which arm + observed count) is visible in
the CI log rather than swallowed. Regenerated ci.yml + falsifier.yml.

Receipt: ci_regen_ratchet job 85537100872, run 28841755357 @ 7927413.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@gunbai-bot gunbai-bot Bot mentioned this pull request Jul 7, 2026
6 tasks
@gunbai-bot

gunbai-bot Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor Author

Status (not abandoned; intentionally parked as draft):

WHAT IS DONE + VERIFIED: the get-main-green two-job split (required green ci job + non-required honest-red ci_regen job) + the §5 counted-divergence ratchet (ci_regen_ratchet). The ratchet is GREEN by execution in CI (validated on 95930fe; stale-binary no-count bug fixed by building regen_stage0 in the shared release step). Compiles clean whole-corpus.

WHY STILL DRAFT (not ready): the required green ci job cannot pass yet because batch-1 dag_compile_clean_gate times out at the 10-min floor budget in CI. This is a PRE-EXISTING main-wide condition (recent main runs time out at the identical batch-1), NOT introduced by this PR. It is the compile-clean serial wall (roadmap §0 item 2-compile-clean-serial). Affected-set scoping (lever a) that would shrink batch-1 is transitively blocked on completing the whole-tree resolve-grounding substrate (lively-raven SymbolIndex lane, gated on #6348) — until that lands, every non-docs PR runs the whole corpus and times out. This PR + bright-heron #6335 (selection) are ready prep behind that substrate.

UN-PARK TRIGGERS: (1) when #6335 merges, rebase origin/main into this branch + resolve the ci_workflow.dag overlap; (2) when the resolve-grounding substrate lands, the green job fits budget and this flips ready. Coordinated with clever-koi (routing) + bright-heron (#6335). Closing would discard coordinated prep behind an active critical-path lane.

@briansrls
briansrls marked this pull request as ready for review July 7, 2026 17:14
@briansrls
briansrls merged commit 1a79ce1 into main Jul 7, 2026
6 of 10 checks passed
@briansrls
briansrls deleted the session/crisp-bear-170 branch July 7, 2026 17:59
briansrls added a commit that referenced this pull request Jul 9, 2026
…sses

The operator's 4-rule business logic generalized on one axis: the decision is
a function of WHEN the redundancy is knowable and WHETHER what was knowable
was prepared for. Errors fire only on knowable-but-unprepared; genuine
emergence and declared triviality are typed acceptances, never silence.

std.materialization_ladder (dag/std):
- Frame/FrameKind: SharedStateFrame | IsolatedChildrenFrame |
  ReplayedFrame{attempts} | UnboundedSiblingsFrame — the nested-scope axis;
  a 'run' at any layer is a frame, never a different kind of thing.
- DemandNature: Pure | IdempotentEffect | WorldRead{envelope_declared} |
  FreshEffect — the D3 effect gate; TTL = unmodeled dependency XOR declared
  staleness, never an eviction knob.
- CacheProvider: keying (ContentKeyed|ExistenceKeyed) + EvictionPolicy
  (ScopeExit|SpacePacked) REQUIRED by construction — rule 3 unwritable-bad.
- LadderVerdict (total): AuthoredDuplication | Discharged | RefusedNoProvider
  | RefusedScopeTooNarrow | RefusedExistenceKeyed (the build-if-absent #6352
  wall) | RefusedUnmodeledWorldRead | ExemptFreshEffect |
  AcceptedBelowCostFloor | AcceptedSingleRecompute.
- Declared-emergent frames obligate UP FRONT: retry frames derive
  checkpointing, unbounded-sibling frames (server loops, CI-runs-over-time)
  derive persistent caches — prepare-before-demand.

12/12 witnesses green by execution; each test is one cell of the table,
fixtures mirror the live worked example (workflow/jobs/steps, retry, fleet).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
briansrls added a commit that referenced this pull request Jul 10, 2026
…sses

The operator's 4-rule business logic generalized on one axis: the decision is
a function of WHEN the redundancy is knowable and WHETHER what was knowable
was prepared for. Errors fire only on knowable-but-unprepared; genuine
emergence and declared triviality are typed acceptances, never silence.

std.materialization_ladder (dag/std):
- Frame/FrameKind: SharedStateFrame | IsolatedChildrenFrame |
  ReplayedFrame{attempts} | UnboundedSiblingsFrame — the nested-scope axis;
  a 'run' at any layer is a frame, never a different kind of thing.
- DemandNature: Pure | IdempotentEffect | WorldRead{envelope_declared} |
  FreshEffect — the D3 effect gate; TTL = unmodeled dependency XOR declared
  staleness, never an eviction knob.
- CacheProvider: keying (ContentKeyed|ExistenceKeyed) + EvictionPolicy
  (ScopeExit|SpacePacked) REQUIRED by construction — rule 3 unwritable-bad.
- LadderVerdict (total): AuthoredDuplication | Discharged | RefusedNoProvider
  | RefusedScopeTooNarrow | RefusedExistenceKeyed (the build-if-absent #6352
  wall) | RefusedUnmodeledWorldRead | ExemptFreshEffect |
  AcceptedBelowCostFloor | AcceptedSingleRecompute.
- Declared-emergent frames obligate UP FRONT: retry frames derive
  checkpointing, unbounded-sibling frames (server loops, CI-runs-over-time)
  derive persistent caches — prepare-before-demand.

12/12 witnesses green by execution; each test is one cell of the table,
fixtures mirror the live worked example (workflow/jobs/steps, retry, fleet).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
briansrls added a commit that referenced this pull request Jul 10, 2026
…sses

The operator's 4-rule business logic generalized on one axis: the decision is
a function of WHEN the redundancy is knowable and WHETHER what was knowable
was prepared for. Errors fire only on knowable-but-unprepared; genuine
emergence and declared triviality are typed acceptances, never silence.

std.materialization_ladder (dag/std):
- Frame/FrameKind: SharedStateFrame | IsolatedChildrenFrame |
  ReplayedFrame{attempts} | UnboundedSiblingsFrame — the nested-scope axis;
  a 'run' at any layer is a frame, never a different kind of thing.
- DemandNature: Pure | IdempotentEffect | WorldRead{envelope_declared} |
  FreshEffect — the D3 effect gate; TTL = unmodeled dependency XOR declared
  staleness, never an eviction knob.
- CacheProvider: keying (ContentKeyed|ExistenceKeyed) + EvictionPolicy
  (ScopeExit|SpacePacked) REQUIRED by construction — rule 3 unwritable-bad.
- LadderVerdict (total): AuthoredDuplication | Discharged | RefusedNoProvider
  | RefusedScopeTooNarrow | RefusedExistenceKeyed (the build-if-absent #6352
  wall) | RefusedUnmodeledWorldRead | ExemptFreshEffect |
  AcceptedBelowCostFloor | AcceptedSingleRecompute.
- Declared-emergent frames obligate UP FRONT: retry frames derive
  checkpointing, unbounded-sibling frames (server loops, CI-runs-over-time)
  derive persistent caches — prepare-before-demand.

12/12 witnesses green by execution; each test is one cell of the table,
fixtures mirror the live worked example (workflow/jobs/steps, retry, fleet).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
briansrls added a commit that referenced this pull request Jul 10, 2026
* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* Analysis spine: spine_receipt composes dependency_view + materialize (increment 1)

The Rc-safe half of run ≜ realize ∘ materialize ∘ dependency_view: compose
the two catamorphisms that need no interpreter thread-safety.

- src/v2/std/spine.dag: level-profile fold over the DependencyView DAG →
  critical_path_depth (longest dependency chain / the reduce spine) +
  independence_width (max nodes at one level / what parallelizes to hw width).
  spine_receipt emits the §9 numbers by COMPUTATION, not assertion, joining
  materialize's content-hash Share/dedup counts.
- Discriminating RED (§9): single chain A→B→C → depth 3 / width 1 (serial);
  root over N independent leaves → depth 2 / width N.
- Witnesses 9/9 (spine) green by execution; materialize 6/6 unchanged.

The RUNNER (wall-clock parallel execution, §8 steps 3-4) stays increment 2+,
gated on interpreter Rc→Arc (v1 interp is !Send). This increment measures the
achievable width/critical-path floor the runner targets; it does not fabricate
wall-clock N×.

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

* Unbundle recompute-trace interpreter extension from the analysis-spine PR

CI root cause: the recompute-trace extension edited v1_interpreter.rs, which
hosts the atom_identity_hash/hash_combine fnv1a64 intrinsics that
dag_collect_fingerprint_witness executes. That correctly invalidated the
re-verify 'assumed-green node-frontier' SKIP of that witness (cone-touch,
fail-closed) — but the witness is a pre-existing 806s (13min) fnv1a64
whole-corpus walk, so un-skipping it blew the 30-min floor budget. Main stays
green only because its interpreter cone is untouched (witness stays skipped).

The interpreter extension is a separable, env-gated (GUNBC_RECOMPUTE_TRACE=1),
READ-mode diagnostic — not a dependency of the spine/materialize analysis
substrate (pure .dag, content_hash-based). Reverting v1_interpreter.rs to main
restores byte-identical interpreter content → the fingerprint witness returns to
assumed-green SKIP → floor budget restored. The recompute-trace extension lands
as its own follow-up PR where the fingerprint-witness re-run is expected.

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

* WIP: Duplicate Computation

* Materialization ladder: the state x decision law, as executable witnesses

The operator's 4-rule business logic generalized on one axis: the decision is
a function of WHEN the redundancy is knowable and WHETHER what was knowable
was prepared for. Errors fire only on knowable-but-unprepared; genuine
emergence and declared triviality are typed acceptances, never silence.

std.materialization_ladder (dag/std):
- Frame/FrameKind: SharedStateFrame | IsolatedChildrenFrame |
  ReplayedFrame{attempts} | UnboundedSiblingsFrame — the nested-scope axis;
  a 'run' at any layer is a frame, never a different kind of thing.
- DemandNature: Pure | IdempotentEffect | WorldRead{envelope_declared} |
  FreshEffect — the D3 effect gate; TTL = unmodeled dependency XOR declared
  staleness, never an eviction knob.
- CacheProvider: keying (ContentKeyed|ExistenceKeyed) + EvictionPolicy
  (ScopeExit|SpacePacked) REQUIRED by construction — rule 3 unwritable-bad.
- LadderVerdict (total): AuthoredDuplication | Discharged | RefusedNoProvider
  | RefusedScopeTooNarrow | RefusedExistenceKeyed (the build-if-absent #6352
  wall) | RefusedUnmodeledWorldRead | ExemptFreshEffect |
  AcceptedBelowCostFloor | AcceptedSingleRecompute.
- Declared-emergent frames obligate UP FRONT: retry frames derive
  checkpointing, unbounded-sibling frames (server loops, CI-runs-over-time)
  derive persistent caches — prepare-before-demand.

12/12 witnesses green by execution; each test is one cell of the table,
fixtures mirror the live worked example (workflow/jobs/steps, retry, fleet).

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

* WIP: Duplicate Computation

* Docs crystallization: derived materialization placement into roadmap ④ + the state x decision table

- roadmap_authority ④ (ROADMAP.md regenerated via main_wet, drift-consistent):
  the nested-frame law, plurality cells, declared-emergent prepare-up-front,
  keying/staleness walls, the caching-completion un-shelve, the ①-vs-§2
  cross-run-caching contradiction subsumed into per-node derived verdicts,
  and the v1.compiler.ownership §3-convergence row.
- duplicate-work design doc: the state x decision table as the qualifier's
  final verdict logic + the ownership consolidation subsection.

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

* Consolidation plan: realization + materialization + ownership are one law

Operator synthesis (2026-07-09): Materialization = the verdict vocabulary;
ownership = the verdict computation at the eval frame; realization = provider
selection discharging the verdict at each frame's carrier. Share's handler is
layer-aware — the cheapest cache is a REFERENCE (same program + ref-capable
carrier + readonly => point-at-it, no copy, no destroyed memory), demoting
through HAMT structural share / process memo / artifact / CAS, and demotion
must be priced, never silent (#6249 clone-fallback is the receipt).

Census of every hand-rolled instance found in-tree (16 rows): each named with
its frame, ladder cell, action, and dissolution trigger — ownership
(consolidated), Rc/HAMT (reference tier), clone-fallback (demotion wall),
ParseTable + cached_stage (C5 grounding), M1 memo / intern / assumed-green /
sccache / cargo-cache (C2 provider rows), PROCESS_RESOLVE_STORE (C3 = the 9GB
scope fix), build-if-absent (landed as the keying wall), resolve-cache #5789
(rule-4 requirements), recompute-trace (state-4 finding source). Peers kept
distinct: affected-set, Independence/Placement, mutable state.

Sequence C1-C5 with C1 = this PR (ladder + live CI gate).

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

* WIP: Duplicate Computation

* Ownership refactored onto materialization: the value tier, tested as providers

First consolidation increment (operator-directed): v1.compiler.ownership's
decision IS provider selection at the value grain, now expressed in the ladder
and proven by mirror witnesses.

- ProviderTier: Reference | Copy | Memo{keying} | Artifact{keying} | Cas{keying}
  — keying folded INTO store tiers, so an existence-keyed reference is
  unwritable BY SHAPE (§5 construction); frame obligations at isolation LCAs
  are dischargeable only by store tiers (a reference cannot cross an isolation
  boundary — witnessed).
- Value tier: AccessMode (Read|Consume|Carry|Project), ValueUsage,
  value_materialization -> ValueDead | ValueMoved | ValueSharedByReference |
  ValueDemotedToCopy (PRICED, requires a declared CopyTier provider — the
  #6249 silent clone-fallback made refusable) | ValueRefusedAffine |
  ValueRefusedNoCarrierProvider.
- Faithful to v1's THREE distinct plurality readings, kept separate:
  take_count = semantic_consumer_count (Consumed only, affine axis);
  value_access_plurality = binding_fan_out (Carry excluded, reference axis);
  borrow_count = whole_value_borrow_count (Read+Carry not Project, movability).
- Fold-accumulator case mirrored at conservative pre-FoldAccUnwrap semantics:
  carries excluded from plurality but blocking the move -> demoted-to-copy.

23/23 witnesses green (14 frame cells + 9 value cells). Corpus-level
equivalence against live v1 ownership folds = the C4 receipt.

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

* WIP: Duplicate Computation

* WIP: Duplicate Computation/Materialization

* G: exhaustive cache/share census (52 mechanisms, 6 groups) + C0 catalog-grounding of provider rows + forward-wiring walls

The sweep found the tree already models caches: extdeps/cache cache_catalog
(CacheInterfaceCatalogFacts, 9 rows) + extdeps/realization carrier facts +
the warm==cold purity oracle. C0 grounds CacheProvider on that catalog
(provider_from_catalog projection; CacheProvider.id -> CacheInterfaceId)
so the ladder and the catalog never restate each other's half. Three
forward walls (demands-from-DependencyView, hand-cache shape lens,
live-provider-or-red) make new caches born as provider rows only.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* WIP: Duplicate Computation/Materialization

* C0: provider rows derive from the cited cache catalog (extdeps/cache/materialization.dag projection)

Operator ruling 2026-07-09: extdeps stays the ground-truth/interface layer;
every USE of a cache goes through materialization so memo never gets
re-invented. provider_from_catalog is the only door from a catalog row into
the ladder: keying/tier/eviction derived from cited facts (mechanism->class:
InProcess=>ScopeExit; Ttl/Lru/SizeBounded=>SpacePacked; Never/Manual outside
a process => typed ProjectionRefused, counted by the new enrolled witness;
HandAuthored/prefix-fallback keys => ExistenceKeyed until key-completeness
upgrades them). CI sccache row now derived, hand-typed tier facts deleted,
6/6 + 23/23 witnesses green. 10b re-scoped: v1-internal caches = inventory
only (retire with seed); ParseTable/cached_stage promoted to next.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* Fail-closed hardening: RefusedNatureConflict arm, weakest-claim nature default, UsesStep silence counted, ladder cells enrolled in CI

The complexity-lens false-clean lesson applied to this gate before anyone
relies on it: (1) heterogeneous natures on one identity were first-wins —
now a typed RefusedNatureConflict (24th ladder cell, RED witness); (2) an
unrostered run-step claimed PureComputation — now IdempotentEffect, the
weakest claim (verdict-identical, no purity overclaim; a misdeclared
WorldRead can no longer be legally memoized by default); (3) UsesStep
foreign actions produced silence — now a pinned denominator (==9; a new
foreign action must consciously bump it); (4) the ladder's 24 cells enroll
on the CI surface so the law's own witnesses gate every run. 24/24 + 7/7.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* WIP: Duplicate Computation/Materialization

* M1 ratchet bump: declared resolve count 1 -> 3 (gate's first live catch — enrollment pays counted resolves)

Run 29058798771: enrolling the ladder witness file moved resolves_total
1 -> 3 (each enrolled entry file pays one closure resolve against the
shared index) and the receipt gate redded that exact run — the designed
semantics, receipted in the note. Bump acknowledges the two witness-entry
resolves as declared debt; M2 (one closure resolve per roots set)
ratchets back toward 1.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Retire the M1/M2 labels from carriers (no-codename rule; collided with DESIGN's floor-memoization M1/M2)

Step renamed to 'Floor resolve receipt gate (declared cold-resolve count)';
notes and the gate echo now say what the things are: the counted
cold-resolve receipt, and the shared-resolve rewire (one closure resolve
per source-roots set). Naming-retirement note left on the carrier.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* WIP: Duplicate Computation/Materialization

* Run-step natures pinned as counted claims, not affordances

Operator ruling 2026-07-10: hardcoded shell scripts get no affordances
— run-steps are supposed to be modeled as typed intents and emitted
(shell-emission-model slice 4 covers ci_workflow RunSteps). Until that
slice lands, every nature in job_run_demands is a claim (rostered
FreshEffect / weakest-default IdempotentEffect), never derived from a
modeled effect row. Count the whole claimed-nature surface (16 by
execution) and pin it in the enrolled witness: a new raw-script step
must consciously bump the pin, and slice-4 migration becomes a
countable ratchet ending at zero, where the pin becomes a wall.
Rejected alternative recorded in the carrier note: a per-step
declared-natures roster (a second parallel ledger over scripts the
shell-emission plan already governs).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Regen DESIGN.md after main merge (duplicate-work row + #6373 body-lowering row coexist)

Conflict was both sides editing the open-threads list in design_document.dag:
ours added the duplicate-work thread, main's #6373 rewrote body-lowering to
Stages 1-3 LANDED. Resolution keeps both rows in the .dag authority; DESIGN.md
regenerated from it, never hand-edited.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Brian Searls <briansrls@gunb.ai>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
briansrls added a commit that referenced this pull request Jul 10, 2026
…ealization carrier, provider rows via provider_from_catalog (design: docs/plans/duplicate-work-graph-lens-design.md section 10b; the .dag-substrate demonstration lane) (#6422)

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Ground v2 ParseTable + cached_stage on materialization: inhabit the Real

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* Analysis spine: spine_receipt composes dependency_view + materialize (increment 1)

The Rc-safe half of run ≜ realize ∘ materialize ∘ dependency_view: compose
the two catamorphisms that need no interpreter thread-safety.

- src/v2/std/spine.dag: level-profile fold over the DependencyView DAG →
  critical_path_depth (longest dependency chain / the reduce spine) +
  independence_width (max nodes at one level / what parallelizes to hw width).
  spine_receipt emits the §9 numbers by COMPUTATION, not assertion, joining
  materialize's content-hash Share/dedup counts.
- Discriminating RED (§9): single chain A→B→C → depth 3 / width 1 (serial);
  root over N independent leaves → depth 2 / width N.
- Witnesses 9/9 (spine) green by execution; materialize 6/6 unchanged.

The RUNNER (wall-clock parallel execution, §8 steps 3-4) stays increment 2+,
gated on interpreter Rc→Arc (v1 interp is !Send). This increment measures the
achievable width/critical-path floor the runner targets; it does not fabricate
wall-clock N×.

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

* Unbundle recompute-trace interpreter extension from the analysis-spine PR

CI root cause: the recompute-trace extension edited v1_interpreter.rs, which
hosts the atom_identity_hash/hash_combine fnv1a64 intrinsics that
dag_collect_fingerprint_witness executes. That correctly invalidated the
re-verify 'assumed-green node-frontier' SKIP of that witness (cone-touch,
fail-closed) — but the witness is a pre-existing 806s (13min) fnv1a64
whole-corpus walk, so un-skipping it blew the 30-min floor budget. Main stays
green only because its interpreter cone is untouched (witness stays skipped).

The interpreter extension is a separable, env-gated (GUNBC_RECOMPUTE_TRACE=1),
READ-mode diagnostic — not a dependency of the spine/materialize analysis
substrate (pure .dag, content_hash-based). Reverting v1_interpreter.rs to main
restores byte-identical interpreter content → the fingerprint witness returns to
assumed-green SKIP → floor budget restored. The recompute-trace extension lands
as its own follow-up PR where the fingerprint-witness re-run is expected.

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

* WIP: Duplicate Computation

* Materialization ladder: the state x decision law, as executable witnesses

The operator's 4-rule business logic generalized on one axis: the decision is
a function of WHEN the redundancy is knowable and WHETHER what was knowable
was prepared for. Errors fire only on knowable-but-unprepared; genuine
emergence and declared triviality are typed acceptances, never silence.

std.materialization_ladder (dag/std):
- Frame/FrameKind: SharedStateFrame | IsolatedChildrenFrame |
  ReplayedFrame{attempts} | UnboundedSiblingsFrame — the nested-scope axis;
  a 'run' at any layer is a frame, never a different kind of thing.
- DemandNature: Pure | IdempotentEffect | WorldRead{envelope_declared} |
  FreshEffect — the D3 effect gate; TTL = unmodeled dependency XOR declared
  staleness, never an eviction knob.
- CacheProvider: keying (ContentKeyed|ExistenceKeyed) + EvictionPolicy
  (ScopeExit|SpacePacked) REQUIRED by construction — rule 3 unwritable-bad.
- LadderVerdict (total): AuthoredDuplication | Discharged | RefusedNoProvider
  | RefusedScopeTooNarrow | RefusedExistenceKeyed (the build-if-absent #6352
  wall) | RefusedUnmodeledWorldRead | ExemptFreshEffect |
  AcceptedBelowCostFloor | AcceptedSingleRecompute.
- Declared-emergent frames obligate UP FRONT: retry frames derive
  checkpointing, unbounded-sibling frames (server loops, CI-runs-over-time)
  derive persistent caches — prepare-before-demand.

12/12 witnesses green by execution; each test is one cell of the table,
fixtures mirror the live worked example (workflow/jobs/steps, retry, fleet).

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

* WIP: Duplicate Computation

* Docs crystallization: derived materialization placement into roadmap ④ + the state x decision table

- roadmap_authority ④ (ROADMAP.md regenerated via main_wet, drift-consistent):
  the nested-frame law, plurality cells, declared-emergent prepare-up-front,
  keying/staleness walls, the caching-completion un-shelve, the ①-vs-§2
  cross-run-caching contradiction subsumed into per-node derived verdicts,
  and the v1.compiler.ownership §3-convergence row.
- duplicate-work design doc: the state x decision table as the qualifier's
  final verdict logic + the ownership consolidation subsection.

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

* Consolidation plan: realization + materialization + ownership are one law

Operator synthesis (2026-07-09): Materialization = the verdict vocabulary;
ownership = the verdict computation at the eval frame; realization = provider
selection discharging the verdict at each frame's carrier. Share's handler is
layer-aware — the cheapest cache is a REFERENCE (same program + ref-capable
carrier + readonly => point-at-it, no copy, no destroyed memory), demoting
through HAMT structural share / process memo / artifact / CAS, and demotion
must be priced, never silent (#6249 clone-fallback is the receipt).

Census of every hand-rolled instance found in-tree (16 rows): each named with
its frame, ladder cell, action, and dissolution trigger — ownership
(consolidated), Rc/HAMT (reference tier), clone-fallback (demotion wall),
ParseTable + cached_stage (C5 grounding), M1 memo / intern / assumed-green /
sccache / cargo-cache (C2 provider rows), PROCESS_RESOLVE_STORE (C3 = the 9GB
scope fix), build-if-absent (landed as the keying wall), resolve-cache #5789
(rule-4 requirements), recompute-trace (state-4 finding source). Peers kept
distinct: affected-set, Independence/Placement, mutable state.

Sequence C1-C5 with C1 = this PR (ladder + live CI gate).

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

* WIP: Duplicate Computation

* Ownership refactored onto materialization: the value tier, tested as providers

First consolidation increment (operator-directed): v1.compiler.ownership's
decision IS provider selection at the value grain, now expressed in the ladder
and proven by mirror witnesses.

- ProviderTier: Reference | Copy | Memo{keying} | Artifact{keying} | Cas{keying}
  — keying folded INTO store tiers, so an existence-keyed reference is
  unwritable BY SHAPE (§5 construction); frame obligations at isolation LCAs
  are dischargeable only by store tiers (a reference cannot cross an isolation
  boundary — witnessed).
- Value tier: AccessMode (Read|Consume|Carry|Project), ValueUsage,
  value_materialization -> ValueDead | ValueMoved | ValueSharedByReference |
  ValueDemotedToCopy (PRICED, requires a declared CopyTier provider — the
  #6249 silent clone-fallback made refusable) | ValueRefusedAffine |
  ValueRefusedNoCarrierProvider.
- Faithful to v1's THREE distinct plurality readings, kept separate:
  take_count = semantic_consumer_count (Consumed only, affine axis);
  value_access_plurality = binding_fan_out (Carry excluded, reference axis);
  borrow_count = whole_value_borrow_count (Read+Carry not Project, movability).
- Fold-accumulator case mirrored at conservative pre-FoldAccUnwrap semantics:
  carries excluded from plurality but blocking the move -> demoted-to-copy.

23/23 witnesses green (14 frame cells + 9 value cells). Corpus-level
equivalence against live v1 ownership folds = the C4 receipt.

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

* WIP: Duplicate Computation

* WIP: Duplicate Computation/Materialization

* G: exhaustive cache/share census (52 mechanisms, 6 groups) + C0 catalog-grounding of provider rows + forward-wiring walls

The sweep found the tree already models caches: extdeps/cache cache_catalog
(CacheInterfaceCatalogFacts, 9 rows) + extdeps/realization carrier facts +
the warm==cold purity oracle. C0 grounds CacheProvider on that catalog
(provider_from_catalog projection; CacheProvider.id -> CacheInterfaceId)
so the ladder and the catalog never restate each other's half. Three
forward walls (demands-from-DependencyView, hand-cache shape lens,
live-provider-or-red) make new caches born as provider rows only.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* WIP: Duplicate Computation/Materialization

* C0: provider rows derive from the cited cache catalog (extdeps/cache/materialization.dag projection)

Operator ruling 2026-07-09: extdeps stays the ground-truth/interface layer;
every USE of a cache goes through materialization so memo never gets
re-invented. provider_from_catalog is the only door from a catalog row into
the ladder: keying/tier/eviction derived from cited facts (mechanism->class:
InProcess=>ScopeExit; Ttl/Lru/SizeBounded=>SpacePacked; Never/Manual outside
a process => typed ProjectionRefused, counted by the new enrolled witness;
HandAuthored/prefix-fallback keys => ExistenceKeyed until key-completeness
upgrades them). CI sccache row now derived, hand-typed tier facts deleted,
6/6 + 23/23 witnesses green. 10b re-scoped: v1-internal caches = inventory
only (retire with seed); ParseTable/cached_stage promoted to next.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* WIP: Ground v2 ParseTable + cached_stage on materialization: inhabit the Real

* Fix compiler materialization witnesses: RealizedStep carrier, plural RED fixture.

Use RealizedStep<Nano> (not unit), drop 02_parse import from witnesses in favor
of parse_table_carrier_grounded_on_catalog, and model cross-run memo plurality
with an isolation-boundary LCA matching the CI ladder pattern.

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

* Fix CI: move materialization_carriers to compiler layer (no std→extdeps import).

Resolves layering_imports_gate and compile-clean failures from v2.std
importing extdeps via materialization_carriers. CachedStageRealization lives
in v2.compiler.materialization_carriers; staging.dag stays transport-only.

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

* WIP: Ground v2 ParseTable + cached_stage on materialization: inhabit the Real

* WIP: Ground v2 ParseTable + cached_stage on materialization: inhabit the Real

* Fix governed memo door: resolve_probe in cached_stage_governed, parse lookup match braces.

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

* WIP: Ground v2 ParseTable + cached_stage on materialization: inhabit the Real

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* Fail-closed hardening: RefusedNatureConflict arm, weakest-claim nature default, UsesStep silence counted, ladder cells enrolled in CI

The complexity-lens false-clean lesson applied to this gate before anyone
relies on it: (1) heterogeneous natures on one identity were first-wins —
now a typed RefusedNatureConflict (24th ladder cell, RED witness); (2) an
unrostered run-step claimed PureComputation — now IdempotentEffect, the
weakest claim (verdict-identical, no purity overclaim; a misdeclared
WorldRead can no longer be legally memoized by default); (3) UsesStep
foreign actions produced silence — now a pinned denominator (==9; a new
foreign action must consciously bump it); (4) the ladder's 24 cells enroll
on the CI surface so the law's own witnesses gate every run. 24/24 + 7/7.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Merge merry-moth-539 (main-integrated); harden governed memo door witnesses.

Merge origin/session/merry-moth-539 for post-main semantics alignment.
Export parse_table_memo_lookup_refuses_store / parse_table_memo_insert_refused
door oracles in 02_parse; witnesses call them directly (reason atom, not full
Diagnostic equality).

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

* WIP: Ground v2 ParseTable + cached_stage on materialization: inhabit the Real

* Regenerate ci.yml for floor resolve receipt pin at 3.

CI run 29059860791 measured resolves_total=3 after enrolling the two
new v2 witness entry classes; sync the emitted gate with
ci_floor_declared_resolve_count in ci_materialization.dag.

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

* WIP: Ground v2 ParseTable + cached_stage on materialization: inhabit the Real

* fix: escape ComputationIdentity braces in design_document.dag

Rebase conflict left unescaped {bound}/{cause} in a li() string, which
broke dag compile and the generated-artifact drift gate. Regenerate ci.yml.

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

* merge origin/main and resolve conflict markers; fix ParseTableMemo Case-A leak

Integrate main (#6431) atop #6375 base. Remove leftover merge conflict
markers from ci_materialization, commit_workflow, design_document, ci.yml.
Gate seed ParseTableMemo insert/serve on Memoize only (after governed door)
so insert-then-lookup door observables are order-independent; enroll
parse_table_memo_door_order_independent witness.

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

* fix: add Terminal disposition contracts for carrier predicate helpers

Land v2_compiler_materialization_memo_gate_predicate_contract and
v2_compiler_catalog_projection_predicate_contract on
materialization_allows_memo_store / projection_is_projected — matching
the Terminal predicate discipline already in materialization_ladder.dag.

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

* fix: correct resolve-receipt note attribution for #6422 enrollments

Pin was already 3 before #6422 witness entries; run 29059860791 held
at 3 with those entries enrolled because they pooled warm on the shared
index (zero additional cold resolves). Remove false per-entry bump claim.

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

* WIP: Ground v2 ParseTable + cached_stage on materialization: inhabit the Real

* fix: drop duplicate projection_is_projected; use extdeps authority

Remove forked CatalogProviderProjection predicate from
materialization_carriers.dag; projection_ok cells now call
!projection_is_refused from extdeps.cache.materialization (§3 single
authority). Remove local Terminal contract that documented the fork.

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

* fix(ci): raise floor step timeout to 45m for #6422 witness cone

Receipt run 29065683045 @ a2bcd6f: batches 1-3 ~20m, batch 4
rust_monolith_gate killed at 30m step cap. Bump floor step and ci/ci_regen
job backstop (85m→100m) to match rust gate step budget.

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

---------

Co-authored-by: Brian Searls <briansrls@gunb.ai>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
briansrls added a commit that referenced this pull request Jul 10, 2026
…rier (#6435)

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* Analysis spine: spine_receipt composes dependency_view + materialize (increment 1)

The Rc-safe half of run ≜ realize ∘ materialize ∘ dependency_view: compose
the two catamorphisms that need no interpreter thread-safety.

- src/v2/std/spine.dag: level-profile fold over the DependencyView DAG →
  critical_path_depth (longest dependency chain / the reduce spine) +
  independence_width (max nodes at one level / what parallelizes to hw width).
  spine_receipt emits the §9 numbers by COMPUTATION, not assertion, joining
  materialize's content-hash Share/dedup counts.
- Discriminating RED (§9): single chain A→B→C → depth 3 / width 1 (serial);
  root over N independent leaves → depth 2 / width N.
- Witnesses 9/9 (spine) green by execution; materialize 6/6 unchanged.

The RUNNER (wall-clock parallel execution, §8 steps 3-4) stays increment 2+,
gated on interpreter Rc→Arc (v1 interp is !Send). This increment measures the
achievable width/critical-path floor the runner targets; it does not fabricate
wall-clock N×.

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

* Unbundle recompute-trace interpreter extension from the analysis-spine PR

CI root cause: the recompute-trace extension edited v1_interpreter.rs, which
hosts the atom_identity_hash/hash_combine fnv1a64 intrinsics that
dag_collect_fingerprint_witness executes. That correctly invalidated the
re-verify 'assumed-green node-frontier' SKIP of that witness (cone-touch,
fail-closed) — but the witness is a pre-existing 806s (13min) fnv1a64
whole-corpus walk, so un-skipping it blew the 30-min floor budget. Main stays
green only because its interpreter cone is untouched (witness stays skipped).

The interpreter extension is a separable, env-gated (GUNBC_RECOMPUTE_TRACE=1),
READ-mode diagnostic — not a dependency of the spine/materialize analysis
substrate (pure .dag, content_hash-based). Reverting v1_interpreter.rs to main
restores byte-identical interpreter content → the fingerprint witness returns to
assumed-green SKIP → floor budget restored. The recompute-trace extension lands
as its own follow-up PR where the fingerprint-witness re-run is expected.

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

* WIP: Duplicate Computation

* Materialization ladder: the state x decision law, as executable witnesses

The operator's 4-rule business logic generalized on one axis: the decision is
a function of WHEN the redundancy is knowable and WHETHER what was knowable
was prepared for. Errors fire only on knowable-but-unprepared; genuine
emergence and declared triviality are typed acceptances, never silence.

std.materialization_ladder (dag/std):
- Frame/FrameKind: SharedStateFrame | IsolatedChildrenFrame |
  ReplayedFrame{attempts} | UnboundedSiblingsFrame — the nested-scope axis;
  a 'run' at any layer is a frame, never a different kind of thing.
- DemandNature: Pure | IdempotentEffect | WorldRead{envelope_declared} |
  FreshEffect — the D3 effect gate; TTL = unmodeled dependency XOR declared
  staleness, never an eviction knob.
- CacheProvider: keying (ContentKeyed|ExistenceKeyed) + EvictionPolicy
  (ScopeExit|SpacePacked) REQUIRED by construction — rule 3 unwritable-bad.
- LadderVerdict (total): AuthoredDuplication | Discharged | RefusedNoProvider
  | RefusedScopeTooNarrow | RefusedExistenceKeyed (the build-if-absent #6352
  wall) | RefusedUnmodeledWorldRead | ExemptFreshEffect |
  AcceptedBelowCostFloor | AcceptedSingleRecompute.
- Declared-emergent frames obligate UP FRONT: retry frames derive
  checkpointing, unbounded-sibling frames (server loops, CI-runs-over-time)
  derive persistent caches — prepare-before-demand.

12/12 witnesses green by execution; each test is one cell of the table,
fixtures mirror the live worked example (workflow/jobs/steps, retry, fleet).

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

* WIP: Duplicate Computation

* Docs crystallization: derived materialization placement into roadmap ④ + the state x decision table

- roadmap_authority ④ (ROADMAP.md regenerated via main_wet, drift-consistent):
  the nested-frame law, plurality cells, declared-emergent prepare-up-front,
  keying/staleness walls, the caching-completion un-shelve, the ①-vs-§2
  cross-run-caching contradiction subsumed into per-node derived verdicts,
  and the v1.compiler.ownership §3-convergence row.
- duplicate-work design doc: the state x decision table as the qualifier's
  final verdict logic + the ownership consolidation subsection.

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

* Consolidation plan: realization + materialization + ownership are one law

Operator synthesis (2026-07-09): Materialization = the verdict vocabulary;
ownership = the verdict computation at the eval frame; realization = provider
selection discharging the verdict at each frame's carrier. Share's handler is
layer-aware — the cheapest cache is a REFERENCE (same program + ref-capable
carrier + readonly => point-at-it, no copy, no destroyed memory), demoting
through HAMT structural share / process memo / artifact / CAS, and demotion
must be priced, never silent (#6249 clone-fallback is the receipt).

Census of every hand-rolled instance found in-tree (16 rows): each named with
its frame, ladder cell, action, and dissolution trigger — ownership
(consolidated), Rc/HAMT (reference tier), clone-fallback (demotion wall),
ParseTable + cached_stage (C5 grounding), M1 memo / intern / assumed-green /
sccache / cargo-cache (C2 provider rows), PROCESS_RESOLVE_STORE (C3 = the 9GB
scope fix), build-if-absent (landed as the keying wall), resolve-cache #5789
(rule-4 requirements), recompute-trace (state-4 finding source). Peers kept
distinct: affected-set, Independence/Placement, mutable state.

Sequence C1-C5 with C1 = this PR (ladder + live CI gate).

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

* WIP: Duplicate Computation

* Ownership refactored onto materialization: the value tier, tested as providers

First consolidation increment (operator-directed): v1.compiler.ownership's
decision IS provider selection at the value grain, now expressed in the ladder
and proven by mirror witnesses.

- ProviderTier: Reference | Copy | Memo{keying} | Artifact{keying} | Cas{keying}
  — keying folded INTO store tiers, so an existence-keyed reference is
  unwritable BY SHAPE (§5 construction); frame obligations at isolation LCAs
  are dischargeable only by store tiers (a reference cannot cross an isolation
  boundary — witnessed).
- Value tier: AccessMode (Read|Consume|Carry|Project), ValueUsage,
  value_materialization -> ValueDead | ValueMoved | ValueSharedByReference |
  ValueDemotedToCopy (PRICED, requires a declared CopyTier provider — the
  #6249 silent clone-fallback made refusable) | ValueRefusedAffine |
  ValueRefusedNoCarrierProvider.
- Faithful to v1's THREE distinct plurality readings, kept separate:
  take_count = semantic_consumer_count (Consumed only, affine axis);
  value_access_plurality = binding_fan_out (Carry excluded, reference axis);
  borrow_count = whole_value_borrow_count (Read+Carry not Project, movability).
- Fold-accumulator case mirrored at conservative pre-FoldAccUnwrap semantics:
  carries excluded from plurality but blocking the move -> demoted-to-copy.

23/23 witnesses green (14 frame cells + 9 value cells). Corpus-level
equivalence against live v1 ownership folds = the C4 receipt.

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

* WIP: Duplicate Computation

* WIP: Duplicate Computation/Materialization

* G: exhaustive cache/share census (52 mechanisms, 6 groups) + C0 catalog-grounding of provider rows + forward-wiring walls

The sweep found the tree already models caches: extdeps/cache cache_catalog
(CacheInterfaceCatalogFacts, 9 rows) + extdeps/realization carrier facts +
the warm==cold purity oracle. C0 grounds CacheProvider on that catalog
(provider_from_catalog projection; CacheProvider.id -> CacheInterfaceId)
so the ladder and the catalog never restate each other's half. Three
forward walls (demands-from-DependencyView, hand-cache shape lens,
live-provider-or-red) make new caches born as provider rows only.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* WIP: Duplicate Computation/Materialization

* C0: provider rows derive from the cited cache catalog (extdeps/cache/materialization.dag projection)

Operator ruling 2026-07-09: extdeps stays the ground-truth/interface layer;
every USE of a cache goes through materialization so memo never gets
re-invented. provider_from_catalog is the only door from a catalog row into
the ladder: keying/tier/eviction derived from cited facts (mechanism->class:
InProcess=>ScopeExit; Ttl/Lru/SizeBounded=>SpacePacked; Never/Manual outside
a process => typed ProjectionRefused, counted by the new enrolled witness;
HandAuthored/prefix-fallback keys => ExistenceKeyed until key-completeness
upgrades them). CI sccache row now derived, hand-typed tier facts deleted,
6/6 + 23/23 witnesses green. 10b re-scoped: v1-internal caches = inventory
only (retire with seed); ParseTable/cached_stage promoted to next.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* Fail-closed hardening: RefusedNatureConflict arm, weakest-claim nature default, UsesStep silence counted, ladder cells enrolled in CI

The complexity-lens false-clean lesson applied to this gate before anyone
relies on it: (1) heterogeneous natures on one identity were first-wins —
now a typed RefusedNatureConflict (24th ladder cell, RED witness); (2) an
unrostered run-step claimed PureComputation — now IdempotentEffect, the
weakest claim (verdict-identical, no purity overclaim; a misdeclared
WorldRead can no longer be legally memoized by default); (3) UsesStep
foreign actions produced silence — now a pinned denominator (==9; a new
foreign action must consciously bump it); (4) the ladder's 24 cells enroll
on the CI surface so the law's own witnesses gate every run. 24/24 + 7/7.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* WIP: Duplicate Computation/Materialization

* M1 ratchet bump: declared resolve count 1 -> 3 (gate's first live catch — enrollment pays counted resolves)

Run 29058798771: enrolling the ladder witness file moved resolves_total
1 -> 3 (each enrolled entry file pays one closure resolve against the
shared index) and the receipt gate redded that exact run — the designed
semantics, receipted in the note. Bump acknowledges the two witness-entry
resolves as declared debt; M2 (one closure resolve per roots set)
ratchets back toward 1.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Retire the M1/M2 labels from carriers (no-codename rule; collided with DESIGN's floor-memoization M1/M2)

Step renamed to 'Floor resolve receipt gate (declared cold-resolve count)';
notes and the gate echo now say what the things are: the counted
cold-resolve receipt, and the shared-resolve rewire (one closure resolve
per source-roots set). Naming-retirement note left on the carrier.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* WIP: Duplicate Computation/Materialization

* Run-step natures pinned as counted claims, not affordances

Operator ruling 2026-07-10: hardcoded shell scripts get no affordances
— run-steps are supposed to be modeled as typed intents and emitted
(shell-emission-model slice 4 covers ci_workflow RunSteps). Until that
slice lands, every nature in job_run_demands is a claim (rostered
FreshEffect / weakest-default IdempotentEffect), never derived from a
modeled effect row. Count the whole claimed-nature surface (16 by
execution) and pin it in the enrolled witness: a new raw-script step
must consciously bump the pin, and slice-4 migration becomes a
countable ratchet ending at zero, where the pin becomes a wall.
Rejected alternative recorded in the carrier note: a per-step
declared-natures roster (a second parallel ledger over scripts the
shell-emission plan already governs).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Regen DESIGN.md after main merge (duplicate-work row + #6373 body-lowering row coexist)

Conflict was both sides editing the open-threads list in design_document.dag:
ours added the duplicate-work thread, main's #6373 rewrote body-lowering to
Stages 1-3 LANDED. Resolution keeps both rows in the .dag authority; DESIGN.md
regenerated from it, never hand-edited.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* WIP: Duplicate Computation/Materialization

---------

Co-authored-by: Brian Searls <briansrls@gunb.ai>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
briansrls added a commit that referenced this pull request Jul 10, 2026
…ate (#6441)

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* Analysis spine: spine_receipt composes dependency_view + materialize (increment 1)

The Rc-safe half of run ≜ realize ∘ materialize ∘ dependency_view: compose
the two catamorphisms that need no interpreter thread-safety.

- src/v2/std/spine.dag: level-profile fold over the DependencyView DAG →
  critical_path_depth (longest dependency chain / the reduce spine) +
  independence_width (max nodes at one level / what parallelizes to hw width).
  spine_receipt emits the §9 numbers by COMPUTATION, not assertion, joining
  materialize's content-hash Share/dedup counts.
- Discriminating RED (§9): single chain A→B→C → depth 3 / width 1 (serial);
  root over N independent leaves → depth 2 / width N.
- Witnesses 9/9 (spine) green by execution; materialize 6/6 unchanged.

The RUNNER (wall-clock parallel execution, §8 steps 3-4) stays increment 2+,
gated on interpreter Rc→Arc (v1 interp is !Send). This increment measures the
achievable width/critical-path floor the runner targets; it does not fabricate
wall-clock N×.

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

* Unbundle recompute-trace interpreter extension from the analysis-spine PR

CI root cause: the recompute-trace extension edited v1_interpreter.rs, which
hosts the atom_identity_hash/hash_combine fnv1a64 intrinsics that
dag_collect_fingerprint_witness executes. That correctly invalidated the
re-verify 'assumed-green node-frontier' SKIP of that witness (cone-touch,
fail-closed) — but the witness is a pre-existing 806s (13min) fnv1a64
whole-corpus walk, so un-skipping it blew the 30-min floor budget. Main stays
green only because its interpreter cone is untouched (witness stays skipped).

The interpreter extension is a separable, env-gated (GUNBC_RECOMPUTE_TRACE=1),
READ-mode diagnostic — not a dependency of the spine/materialize analysis
substrate (pure .dag, content_hash-based). Reverting v1_interpreter.rs to main
restores byte-identical interpreter content → the fingerprint witness returns to
assumed-green SKIP → floor budget restored. The recompute-trace extension lands
as its own follow-up PR where the fingerprint-witness re-run is expected.

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

* WIP: Duplicate Computation

* Materialization ladder: the state x decision law, as executable witnesses

The operator's 4-rule business logic generalized on one axis: the decision is
a function of WHEN the redundancy is knowable and WHETHER what was knowable
was prepared for. Errors fire only on knowable-but-unprepared; genuine
emergence and declared triviality are typed acceptances, never silence.

std.materialization_ladder (dag/std):
- Frame/FrameKind: SharedStateFrame | IsolatedChildrenFrame |
  ReplayedFrame{attempts} | UnboundedSiblingsFrame — the nested-scope axis;
  a 'run' at any layer is a frame, never a different kind of thing.
- DemandNature: Pure | IdempotentEffect | WorldRead{envelope_declared} |
  FreshEffect — the D3 effect gate; TTL = unmodeled dependency XOR declared
  staleness, never an eviction knob.
- CacheProvider: keying (ContentKeyed|ExistenceKeyed) + EvictionPolicy
  (ScopeExit|SpacePacked) REQUIRED by construction — rule 3 unwritable-bad.
- LadderVerdict (total): AuthoredDuplication | Discharged | RefusedNoProvider
  | RefusedScopeTooNarrow | RefusedExistenceKeyed (the build-if-absent #6352
  wall) | RefusedUnmodeledWorldRead | ExemptFreshEffect |
  AcceptedBelowCostFloor | AcceptedSingleRecompute.
- Declared-emergent frames obligate UP FRONT: retry frames derive
  checkpointing, unbounded-sibling frames (server loops, CI-runs-over-time)
  derive persistent caches — prepare-before-demand.

12/12 witnesses green by execution; each test is one cell of the table,
fixtures mirror the live worked example (workflow/jobs/steps, retry, fleet).

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

* WIP: Duplicate Computation

* Docs crystallization: derived materialization placement into roadmap ④ + the state x decision table

- roadmap_authority ④ (ROADMAP.md regenerated via main_wet, drift-consistent):
  the nested-frame law, plurality cells, declared-emergent prepare-up-front,
  keying/staleness walls, the caching-completion un-shelve, the ①-vs-§2
  cross-run-caching contradiction subsumed into per-node derived verdicts,
  and the v1.compiler.ownership §3-convergence row.
- duplicate-work design doc: the state x decision table as the qualifier's
  final verdict logic + the ownership consolidation subsection.

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

* Consolidation plan: realization + materialization + ownership are one law

Operator synthesis (2026-07-09): Materialization = the verdict vocabulary;
ownership = the verdict computation at the eval frame; realization = provider
selection discharging the verdict at each frame's carrier. Share's handler is
layer-aware — the cheapest cache is a REFERENCE (same program + ref-capable
carrier + readonly => point-at-it, no copy, no destroyed memory), demoting
through HAMT structural share / process memo / artifact / CAS, and demotion
must be priced, never silent (#6249 clone-fallback is the receipt).

Census of every hand-rolled instance found in-tree (16 rows): each named with
its frame, ladder cell, action, and dissolution trigger — ownership
(consolidated), Rc/HAMT (reference tier), clone-fallback (demotion wall),
ParseTable + cached_stage (C5 grounding), M1 memo / intern / assumed-green /
sccache / cargo-cache (C2 provider rows), PROCESS_RESOLVE_STORE (C3 = the 9GB
scope fix), build-if-absent (landed as the keying wall), resolve-cache #5789
(rule-4 requirements), recompute-trace (state-4 finding source). Peers kept
distinct: affected-set, Independence/Placement, mutable state.

Sequence C1-C5 with C1 = this PR (ladder + live CI gate).

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

* WIP: Duplicate Computation

* Ownership refactored onto materialization: the value tier, tested as providers

First consolidation increment (operator-directed): v1.compiler.ownership's
decision IS provider selection at the value grain, now expressed in the ladder
and proven by mirror witnesses.

- ProviderTier: Reference | Copy | Memo{keying} | Artifact{keying} | Cas{keying}
  — keying folded INTO store tiers, so an existence-keyed reference is
  unwritable BY SHAPE (§5 construction); frame obligations at isolation LCAs
  are dischargeable only by store tiers (a reference cannot cross an isolation
  boundary — witnessed).
- Value tier: AccessMode (Read|Consume|Carry|Project), ValueUsage,
  value_materialization -> ValueDead | ValueMoved | ValueSharedByReference |
  ValueDemotedToCopy (PRICED, requires a declared CopyTier provider — the
  #6249 silent clone-fallback made refusable) | ValueRefusedAffine |
  ValueRefusedNoCarrierProvider.
- Faithful to v1's THREE distinct plurality readings, kept separate:
  take_count = semantic_consumer_count (Consumed only, affine axis);
  value_access_plurality = binding_fan_out (Carry excluded, reference axis);
  borrow_count = whole_value_borrow_count (Read+Carry not Project, movability).
- Fold-accumulator case mirrored at conservative pre-FoldAccUnwrap semantics:
  carries excluded from plurality but blocking the move -> demoted-to-copy.

23/23 witnesses green (14 frame cells + 9 value cells). Corpus-level
equivalence against live v1 ownership folds = the C4 receipt.

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

* WIP: Duplicate Computation

* WIP: Duplicate Computation/Materialization

* G: exhaustive cache/share census (52 mechanisms, 6 groups) + C0 catalog-grounding of provider rows + forward-wiring walls

The sweep found the tree already models caches: extdeps/cache cache_catalog
(CacheInterfaceCatalogFacts, 9 rows) + extdeps/realization carrier facts +
the warm==cold purity oracle. C0 grounds CacheProvider on that catalog
(provider_from_catalog projection; CacheProvider.id -> CacheInterfaceId)
so the ladder and the catalog never restate each other's half. Three
forward walls (demands-from-DependencyView, hand-cache shape lens,
live-provider-or-red) make new caches born as provider rows only.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* WIP: Duplicate Computation/Materialization

* C0: provider rows derive from the cited cache catalog (extdeps/cache/materialization.dag projection)

Operator ruling 2026-07-09: extdeps stays the ground-truth/interface layer;
every USE of a cache goes through materialization so memo never gets
re-invented. provider_from_catalog is the only door from a catalog row into
the ladder: keying/tier/eviction derived from cited facts (mechanism->class:
InProcess=>ScopeExit; Ttl/Lru/SizeBounded=>SpacePacked; Never/Manual outside
a process => typed ProjectionRefused, counted by the new enrolled witness;
HandAuthored/prefix-fallback keys => ExistenceKeyed until key-completeness
upgrades them). CI sccache row now derived, hand-typed tier facts deleted,
6/6 + 23/23 witnesses green. 10b re-scoped: v1-internal caches = inventory
only (retire with seed); ParseTable/cached_stage promoted to next.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* Fail-closed hardening: RefusedNatureConflict arm, weakest-claim nature default, UsesStep silence counted, ladder cells enrolled in CI

The complexity-lens false-clean lesson applied to this gate before anyone
relies on it: (1) heterogeneous natures on one identity were first-wins —
now a typed RefusedNatureConflict (24th ladder cell, RED witness); (2) an
unrostered run-step claimed PureComputation — now IdempotentEffect, the
weakest claim (verdict-identical, no purity overclaim; a misdeclared
WorldRead can no longer be legally memoized by default); (3) UsesStep
foreign actions produced silence — now a pinned denominator (==9; a new
foreign action must consciously bump it); (4) the ladder's 24 cells enroll
on the CI surface so the law's own witnesses gate every run. 24/24 + 7/7.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* WIP: Duplicate Computation/Materialization

* M1 ratchet bump: declared resolve count 1 -> 3 (gate's first live catch — enrollment pays counted resolves)

Run 29058798771: enrolling the ladder witness file moved resolves_total
1 -> 3 (each enrolled entry file pays one closure resolve against the
shared index) and the receipt gate redded that exact run — the designed
semantics, receipted in the note. Bump acknowledges the two witness-entry
resolves as declared debt; M2 (one closure resolve per roots set)
ratchets back toward 1.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Retire the M1/M2 labels from carriers (no-codename rule; collided with DESIGN's floor-memoization M1/M2)

Step renamed to 'Floor resolve receipt gate (declared cold-resolve count)';
notes and the gate echo now say what the things are: the counted
cold-resolve receipt, and the shared-resolve rewire (one closure resolve
per source-roots set). Naming-retirement note left on the carrier.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* WIP: Duplicate Computation/Materialization

* Run-step natures pinned as counted claims, not affordances

Operator ruling 2026-07-10: hardcoded shell scripts get no affordances
— run-steps are supposed to be modeled as typed intents and emitted
(shell-emission-model slice 4 covers ci_workflow RunSteps). Until that
slice lands, every nature in job_run_demands is a claim (rostered
FreshEffect / weakest-default IdempotentEffect), never derived from a
modeled effect row. Count the whole claimed-nature surface (16 by
execution) and pin it in the enrolled witness: a new raw-script step
must consciously bump the pin, and slice-4 migration becomes a
countable ratchet ending at zero, where the pin becomes a wall.
Rejected alternative recorded in the carrier note: a per-step
declared-natures roster (a second parallel ledger over scripts the
shell-emission plan already governs).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Regen DESIGN.md after main merge (duplicate-work row + #6373 body-lowering row coexist)

Conflict was both sides editing the open-threads list in design_document.dag:
ours added the duplicate-work thread, main's #6373 rewrote body-lowering to
Stages 1-3 LANDED. Resolution keeps both rows in the .dag authority; DESIGN.md
regenerated from it, never hand-edited.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* Inferred materialization increment 1: floor demand ledger + receipt-or-red gate

Running IS enrolling: the interpreter ledgers every keyed pure call and every
InterpContext absorbs its totals into a process accumulator on Drop — by
construction, no eval path escapes the receipt. claim_executor writes
target/floor-materialization-receipt.txt at walk end; trace defaults ON in
the executor, and an explicit =0 zeroes keyed_calls which the gate refuses.

Gate arms this push (all verified under dash from the emitted ci.yml):
receipt missing/malformed/keyed_calls=0 fail closed. Exact pins for
unkeyed_calls and duplicated_keys land from the FIRST CI receipt (the
resolve gate's measure-then-pin path) — unkeyed is known nonzero on the
floor (count_matching takes a predicate closure; closures are the one
disclosed identity-less class, dissolve-on captured-env content identity).

Unit witness green: resolve -> eval -> ctx Drop -> absorb -> drain-once.
Step addition bumped the claimed-natures pin 16 -> 17 consciously.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Review fix: drop the racy drain-once assertion from the receipt unit test

opus-4-7 finding on #6441: under plain cargo test (still the documented
runner) tests share a process, the env latch is OnceLock-sticky, and
sibling ctx drops could absorb between the two takes — making the
drain-empty assertion racy. Absorb-on-Drop stays asserted (monotone under
concurrent absorbs: siblings only ADD); drain-once is Option::take by
construction, not asserted through the shared global. Comment states the
sharing semantics explicitly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

---------

Co-authored-by: Brian Searls <briansrls@gunb.ai>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@gunbai-bot gunbai-bot Bot mentioned this pull request Jul 10, 2026
briansrls added a commit that referenced this pull request Jul 10, 2026
… gated) (#6455)

* Inferred materialization increment 1: floor demand ledger + receipt gate (#6441)

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* Analysis spine: spine_receipt composes dependency_view + materialize (increment 1)

The Rc-safe half of run ≜ realize ∘ materialize ∘ dependency_view: compose
the two catamorphisms that need no interpreter thread-safety.

- src/v2/std/spine.dag: level-profile fold over the DependencyView DAG →
  critical_path_depth (longest dependency chain / the reduce spine) +
  independence_width (max nodes at one level / what parallelizes to hw width).
  spine_receipt emits the §9 numbers by COMPUTATION, not assertion, joining
  materialize's content-hash Share/dedup counts.
- Discriminating RED (§9): single chain A→B→C → depth 3 / width 1 (serial);
  root over N independent leaves → depth 2 / width N.
- Witnesses 9/9 (spine) green by execution; materialize 6/6 unchanged.

The RUNNER (wall-clock parallel execution, §8 steps 3-4) stays increment 2+,
gated on interpreter Rc→Arc (v1 interp is !Send). This increment measures the
achievable width/critical-path floor the runner targets; it does not fabricate
wall-clock N×.

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

* Unbundle recompute-trace interpreter extension from the analysis-spine PR

CI root cause: the recompute-trace extension edited v1_interpreter.rs, which
hosts the atom_identity_hash/hash_combine fnv1a64 intrinsics that
dag_collect_fingerprint_witness executes. That correctly invalidated the
re-verify 'assumed-green node-frontier' SKIP of that witness (cone-touch,
fail-closed) — but the witness is a pre-existing 806s (13min) fnv1a64
whole-corpus walk, so un-skipping it blew the 30-min floor budget. Main stays
green only because its interpreter cone is untouched (witness stays skipped).

The interpreter extension is a separable, env-gated (GUNBC_RECOMPUTE_TRACE=1),
READ-mode diagnostic — not a dependency of the spine/materialize analysis
substrate (pure .dag, content_hash-based). Reverting v1_interpreter.rs to main
restores byte-identical interpreter content → the fingerprint witness returns to
assumed-green SKIP → floor budget restored. The recompute-trace extension lands
as its own follow-up PR where the fingerprint-witness re-run is expected.

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

* WIP: Duplicate Computation

* Materialization ladder: the state x decision law, as executable witnesses

The operator's 4-rule business logic generalized on one axis: the decision is
a function of WHEN the redundancy is knowable and WHETHER what was knowable
was prepared for. Errors fire only on knowable-but-unprepared; genuine
emergence and declared triviality are typed acceptances, never silence.

std.materialization_ladder (dag/std):
- Frame/FrameKind: SharedStateFrame | IsolatedChildrenFrame |
  ReplayedFrame{attempts} | UnboundedSiblingsFrame — the nested-scope axis;
  a 'run' at any layer is a frame, never a different kind of thing.
- DemandNature: Pure | IdempotentEffect | WorldRead{envelope_declared} |
  FreshEffect — the D3 effect gate; TTL = unmodeled dependency XOR declared
  staleness, never an eviction knob.
- CacheProvider: keying (ContentKeyed|ExistenceKeyed) + EvictionPolicy
  (ScopeExit|SpacePacked) REQUIRED by construction — rule 3 unwritable-bad.
- LadderVerdict (total): AuthoredDuplication | Discharged | RefusedNoProvider
  | RefusedScopeTooNarrow | RefusedExistenceKeyed (the build-if-absent #6352
  wall) | RefusedUnmodeledWorldRead | ExemptFreshEffect |
  AcceptedBelowCostFloor | AcceptedSingleRecompute.
- Declared-emergent frames obligate UP FRONT: retry frames derive
  checkpointing, unbounded-sibling frames (server loops, CI-runs-over-time)
  derive persistent caches — prepare-before-demand.

12/12 witnesses green by execution; each test is one cell of the table,
fixtures mirror the live worked example (workflow/jobs/steps, retry, fleet).

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

* WIP: Duplicate Computation

* Docs crystallization: derived materialization placement into roadmap ④ + the state x decision table

- roadmap_authority ④ (ROADMAP.md regenerated via main_wet, drift-consistent):
  the nested-frame law, plurality cells, declared-emergent prepare-up-front,
  keying/staleness walls, the caching-completion un-shelve, the ①-vs-§2
  cross-run-caching contradiction subsumed into per-node derived verdicts,
  and the v1.compiler.ownership §3-convergence row.
- duplicate-work design doc: the state x decision table as the qualifier's
  final verdict logic + the ownership consolidation subsection.

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

* Consolidation plan: realization + materialization + ownership are one law

Operator synthesis (2026-07-09): Materialization = the verdict vocabulary;
ownership = the verdict computation at the eval frame; realization = provider
selection discharging the verdict at each frame's carrier. Share's handler is
layer-aware — the cheapest cache is a REFERENCE (same program + ref-capable
carrier + readonly => point-at-it, no copy, no destroyed memory), demoting
through HAMT structural share / process memo / artifact / CAS, and demotion
must be priced, never silent (#6249 clone-fallback is the receipt).

Census of every hand-rolled instance found in-tree (16 rows): each named with
its frame, ladder cell, action, and dissolution trigger — ownership
(consolidated), Rc/HAMT (reference tier), clone-fallback (demotion wall),
ParseTable + cached_stage (C5 grounding), M1 memo / intern / assumed-green /
sccache / cargo-cache (C2 provider rows), PROCESS_RESOLVE_STORE (C3 = the 9GB
scope fix), build-if-absent (landed as the keying wall), resolve-cache #5789
(rule-4 requirements), recompute-trace (state-4 finding source). Peers kept
distinct: affected-set, Independence/Placement, mutable state.

Sequence C1-C5 with C1 = this PR (ladder + live CI gate).

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

* WIP: Duplicate Computation

* Ownership refactored onto materialization: the value tier, tested as providers

First consolidation increment (operator-directed): v1.compiler.ownership's
decision IS provider selection at the value grain, now expressed in the ladder
and proven by mirror witnesses.

- ProviderTier: Reference | Copy | Memo{keying} | Artifact{keying} | Cas{keying}
  — keying folded INTO store tiers, so an existence-keyed reference is
  unwritable BY SHAPE (§5 construction); frame obligations at isolation LCAs
  are dischargeable only by store tiers (a reference cannot cross an isolation
  boundary — witnessed).
- Value tier: AccessMode (Read|Consume|Carry|Project), ValueUsage,
  value_materialization -> ValueDead | ValueMoved | ValueSharedByReference |
  ValueDemotedToCopy (PRICED, requires a declared CopyTier provider — the
  #6249 silent clone-fallback made refusable) | ValueRefusedAffine |
  ValueRefusedNoCarrierProvider.
- Faithful to v1's THREE distinct plurality readings, kept separate:
  take_count = semantic_consumer_count (Consumed only, affine axis);
  value_access_plurality = binding_fan_out (Carry excluded, reference axis);
  borrow_count = whole_value_borrow_count (Read+Carry not Project, movability).
- Fold-accumulator case mirrored at conservative pre-FoldAccUnwrap semantics:
  carries excluded from plurality but blocking the move -> demoted-to-copy.

23/23 witnesses green (14 frame cells + 9 value cells). Corpus-level
equivalence against live v1 ownership folds = the C4 receipt.

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

* WIP: Duplicate Computation

* WIP: Duplicate Computation/Materialization

* G: exhaustive cache/share census (52 mechanisms, 6 groups) + C0 catalog-grounding of provider rows + forward-wiring walls

The sweep found the tree already models caches: extdeps/cache cache_catalog
(CacheInterfaceCatalogFacts, 9 rows) + extdeps/realization carrier facts +
the warm==cold purity oracle. C0 grounds CacheProvider on that catalog
(provider_from_catalog projection; CacheProvider.id -> CacheInterfaceId)
so the ladder and the catalog never restate each other's half. Three
forward walls (demands-from-DependencyView, hand-cache shape lens,
live-provider-or-red) make new caches born as provider rows only.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* WIP: Duplicate Computation/Materialization

* C0: provider rows derive from the cited cache catalog (extdeps/cache/materialization.dag projection)

Operator ruling 2026-07-09: extdeps stays the ground-truth/interface layer;
every USE of a cache goes through materialization so memo never gets
re-invented. provider_from_catalog is the only door from a catalog row into
the ladder: keying/tier/eviction derived from cited facts (mechanism->class:
InProcess=>ScopeExit; Ttl/Lru/SizeBounded=>SpacePacked; Never/Manual outside
a process => typed ProjectionRefused, counted by the new enrolled witness;
HandAuthored/prefix-fallback keys => ExistenceKeyed until key-completeness
upgrades them). CI sccache row now derived, hand-typed tier facts deleted,
6/6 + 23/23 witnesses green. 10b re-scoped: v1-internal caches = inventory
only (retire with seed); ParseTable/cached_stage promoted to next.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* Fail-closed hardening: RefusedNatureConflict arm, weakest-claim nature default, UsesStep silence counted, ladder cells enrolled in CI

The complexity-lens false-clean lesson applied to this gate before anyone
relies on it: (1) heterogeneous natures on one identity were first-wins —
now a typed RefusedNatureConflict (24th ladder cell, RED witness); (2) an
unrostered run-step claimed PureComputation — now IdempotentEffect, the
weakest claim (verdict-identical, no purity overclaim; a misdeclared
WorldRead can no longer be legally memoized by default); (3) UsesStep
foreign actions produced silence — now a pinned denominator (==9; a new
foreign action must consciously bump it); (4) the ladder's 24 cells enroll
on the CI surface so the law's own witnesses gate every run. 24/24 + 7/7.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* WIP: Duplicate Computation/Materialization

* M1 ratchet bump: declared resolve count 1 -> 3 (gate's first live catch — enrollment pays counted resolves)

Run 29058798771: enrolling the ladder witness file moved resolves_total
1 -> 3 (each enrolled entry file pays one closure resolve against the
shared index) and the receipt gate redded that exact run — the designed
semantics, receipted in the note. Bump acknowledges the two witness-entry
resolves as declared debt; M2 (one closure resolve per roots set)
ratchets back toward 1.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Retire the M1/M2 labels from carriers (no-codename rule; collided with DESIGN's floor-memoization M1/M2)

Step renamed to 'Floor resolve receipt gate (declared cold-resolve count)';
notes and the gate echo now say what the things are: the counted
cold-resolve receipt, and the shared-resolve rewire (one closure resolve
per source-roots set). Naming-retirement note left on the carrier.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* WIP: Duplicate Computation/Materialization

* Run-step natures pinned as counted claims, not affordances

Operator ruling 2026-07-10: hardcoded shell scripts get no affordances
— run-steps are supposed to be modeled as typed intents and emitted
(shell-emission-model slice 4 covers ci_workflow RunSteps). Until that
slice lands, every nature in job_run_demands is a claim (rostered
FreshEffect / weakest-default IdempotentEffect), never derived from a
modeled effect row. Count the whole claimed-nature surface (16 by
execution) and pin it in the enrolled witness: a new raw-script step
must consciously bump the pin, and slice-4 migration becomes a
countable ratchet ending at zero, where the pin becomes a wall.
Rejected alternative recorded in the carrier note: a per-step
declared-natures roster (a second parallel ledger over scripts the
shell-emission plan already governs).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Regen DESIGN.md after main merge (duplicate-work row + #6373 body-lowering row coexist)

Conflict was both sides editing the open-threads list in design_document.dag:
ours added the duplicate-work thread, main's #6373 rewrote body-lowering to
Stages 1-3 LANDED. Resolution keeps both rows in the .dag authority; DESIGN.md
regenerated from it, never hand-edited.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* Inferred materialization increment 1: floor demand ledger + receipt-or-red gate

Running IS enrolling: the interpreter ledgers every keyed pure call and every
InterpContext absorbs its totals into a process accumulator on Drop — by
construction, no eval path escapes the receipt. claim_executor writes
target/floor-materialization-receipt.txt at walk end; trace defaults ON in
the executor, and an explicit =0 zeroes keyed_calls which the gate refuses.

Gate arms this push (all verified under dash from the emitted ci.yml):
receipt missing/malformed/keyed_calls=0 fail closed. Exact pins for
unkeyed_calls and duplicated_keys land from the FIRST CI receipt (the
resolve gate's measure-then-pin path) — unkeyed is known nonzero on the
floor (count_matching takes a predicate closure; closures are the one
disclosed identity-less class, dissolve-on captured-env content identity).

Unit witness green: resolve -> eval -> ctx Drop -> absorb -> drain-once.
Step addition bumped the claimed-natures pin 16 -> 17 consciously.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Review fix: drop the racy drain-once assertion from the receipt unit test

opus-4-7 finding on #6441: under plain cargo test (still the documented
runner) tests share a process, the env latch is OnceLock-sticky, and
sibling ctx drops could absorb between the two takes — making the
drain-empty assertion racy. Absorb-on-Drop stays asserted (monotone under
concurrent absorbs: siblings only ADD); drain-once is Option::take by
construction, not asserted through the shared global. Comment states the
sharing semantics explicitly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

---------

Co-authored-by: Brian Searls <briansrls@gunb.ai>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* Turn on affected-set CI: re-land witness enrollment flip (discovery shrunk by affected set) + falsifier host-OOM receipt (#6438)

* WIP: Re-land affected-set CI enrollment flip once shard resolve footprint is

* WIP: Re-land affected-set CI enrollment flip once shard resolve footprint is

* Fix CI OOM: pin discovery corpus spawn_width_cap to 1.

Run 28999086030 OOM-killed at width=2 on the 24GiB live slot during the
discovery-flip corpus batch. Gate workloads still fit at width=2; only the
tree-wide discovery batch serializes via spawn_width_cap=1, with a receipt
witness and dissolve-on note.

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

* Fix type error in corpus discovery spawn width cap helper.

Both if-branches must return Nat (hardware_thread_count_value), not a
bare Int literal.

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

* Merge affected-set enrollment flip (takeover of PR #6403 from session/gentle-stag-677-flip)

Conflict resolutions onto post-#6422/#6431/#6432/#6435 main:
- ci_witness_optin_inversion: main's typed Scaffold Disposition -> Terminal (dissolve fired at the flip; roster stays as explicit-entry home, exclusivity dissolved)
- floor step timeout: 45 (main) vs 60 (flip) -> 60 with provenance note
- ci_spec notes: kept flip notes, stale fixed-8 phrasing dated
- falsifier width note: + RESIDUE paragraph (5x exit-137 on srv2-class slots = converge lane, not plan width)

Verified before commit: discovery batches charge corpus_resolve_nanos (own key), resolve_nanos=0 -> resolves_total declared 3 is NOT moved by the flip.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* WIP: affected set processing

* WIP: affected set processing

* WIP: affected set processing

* WIP: affected set processing

* Correct the false flip receipt + kill-surviving calibration receipts (space-lens loop)

CORRECTED RECEIPT: run 29000557166's floor never completed - the executor was
host-OOM-killed mid-discovery-corpus at ~8min; the log's ExitSuccess belongs to
the merge-admission stamp tool stamping CI_FLOOR_EXIT=137. No flipped corpus
has completed in CI (0/1 ci + 0/5 falsifier). Both carrier notes corrected.

Calibration (coordinated with merry-owl-649's space-lens lane):
- roster_import_closure_nodes_pre_resolve: shared closure-count authority
  (pure import walk, closure grain not entry grain), emitted BEFORE the heavy
  resolve so killed runs still yield the (nodes, peak) lower-bound pair
- width-1 definition-drift oracle: pre-resolve walk must equal post-resolve
  resolved union on completed runs; refuses on divergence. Proven by execution:
  pre == post == 190/213 nodes across Off/Applied modes
- kill-surviving cgroup memory.peak pre/post steps (post is always()) in the
  ci job and falsifier.yml; scope semantics labeled on the emission lines
  (reset=ok floor-scoped; span compares post>pre; never silently conflated)
- job backstop timeouts extended by the two aux steps in both jobs

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* WIP: affected set processing

* Calibration pairs carry censored-vs-exact labels (methodology: killed runs are censored observations)

Floor steps get id=floor; the always() post-peak step emits floor_outcome so
each (closure_nodes, peak) pair is explicitly labeled: success = exact point,
anything else = censored lower bound (true demand strictly greater than read).
Prevents the fit from treating cap-kill reads as point estimates, which would
drag the slope down and make the predictor underestimate - the dangerous
direction (merry-owl methodology catch, 2026-07-10).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* WIP: affected set processing

* Review fixes: explicit witness import + complete step-budget ledger

- ci_floor_plan_witness_test.dag: import witness_ci_corpus_discovery_serializes_at_width_one
  explicitly (cursor catch on #6438). The call resolved pre-fix via the seed resolver's flat
  namespace, so the witness ran green by execution; the explicit import restores the file's
  per-symbol import convention.
- ci_workflow.dag: the resolve-receipt gate step had NO step cap — a hang there could only die
  by job-cancel (the #6323 starvation-kill class). It now carries the aux cap (script is a
  sub-second receipt read) and the ci job backstop counts four aux terms (peak pre/post,
  resolve-receipt gate, merge-admission gate): every step budgeted, backstop = step-sum + prelude
  (claude review catch on #6438, sharpened).
- falsifier_workflow_witness_test.dag: falsifier_backstop_is_step_sum_plus_prelude asserted the
  pre-calibration formula — latent red proven by execution (FAIL receipt), fixed to the live
  two-aux sum, re-run PASS.
- ci.yml regenerated byte-stable from the carrier (backstops 125->130, gate step timeout 5m).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Rebind calibration provenance comments to real artifacts (cursor review catch)

The two cli_run.rs comments cited docs/plans/space-lens-minimal-project.md, which does
not exist on main — the predictor design is in flight on PR #6442 (merry-owl-649's lane)
and was never landed under that path. Rebound: the shared closure-definition authority is
stated as this function itself, with the in-flight design cited by PR number and the
landed parent-lane authorities cited by real paths (compute-envelope-model.md fleet
envelope; input-envelope-roadmap.md admission). No behavior change; cargo check clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* WIP: affected set processing

* Remove stray empty file (shell-redirect artifact the auto-committer flushed)

An internal-messaging command's backtick content was command-substituted by bash; a
'-> fail-closed' fragment became a stdout redirect and created an empty file at the
repo root, which the auto-committer then committed as 38f0a46. No tree content
beyond the empty file; removing it restores the branch to e99c757's content.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* WIP: affected set processing

* Scaffold-mark the cgroup peak calibration shell (cursor review catch)

The three concat-built calibration runners (ci_cgroup_peak_locate_shell,
ci_floor_peak_pre_script, ci_floor_peak_post_script) landed without the on-carrier
scaffold markers repo convention requires for hand-shell. Each now carries a
Disposition = Scaffold { dissolves_to: RealizationDispatch } row binding the decl
(the ci_materialization pattern), and both scripts embed the shared dissolve-on
note as a shell comment (the ci_spec pattern): dissolution = bash-emit (#5828 /
gap-B emit(intent, Bash)) realizing the observation as an emitted ShellProgram
intent or a typed host Observe effect. ci.yml + falsifier.yml regenerated;
falsifier_workflow_witness_holds and the flip witnesses re-run PASS.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Merge origin/main into session/loyal-wren-398 (resolve #6441 step-list conflict)

Conflict resolution, all consciously declared:
- ci_job steps: union — the calibration peak pre/post steps wrap the floor step (this
  branch) and #6441's materialization receipt gate slots between the resolve-receipt
  gate and the merge-admission gate (main).
- The incoming materialization receipt gate step landed with timeout none — the same
  uncapped-step starvation-kill class this branch's review fix eliminated — so it now
  carries the aux cap, and the ci backstop counts FIVE aux terms (peak pre, peak post,
  resolve-receipt gate, materialization receipt gate, merge-admission gate); the budget
  disposition note records the merge provenance.
- ci_run_step_natures_are_claims_counted_not_silent: RunStep count pin bumped 17 -> 19,
  acknowledging the two peak calibration steps #6441's count predates (conscious-count
  discipline; proven red at 17 then green at 19 by execution).
- ci.yml regenerated from the merged carriers (backstops 130 -> 135).

Verified on the merged tree: release bins rebuilt on merged Rust; falsifier workflow
witness, flip witnesses, floor-plan/optin/width witnesses, and all 8 ci_materialization
witnesses PASS; generated-artifact regen ExitSuccess.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Brian Searls <briansrls@gunb.ai>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>

* ShellProgram -> DAG: transport intent collapse + live importer ratchet (phase 0 of the sidecar dissolution) (#6449)

* WIP: ShellProgram -> DAG

* WIP: ShellProgram -> DAG

* WIP: ShellProgram -> DAG

* WIP: ShellProgram -> DAG

* WIP: ShellProgram -> DAG

* bash fold: native Concat/CmdSubst/WithRedir coverage + measured cost wall on the whole-tree emit path

Fold-family productions extended so the fold no longer refuses word
Concat/CmdSubst or stmt WithRedir (all four Redir variants): new
concat_parts/word-compound/with_redir production families, lex tokens,
kind-tag emit transforms, and recursive bundle arms. Byte-identity vs
serialize_bash proven by execution: five depth-2 oracle tests plus the
depth-4 assign_root_stmt manual probe (ROOT=$('git' 'rev-parse'
'--show-toplevel' 2>/dev/null || 'pwd') byte-exact). The delegated
fail-closed RED control repoints from WithRedir (now native) to Heredoc
(still delegated) so the boundary guard stays discriminating.

Measured cost wall, declared on-carrier (bash_program_emit_cost_wall_note):
whole-tree backward row-selection is ~alternatives^depth (1s flat stmt,
64s for the single depth-4 stmt, DNF >8min for the full witness_bin
program) because formal_production_unique_lhs_exact_match deep-validates
every candidate per level and the descent re-validates each level again.
Real-program oracles therefore stay MANUAL probes, not test fns (a
discovery-run test would hang the local floor); the probe note on the
test carrier names the dissolution triggers.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Brian Searls <briansrls@gunb.ai>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>

* WIP: Wave 1A - namespace-only name resolution: make the syntactic containment

* B1: NameResolutionPolicy row + position-tracked resolve (NamespaceOnlyY gated).

Add v2.std.resolution_policy (ImportScoped default | NamespaceOnlyY). Thread
ResolveContext { position, expected, policy } through resolve walk; namespace-only
skips import module bindings and uses symbol_index at position. Policy pilot
witness: green under NamespaceOnlyY at type position, RED under ImportScoped at
module position. Import-scoped global default unchanged — zero corpus churn.

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

* Wave 1A - namespace-only name resolution: make the syntactic containment tree the single naming authority (qualified name = nesting position, reference = lexical lookup up ancestors, . = projection one level down). Path: confirm loyal-heron SymbolIndex scaling receipt FIRST, then SymbolIndex = conta (#6451)

* WIP: Wave 1A - namespace-only name resolution: make the syntactic containment

* v2.std.symbol_index: materialize containment tree as single naming authority

Add SymbolIndex fill from nesting (qualified path → Node), qualified-name
path algebra bridges, and discriminating witnesses. Retarget #6436 variant-
visibility scaffold to dissolve into symbol_index_lexical_lookup; harvest_unique
stays interim until module-scoped index scan lands.

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

* WIP: Wave 1A - namespace-only name resolution: make the syntactic containment

* Fix rust fmt on qualified-name bridge host functions (CI rust_tests gate).

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

* WIP: Wave 1A - namespace-only name resolution: make the syntactic containment

* Remove symbol_index_has_path; tests match symbol_index_lookup directly

Dissolve Optional→Bool predicate in new std/ surface per review. Lexical
lookup root termination already uses qualified_name_is_empty (not dotted
string projection).

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

* WIP: Wave 1A - namespace-only name resolution: make the syntactic containment

* Address review: is_empty authority, host scaffold binds, layer split

- Remove qualified_name_is_empty; lexical lookup uses is_empty(xs: position)
- Host dispositions bind to from/to_dotted_string bridges; add P5 receipt tests
- Move extdeps-coupled fill to v2.compiler.symbol_index_fill (layer DAG fix)

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

* WIP: Wave 1A - namespace-only name resolution: make the syntactic containment

* WIP: Wave 1A - namespace-only name resolution: make the syntactic containment

* Wire resolver through SymbolIndex; dissolve harvest_unique_disj interim.

Build SymbolIndex at admission and thread it through Namespace. resolve_atom
falls back to symbol_index_lexical_lookup for unbound atoms after import-scoped
lookup_chain. Fill-time unique-variant aliases (suffix-scan equivalent) replace
#6436 harvest_unique_disj. Equivalence witnesses prove SymbolIndex-alone covers
variant visibility (green + without-alias RED control); end-to-end wire green.

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

---------

Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>

* WIP: Wave 1A - namespace-only name resolution: make the syntactic containment

* Drop unused ResolveContext.expected until expected-type lane lands.

Removes the dead field and uncalled resolve_ctx_with_expected helper
flagged in #6454 review 36717 — B1 uses position-only disambiguation;
expected-type filtering returns when that slice is scoped.

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

---------

Co-authored-by: gunbai-bot[bot] <289086189+gunbai-bot[bot]@users.noreply.github.com>
Co-authored-by: Brian Searls <briansrls@gunb.ai>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: Brian Searls <11205878+briansrls@users.noreply.github.com>
briansrls added a commit that referenced this pull request Jul 11, 2026
…eipt-write refusal + counter invariant (#6456)

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* Analysis spine: spine_receipt composes dependency_view + materialize (increment 1)

The Rc-safe half of run ≜ realize ∘ materialize ∘ dependency_view: compose
the two catamorphisms that need no interpreter thread-safety.

- src/v2/std/spine.dag: level-profile fold over the DependencyView DAG →
  critical_path_depth (longest dependency chain / the reduce spine) +
  independence_width (max nodes at one level / what parallelizes to hw width).
  spine_receipt emits the §9 numbers by COMPUTATION, not assertion, joining
  materialize's content-hash Share/dedup counts.
- Discriminating RED (§9): single chain A→B→C → depth 3 / width 1 (serial);
  root over N independent leaves → depth 2 / width N.
- Witnesses 9/9 (spine) green by execution; materialize 6/6 unchanged.

The RUNNER (wall-clock parallel execution, §8 steps 3-4) stays increment 2+,
gated on interpreter Rc→Arc (v1 interp is !Send). This increment measures the
achievable width/critical-path floor the runner targets; it does not fabricate
wall-clock N×.

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

* Unbundle recompute-trace interpreter extension from the analysis-spine PR

CI root cause: the recompute-trace extension edited v1_interpreter.rs, which
hosts the atom_identity_hash/hash_combine fnv1a64 intrinsics that
dag_collect_fingerprint_witness executes. That correctly invalidated the
re-verify 'assumed-green node-frontier' SKIP of that witness (cone-touch,
fail-closed) — but the witness is a pre-existing 806s (13min) fnv1a64
whole-corpus walk, so un-skipping it blew the 30-min floor budget. Main stays
green only because its interpreter cone is untouched (witness stays skipped).

The interpreter extension is a separable, env-gated (GUNBC_RECOMPUTE_TRACE=1),
READ-mode diagnostic — not a dependency of the spine/materialize analysis
substrate (pure .dag, content_hash-based). Reverting v1_interpreter.rs to main
restores byte-identical interpreter content → the fingerprint witness returns to
assumed-green SKIP → floor budget restored. The recompute-trace extension lands
as its own follow-up PR where the fingerprint-witness re-run is expected.

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

* WIP: Duplicate Computation

* Materialization ladder: the state x decision law, as executable witnesses

The operator's 4-rule business logic generalized on one axis: the decision is
a function of WHEN the redundancy is knowable and WHETHER what was knowable
was prepared for. Errors fire only on knowable-but-unprepared; genuine
emergence and declared triviality are typed acceptances, never silence.

std.materialization_ladder (dag/std):
- Frame/FrameKind: SharedStateFrame | IsolatedChildrenFrame |
  ReplayedFrame{attempts} | UnboundedSiblingsFrame — the nested-scope axis;
  a 'run' at any layer is a frame, never a different kind of thing.
- DemandNature: Pure | IdempotentEffect | WorldRead{envelope_declared} |
  FreshEffect — the D3 effect gate; TTL = unmodeled dependency XOR declared
  staleness, never an eviction knob.
- CacheProvider: keying (ContentKeyed|ExistenceKeyed) + EvictionPolicy
  (ScopeExit|SpacePacked) REQUIRED by construction — rule 3 unwritable-bad.
- LadderVerdict (total): AuthoredDuplication | Discharged | RefusedNoProvider
  | RefusedScopeTooNarrow | RefusedExistenceKeyed (the build-if-absent #6352
  wall) | RefusedUnmodeledWorldRead | ExemptFreshEffect |
  AcceptedBelowCostFloor | AcceptedSingleRecompute.
- Declared-emergent frames obligate UP FRONT: retry frames derive
  checkpointing, unbounded-sibling frames (server loops, CI-runs-over-time)
  derive persistent caches — prepare-before-demand.

12/12 witnesses green by execution; each test is one cell of the table,
fixtures mirror the live worked example (workflow/jobs/steps, retry, fleet).

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

* WIP: Duplicate Computation

* Docs crystallization: derived materialization placement into roadmap ④ + the state x decision table

- roadmap_authority ④ (ROADMAP.md regenerated via main_wet, drift-consistent):
  the nested-frame law, plurality cells, declared-emergent prepare-up-front,
  keying/staleness walls, the caching-completion un-shelve, the ①-vs-§2
  cross-run-caching contradiction subsumed into per-node derived verdicts,
  and the v1.compiler.ownership §3-convergence row.
- duplicate-work design doc: the state x decision table as the qualifier's
  final verdict logic + the ownership consolidation subsection.

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

* Consolidation plan: realization + materialization + ownership are one law

Operator synthesis (2026-07-09): Materialization = the verdict vocabulary;
ownership = the verdict computation at the eval frame; realization = provider
selection discharging the verdict at each frame's carrier. Share's handler is
layer-aware — the cheapest cache is a REFERENCE (same program + ref-capable
carrier + readonly => point-at-it, no copy, no destroyed memory), demoting
through HAMT structural share / process memo / artifact / CAS, and demotion
must be priced, never silent (#6249 clone-fallback is the receipt).

Census of every hand-rolled instance found in-tree (16 rows): each named with
its frame, ladder cell, action, and dissolution trigger — ownership
(consolidated), Rc/HAMT (reference tier), clone-fallback (demotion wall),
ParseTable + cached_stage (C5 grounding), M1 memo / intern / assumed-green /
sccache / cargo-cache (C2 provider rows), PROCESS_RESOLVE_STORE (C3 = the 9GB
scope fix), build-if-absent (landed as the keying wall), resolve-cache #5789
(rule-4 requirements), recompute-trace (state-4 finding source). Peers kept
distinct: affected-set, Independence/Placement, mutable state.

Sequence C1-C5 with C1 = this PR (ladder + live CI gate).

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

* WIP: Duplicate Computation

* Ownership refactored onto materialization: the value tier, tested as providers

First consolidation increment (operator-directed): v1.compiler.ownership's
decision IS provider selection at the value grain, now expressed in the ladder
and proven by mirror witnesses.

- ProviderTier: Reference | Copy | Memo{keying} | Artifact{keying} | Cas{keying}
  — keying folded INTO store tiers, so an existence-keyed reference is
  unwritable BY SHAPE (§5 construction); frame obligations at isolation LCAs
  are dischargeable only by store tiers (a reference cannot cross an isolation
  boundary — witnessed).
- Value tier: AccessMode (Read|Consume|Carry|Project), ValueUsage,
  value_materialization -> ValueDead | ValueMoved | ValueSharedByReference |
  ValueDemotedToCopy (PRICED, requires a declared CopyTier provider — the
  #6249 silent clone-fallback made refusable) | ValueRefusedAffine |
  ValueRefusedNoCarrierProvider.
- Faithful to v1's THREE distinct plurality readings, kept separate:
  take_count = semantic_consumer_count (Consumed only, affine axis);
  value_access_plurality = binding_fan_out (Carry excluded, reference axis);
  borrow_count = whole_value_borrow_count (Read+Carry not Project, movability).
- Fold-accumulator case mirrored at conservative pre-FoldAccUnwrap semantics:
  carries excluded from plurality but blocking the move -> demoted-to-copy.

23/23 witnesses green (14 frame cells + 9 value cells). Corpus-level
equivalence against live v1 ownership folds = the C4 receipt.

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

* WIP: Duplicate Computation

* WIP: Duplicate Computation/Materialization

* G: exhaustive cache/share census (52 mechanisms, 6 groups) + C0 catalog-grounding of provider rows + forward-wiring walls

The sweep found the tree already models caches: extdeps/cache cache_catalog
(CacheInterfaceCatalogFacts, 9 rows) + extdeps/realization carrier facts +
the warm==cold purity oracle. C0 grounds CacheProvider on that catalog
(provider_from_catalog projection; CacheProvider.id -> CacheInterfaceId)
so the ladder and the catalog never restate each other's half. Three
forward walls (demands-from-DependencyView, hand-cache shape lens,
live-provider-or-red) make new caches born as provider rows only.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* WIP: Duplicate Computation/Materialization

* C0: provider rows derive from the cited cache catalog (extdeps/cache/materialization.dag projection)

Operator ruling 2026-07-09: extdeps stays the ground-truth/interface layer;
every USE of a cache goes through materialization so memo never gets
re-invented. provider_from_catalog is the only door from a catalog row into
the ladder: keying/tier/eviction derived from cited facts (mechanism->class:
InProcess=>ScopeExit; Ttl/Lru/SizeBounded=>SpacePacked; Never/Manual outside
a process => typed ProjectionRefused, counted by the new enrolled witness;
HandAuthored/prefix-fallback keys => ExistenceKeyed until key-completeness
upgrades them). CI sccache row now derived, hand-typed tier facts deleted,
6/6 + 23/23 witnesses green. 10b re-scoped: v1-internal caches = inventory
only (retire with seed); ParseTable/cached_stage promoted to next.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* Fail-closed hardening: RefusedNatureConflict arm, weakest-claim nature default, UsesStep silence counted, ladder cells enrolled in CI

The complexity-lens false-clean lesson applied to this gate before anyone
relies on it: (1) heterogeneous natures on one identity were first-wins —
now a typed RefusedNatureConflict (24th ladder cell, RED witness); (2) an
unrostered run-step claimed PureComputation — now IdempotentEffect, the
weakest claim (verdict-identical, no purity overclaim; a misdeclared
WorldRead can no longer be legally memoized by default); (3) UsesStep
foreign actions produced silence — now a pinned denominator (==9; a new
foreign action must consciously bump it); (4) the ladder's 24 cells enroll
on the CI surface so the law's own witnesses gate every run. 24/24 + 7/7.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* WIP: Duplicate Computation/Materialization

* M1 ratchet bump: declared resolve count 1 -> 3 (gate's first live catch — enrollment pays counted resolves)

Run 29058798771: enrolling the ladder witness file moved resolves_total
1 -> 3 (each enrolled entry file pays one closure resolve against the
shared index) and the receipt gate redded that exact run — the designed
semantics, receipted in the note. Bump acknowledges the two witness-entry
resolves as declared debt; M2 (one closure resolve per roots set)
ratchets back toward 1.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Retire the M1/M2 labels from carriers (no-codename rule; collided with DESIGN's floor-memoization M1/M2)

Step renamed to 'Floor resolve receipt gate (declared cold-resolve count)';
notes and the gate echo now say what the things are: the counted
cold-resolve receipt, and the shared-resolve rewire (one closure resolve
per source-roots set). Naming-retirement note left on the carrier.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* WIP: Duplicate Computation/Materialization

* Run-step natures pinned as counted claims, not affordances

Operator ruling 2026-07-10: hardcoded shell scripts get no affordances
— run-steps are supposed to be modeled as typed intents and emitted
(shell-emission-model slice 4 covers ci_workflow RunSteps). Until that
slice lands, every nature in job_run_demands is a claim (rostered
FreshEffect / weakest-default IdempotentEffect), never derived from a
modeled effect row. Count the whole claimed-nature surface (16 by
execution) and pin it in the enrolled witness: a new raw-script step
must consciously bump the pin, and slice-4 migration becomes a
countable ratchet ending at zero, where the pin becomes a wall.
Rejected alternative recorded in the carrier note: a per-step
declared-natures roster (a second parallel ledger over scripts the
shell-emission plan already governs).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Regen DESIGN.md after main merge (duplicate-work row + #6373 body-lowering row coexist)

Conflict was both sides editing the open-threads list in design_document.dag:
ours added the duplicate-work thread, main's #6373 rewrote body-lowering to
Stages 1-3 LANDED. Resolution keeps both rows in the .dag authority; DESIGN.md
regenerated from it, never hand-edited.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* Inferred materialization increment 1: floor demand ledger + receipt-or-red gate

Running IS enrolling: the interpreter ledgers every keyed pure call and every
InterpContext absorbs its totals into a process accumulator on Drop — by
construction, no eval path escapes the receipt. claim_executor writes
target/floor-materialization-receipt.txt at walk end; trace defaults ON in
the executor, and an explicit =0 zeroes keyed_calls which the gate refuses.

Gate arms this push (all verified under dash from the emitted ci.yml):
receipt missing/malformed/keyed_calls=0 fail closed. Exact pins for
unkeyed_calls and duplicated_keys land from the FIRST CI receipt (the
resolve gate's measure-then-pin path) — unkeyed is known nonzero on the
floor (count_matching takes a predicate closure; closures are the one
disclosed identity-less class, dissolve-on captured-env content identity).

Unit witness green: resolve -> eval -> ctx Drop -> absorb -> drain-once.
Step addition bumped the claimed-natures pin 16 -> 17 consciously.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Review fix: drop the racy drain-once assertion from the receipt unit test

opus-4-7 finding on #6441: under plain cargo test (still the documented
runner) tests share a process, the env latch is OnceLock-sticky, and
sibling ctx drops could absorb between the two takes — making the
drain-empty assertion racy. Absorb-on-Drop stays asserted (monotone under
concurrent absorbs: siblings only ADD); drain-once is Option::take by
construction, not asserted through the shared global. Comment states the
sharing semantics explicitly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

---------

Co-authored-by: Brian Searls <briansrls@gunb.ai>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
briansrls added a commit that referenced this pull request Jul 11, 2026
…ncident, argued serially with receipts) (#6469)

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* WIP: Duplicate Computation

* Analysis spine: spine_receipt composes dependency_view + materialize (increment 1)

The Rc-safe half of run ≜ realize ∘ materialize ∘ dependency_view: compose
the two catamorphisms that need no interpreter thread-safety.

- src/v2/std/spine.dag: level-profile fold over the DependencyView DAG →
  critical_path_depth (longest dependency chain / the reduce spine) +
  independence_width (max nodes at one level / what parallelizes to hw width).
  spine_receipt emits the §9 numbers by COMPUTATION, not assertion, joining
  materialize's content-hash Share/dedup counts.
- Discriminating RED (§9): single chain A→B→C → depth 3 / width 1 (serial);
  root over N independent leaves → depth 2 / width N.
- Witnesses 9/9 (spine) green by execution; materialize 6/6 unchanged.

The RUNNER (wall-clock parallel execution, §8 steps 3-4) stays increment 2+,
gated on interpreter Rc→Arc (v1 interp is !Send). This increment measures the
achievable width/critical-path floor the runner targets; it does not fabricate
wall-clock N×.

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

* Unbundle recompute-trace interpreter extension from the analysis-spine PR

CI root cause: the recompute-trace extension edited v1_interpreter.rs, which
hosts the atom_identity_hash/hash_combine fnv1a64 intrinsics that
dag_collect_fingerprint_witness executes. That correctly invalidated the
re-verify 'assumed-green node-frontier' SKIP of that witness (cone-touch,
fail-closed) — but the witness is a pre-existing 806s (13min) fnv1a64
whole-corpus walk, so un-skipping it blew the 30-min floor budget. Main stays
green only because its interpreter cone is untouched (witness stays skipped).

The interpreter extension is a separable, env-gated (GUNBC_RECOMPUTE_TRACE=1),
READ-mode diagnostic — not a dependency of the spine/materialize analysis
substrate (pure .dag, content_hash-based). Reverting v1_interpreter.rs to main
restores byte-identical interpreter content → the fingerprint witness returns to
assumed-green SKIP → floor budget restored. The recompute-trace extension lands
as its own follow-up PR where the fingerprint-witness re-run is expected.

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

* WIP: Duplicate Computation

* Materialization ladder: the state x decision law, as executable witnesses

The operator's 4-rule business logic generalized on one axis: the decision is
a function of WHEN the redundancy is knowable and WHETHER what was knowable
was prepared for. Errors fire only on knowable-but-unprepared; genuine
emergence and declared triviality are typed acceptances, never silence.

std.materialization_ladder (dag/std):
- Frame/FrameKind: SharedStateFrame | IsolatedChildrenFrame |
  ReplayedFrame{attempts} | UnboundedSiblingsFrame — the nested-scope axis;
  a 'run' at any layer is a frame, never a different kind of thing.
- DemandNature: Pure | IdempotentEffect | WorldRead{envelope_declared} |
  FreshEffect — the D3 effect gate; TTL = unmodeled dependency XOR declared
  staleness, never an eviction knob.
- CacheProvider: keying (ContentKeyed|ExistenceKeyed) + EvictionPolicy
  (ScopeExit|SpacePacked) REQUIRED by construction — rule 3 unwritable-bad.
- LadderVerdict (total): AuthoredDuplication | Discharged | RefusedNoProvider
  | RefusedScopeTooNarrow | RefusedExistenceKeyed (the build-if-absent #6352
  wall) | RefusedUnmodeledWorldRead | ExemptFreshEffect |
  AcceptedBelowCostFloor | AcceptedSingleRecompute.
- Declared-emergent frames obligate UP FRONT: retry frames derive
  checkpointing, unbounded-sibling frames (server loops, CI-runs-over-time)
  derive persistent caches — prepare-before-demand.

12/12 witnesses green by execution; each test is one cell of the table,
fixtures mirror the live worked example (workflow/jobs/steps, retry, fleet).

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

* WIP: Duplicate Computation

* Docs crystallization: derived materialization placement into roadmap ④ + the state x decision table

- roadmap_authority ④ (ROADMAP.md regenerated via main_wet, drift-consistent):
  the nested-frame law, plurality cells, declared-emergent prepare-up-front,
  keying/staleness walls, the caching-completion un-shelve, the ①-vs-§2
  cross-run-caching contradiction subsumed into per-node derived verdicts,
  and the v1.compiler.ownership §3-convergence row.
- duplicate-work design doc: the state x decision table as the qualifier's
  final verdict logic + the ownership consolidation subsection.

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

* Consolidation plan: realization + materialization + ownership are one law

Operator synthesis (2026-07-09): Materialization = the verdict vocabulary;
ownership = the verdict computation at the eval frame; realization = provider
selection discharging the verdict at each frame's carrier. Share's handler is
layer-aware — the cheapest cache is a REFERENCE (same program + ref-capable
carrier + readonly => point-at-it, no copy, no destroyed memory), demoting
through HAMT structural share / process memo / artifact / CAS, and demotion
must be priced, never silent (#6249 clone-fallback is the receipt).

Census of every hand-rolled instance found in-tree (16 rows): each named with
its frame, ladder cell, action, and dissolution trigger — ownership
(consolidated), Rc/HAMT (reference tier), clone-fallback (demotion wall),
ParseTable + cached_stage (C5 grounding), M1 memo / intern / assumed-green /
sccache / cargo-cache (C2 provider rows), PROCESS_RESOLVE_STORE (C3 = the 9GB
scope fix), build-if-absent (landed as the keying wall), resolve-cache #5789
(rule-4 requirements), recompute-trace (state-4 finding source). Peers kept
distinct: affected-set, Independence/Placement, mutable state.

Sequence C1-C5 with C1 = this PR (ladder + live CI gate).

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

* WIP: Duplicate Computation

* Ownership refactored onto materialization: the value tier, tested as providers

First consolidation increment (operator-directed): v1.compiler.ownership's
decision IS provider selection at the value grain, now expressed in the ladder
and proven by mirror witnesses.

- ProviderTier: Reference | Copy | Memo{keying} | Artifact{keying} | Cas{keying}
  — keying folded INTO store tiers, so an existence-keyed reference is
  unwritable BY SHAPE (§5 construction); frame obligations at isolation LCAs
  are dischargeable only by store tiers (a reference cannot cross an isolation
  boundary — witnessed).
- Value tier: AccessMode (Read|Consume|Carry|Project), ValueUsage,
  value_materialization -> ValueDead | ValueMoved | ValueSharedByReference |
  ValueDemotedToCopy (PRICED, requires a declared CopyTier provider — the
  #6249 silent clone-fallback made refusable) | ValueRefusedAffine |
  ValueRefusedNoCarrierProvider.
- Faithful to v1's THREE distinct plurality readings, kept separate:
  take_count = semantic_consumer_count (Consumed only, affine axis);
  value_access_plurality = binding_fan_out (Carry excluded, reference axis);
  borrow_count = whole_value_borrow_count (Read+Carry not Project, movability).
- Fold-accumulator case mirrored at conservative pre-FoldAccUnwrap semantics:
  carries excluded from plurality but blocking the move -> demoted-to-copy.

23/23 witnesses green (14 frame cells + 9 value cells). Corpus-level
equivalence against live v1 ownership folds = the C4 receipt.

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

* WIP: Duplicate Computation

* WIP: Duplicate Computation/Materialization

* G: exhaustive cache/share census (52 mechanisms, 6 groups) + C0 catalog-grounding of provider rows + forward-wiring walls

The sweep found the tree already models caches: extdeps/cache cache_catalog
(CacheInterfaceCatalogFacts, 9 rows) + extdeps/realization carrier facts +
the warm==cold purity oracle. C0 grounds CacheProvider on that catalog
(provider_from_catalog projection; CacheProvider.id -> CacheInterfaceId)
so the ladder and the catalog never restate each other's half. Three
forward walls (demands-from-DependencyView, hand-cache shape lens,
live-provider-or-red) make new caches born as provider rows only.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* WIP: Duplicate Computation/Materialization

* C0: provider rows derive from the cited cache catalog (extdeps/cache/materialization.dag projection)

Operator ruling 2026-07-09: extdeps stays the ground-truth/interface layer;
every USE of a cache goes through materialization so memo never gets
re-invented. provider_from_catalog is the only door from a catalog row into
the ladder: keying/tier/eviction derived from cited facts (mechanism->class:
InProcess=>ScopeExit; Ttl/Lru/SizeBounded=>SpacePacked; Never/Manual outside
a process => typed ProjectionRefused, counted by the new enrolled witness;
HandAuthored/prefix-fallback keys => ExistenceKeyed until key-completeness
upgrades them). CI sccache row now derived, hand-typed tier facts deleted,
6/6 + 23/23 witnesses green. 10b re-scoped: v1-internal caches = inventory
only (retire with seed); ParseTable/cached_stage promoted to next.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* Fail-closed hardening: RefusedNatureConflict arm, weakest-claim nature default, UsesStep silence counted, ladder cells enrolled in CI

The complexity-lens false-clean lesson applied to this gate before anyone
relies on it: (1) heterogeneous natures on one identity were first-wins —
now a typed RefusedNatureConflict (24th ladder cell, RED witness); (2) an
unrostered run-step claimed PureComputation — now IdempotentEffect, the
weakest claim (verdict-identical, no purity overclaim; a misdeclared
WorldRead can no longer be legally memoized by default); (3) UsesStep
foreign actions produced silence — now a pinned denominator (==9; a new
foreign action must consciously bump it); (4) the ladder's 24 cells enroll
on the CI surface so the law's own witnesses gate every run. 24/24 + 7/7.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* WIP: Duplicate Computation/Materialization

* M1 ratchet bump: declared resolve count 1 -> 3 (gate's first live catch — enrollment pays counted resolves)

Run 29058798771: enrolling the ladder witness file moved resolves_total
1 -> 3 (each enrolled entry file pays one closure resolve against the
shared index) and the receipt gate redded that exact run — the designed
semantics, receipted in the note. Bump acknowledges the two witness-entry
resolves as declared debt; M2 (one closure resolve per roots set)
ratchets back toward 1.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Retire the M1/M2 labels from carriers (no-codename rule; collided with DESIGN's floor-memoization M1/M2)

Step renamed to 'Floor resolve receipt gate (declared cold-resolve count)';
notes and the gate echo now say what the things are: the counted
cold-resolve receipt, and the shared-resolve rewire (one closure resolve
per source-roots set). Naming-retirement note left on the carrier.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* WIP: Duplicate Computation/Materialization

* Run-step natures pinned as counted claims, not affordances

Operator ruling 2026-07-10: hardcoded shell scripts get no affordances
— run-steps are supposed to be modeled as typed intents and emitted
(shell-emission-model slice 4 covers ci_workflow RunSteps). Until that
slice lands, every nature in job_run_demands is a claim (rostered
FreshEffect / weakest-default IdempotentEffect), never derived from a
modeled effect row. Count the whole claimed-nature surface (16 by
execution) and pin it in the enrolled witness: a new raw-script step
must consciously bump the pin, and slice-4 migration becomes a
countable ratchet ending at zero, where the pin becomes a wall.
Rejected alternative recorded in the carrier note: a per-step
declared-natures roster (a second parallel ledger over scripts the
shell-emission plan already governs).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Regen DESIGN.md after main merge (duplicate-work row + #6373 body-lowering row coexist)

Conflict was both sides editing the open-threads list in design_document.dag:
ours added the duplicate-work thread, main's #6373 rewrote body-lowering to
Stages 1-3 LANDED. Resolution keeps both rows in the .dag authority; DESIGN.md
regenerated from it, never hand-edited.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* Inferred materialization increment 1: floor demand ledger + receipt-or-red gate

Running IS enrolling: the interpreter ledgers every keyed pure call and every
InterpContext absorbs its totals into a process accumulator on Drop — by
construction, no eval path escapes the receipt. claim_executor writes
target/floor-materialization-receipt.txt at walk end; trace defaults ON in
the executor, and an explicit =0 zeroes keyed_calls which the gate refuses.

Gate arms this push (all verified under dash from the emitted ci.yml):
receipt missing/malformed/keyed_calls=0 fail closed. Exact pins for
unkeyed_calls and duplicated_keys land from the FIRST CI receipt (the
resolve gate's measure-then-pin path) — unkeyed is known nonzero on the
floor (count_matching takes a predicate closure; closures are the one
disclosed identity-less class, dissolve-on captured-env content identity).

Unit witness green: resolve -> eval -> ctx Drop -> absorb -> drain-once.
Step addition bumped the claimed-natures pin 16 -> 17 consciously.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* Review fix: drop the racy drain-once assertion from the receipt unit test

opus-4-7 finding on #6441: under plain cargo test (still the documented
runner) tests share a process, the env latch is OnceLock-sticky, and
sibling ctx drops could absorb between the two takes — making the
drain-empty assertion racy. Absorb-on-Drop stays asserted (monotone under
concurrent absorbs: siblings only ADD); drain-once is Option::take by
construction, not asserted through the shared global. Comment states the
sharing semantics explicitly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

* WIP: Duplicate Computation/Materialization

---------

Co-authored-by: Brian Searls <briansrls@gunb.ai>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-authored-by: Brian Searls <11205878+briansrls@users.noreply.github.com>
briansrls added a commit that referenced this pull request Jul 18, 2026
…ane PR; P0 merged via #6663) (#6738)

* P2 pure-spec half: content-addressed artifact store — the first read eviction field

std.artifact_store (witness-realization plan P2, pure fold spec; host transport
is the second half and this spec is its single authority):
- ArtifactKey { closure_digest, emitter_identity, target_language, toolchain }
  -> artifact_key_hash via std.content_hash (one hash authority) — keying is
  ContentHash BY SHAPE; no mtime/existence input exists, so ExistenceKeyed is
  unwritable here (the #6352 wall by construction)
- store_over_provider READS CacheProvider.eviction and refuses construction
  over a non-SpacePacked provider (typed StoreRefusedEviction) — the eviction
  field's first behavioral consumer (memory-control audit F5)
- store_get bumps recency; store_put packs to budget by least-recent eviction
  with every eviction COUNTED in StorePutReceipt (refuse-or-count, never widen)
- budget stays a typed parameter beside the row for now: EvictionClass.budget
  carries cited upstream policy PROSE in extdeps rows (two concepts in one
  field); dissolve-on recorded in the module note for the variant split

Witnesses (all green by execution, current binary, SubstrateInputsOnly):
- store_construction_reads_eviction_holds (ScopeExit provider -> typed refusal)
- store_hit_and_stale_never_served_holds (toolchain mutation -> new key -> miss)
- store_budget_evicts_least_recent_counted_holds (touch ka, put kc -> [kb] evicted,
  within budget, survivor still hits)
- store_no_eviction_under_budget_holds

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

* P2 host-transport half: filesystem realization of the artifact store

extdeps.realization.artifact_store_fs — one transport handler bound to the
pure spec (std.artifact_store stays the single authority; a remote CAS is
the other handler). The keyed path ENCODES identity (store_root/<hash>.artifact),
so presence-at-path is a ContentKeyed hit for exactly that identity — not the
#6352 existence-keying (which keyed output presence over unhashed inputs).

SCOPE, honest and named: put/get only. The cited Filesystem service exposes
Write/Read but no Delete/List, so SpacePacked budget enforcement on the
persistent tier is unrealizable until those operations are added — until then
the disk tier grows unbounded and the in-process fold is the only packed tier.
Recorded in the transport note as the next rung, never a silent widen.

Witnesses green by wet execution (artifact observed on disk at its hash path):
- artifact_fs_roundtrip_holds
- artifact_fs_mutated_input_misses_holds (stale-never-served on the persistent tier)

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

* Plan doc: P2 status (both halves landed, green by execution; two named gaps)

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

* P1 (code): ObservePeakResidentAtSubject + the space algebra — memory becomes observable

- RealizationMeasureEffect gains ObservePeakResidentAtSubject (audit F2: the
  effect coproduct had exactly one variant, time; a Measured space fact was
  unproducible by construction)
- space algebra as time's DUAL (audit F4): space_measure_seq = max (sequential
  steps release), space_measure_par = add (concurrent steps co-reside), plus
  space_measure_list_seq; duality note records why the old sum was wrong
- fleet_intent receipt rollup: space summed over a sequential list -> now the
  peak (the parallel rule was applied to the serial axis); keystone witness
  FLIPPED to assert max AND assert != sum, so the old contract cannot silently
  return
- host physics: observed_peak_resident_bytes builtin (VmHWM in bytes) —
  registered in v1.compiler.method builtins, realized in the hand-maintained
  interpreter, FAIL-CLOSED when the host cannot report it (a fabricated 0
  would be a Measured lie, DESIGN section 5)
- peak_resident_measured_witness_test: the plan's P1 ACCEPT — the first
  CostAccount.space with basis Measured produced BY EXECUTION — declared
  ReadsLiveTree honestly (reads /proc through a builtin, the classifier's
  declared blind-spot class); plus the seq=max/par=add RED control

Receipts land in the follow-up commit with the regen-synced stage0 and the
rebuilt binary (pipeline in flight); the pure-.dag half already compiles clean
through the P0 wall.

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

* P1 (receipts): regen sync + green-by-execution verification

Regen-synced stage0 (the observed_peak_resident_bytes registration reaching the
generated method registry) after rebuilding the regen tool from merged main
(its compiled-in roster predated the Wave-2 crate-layout file; two-generation
discipline: build committed -> regen -> build).

Receipts on the rebuilt binary:
- peak_resident_measured_holds -> true : the FIRST CostAccount.space with
  basis Measured produced by execution (plan P1 ACCEPT; audit F2 discharged
  at the witness grain)
- space_seq_is_peak_not_sum_holds -> true (seq=max=5, par=add=8, list_seq=5)
- witness_space_rolls_up_across_receipts -> true FLIPPED (asserts max AND
  != sum; 1024/2048 samples discriminate)
- P0 regression: diagnostics_witness record_field_walls suite exit 0

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

* P3 MVP: emit-on-demand at the source grain — second run pays zero emit

The emit cache wired through the P2 store, keyed on INPUT identity:
inferred_tree_digest x emitter identity x target x artifact kind — the same
Hash=ContentHash authority the fnv1a64 convergence landed, composed by
artifact_key_hash. Cold: miss -> pure emit (v2 emit = serialize_target o
translate) -> put. Warm: served from the store WITH NO EMIT CALL IN THE ARM,
and the served bytes asserted equal to a fresh emit (the agreement receipt —
plan P3 ACCEPT (a) at the source grain).

Witnesses green by wet execution (emitted rust_add source observed on disk at
its hash path):
- emit_source_store_cold_then_warm_holds
- emit_source_store_mutated_emitter_misses_holds (emitter version bump -> new
  key -> miss; stale emitter output never served)
- emit_source_store_provider_gate_holds

Rung remainder (named): the native-artifact tier (zero BUILD — needs FLAG A,
the hermetic pinned-toolchain ruling, and the parse-census first customer) and
enrollment of the wet witnesses.

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

* Design: effect grants over namespaces — hermetic/wet dissolved into (frame x verb x subtree)

Operator rulings captured (2026-07-16): "hermetic" conflates four axes (input
closure / output reach / handler binding / selection eligibility — the doc's own
state-space-conflation failure mode, effect-system edition), and the fix must
reuse NAMESPACES directly rather than mint a "universe" vocabulary. An effect
target is a position in a containment tree that already exists (filesystem, URI,
proc, code names); permission is a grant of (verb x subtree) on a frame;
admissibility is the same prefix relation the naming lane walks — effects become
the containment structure's fourth consumer, not a fork.

Convergence map covers the proto-envelopes already in-tree (the hand-rolled
workspace_root path gate, std.resources.ResourceHandle, AuthScope,
LiveTreeDisposition) — all dissolve into derived projections. FLAG A reframed:
build admissibility becomes the first grant row (Read within closure + pinned
toolchain; Write within own workspace), scaffold-marked, dissolving into the
P-B enforcement seam — a row, not a mode exception.

Bound into the doc graph via the witness-realization plan's FLAG A section
(orphan wall re-verified green).

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

* Effect-grants design: the containment law (target lifecycle) + fix inherited orphan

Design refinement (operator, 2026-07-16): a write is frame-contained iff
(target within a frame-controlled namespace) AND (target lifecycle within
frame lifecycle) — the lifecycle conjunct is what the old "hermetic" intuition
was actually about, graded on the section-5 construction/validation axis
(LifecycleByConstruction: ephemeral container fs, netns-scoped loopback
receiver — persistence unwritable past the frame; LifecycleByConvention:
/tmp scratch + cleanup). Four named acceptance cases added up front so the
model cannot mislead: netns loopback = contained; container write = contained
by construction; /tmp scratch = contained by convention only (the artifact
store witnesses' honest current grade); BMC POST / repo-tree write = wet
under any grade.

Also: bind docs/plans/emitted-crate-partition-design.md into the doc graph
(frontier.dag provenance row) — it merged orphaned on main (8322580) and
the doc-reachability wall was red on main; wall re-verified true here, and
frontier.dag entry-compiles clean.

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

* Record duplicate-computation direction: one ComputationIdentity, N grains (execution-frame is the gap)

Operator direction (2026-07-16): duplicate-computation detection is not
shell-specific — "same inputs + deterministic process → same content-identity
→ the second is duplicate work" is the whole law; the surface it's read on is a
realization axis, not the concept. Records the three detection grains against
ONE ComputationIdentity:
- within-script (argv/ShellWord) — v2.lens.duplicate_computation, dissolves in (§7)
- within-graph (content_hash over Node subtrees) — v2.std.materialize MVP
- within-run execution-frame — the UNCOVERED grain, where the ~275s double-resolve
  lives (two compile_to_resolved calls in one v1-seed claim_executor process,
  invisible to both peers). Ladder-classed: shared-state frame ⇒ AuthoredDuplication
  ⇒ REWIRE (not cache), distinct from the cross-run isolation-boundary store
  obligation — same identity, remedy by frame.

Direction: the general detector must reach the execution-frame grain; the argv
lens then dissolves into it and the within-graph MVP extends down — one detector,
the surfaces its realizations. Doc is the roadmap ④'s linked carrier; orphan
wall re-verified green.

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

* Fix §5 fail-open: eval-call memo served stale world-reads (effect-dispatch odometer)

Found via the artifact-store List-after-Delete witness: the interpreter's
eval-call memo treated "no declared `uses` clause" as pure — and ZERO corpus
funcs declare `uses`, so every effectful named func was memo-eligible. A func
called twice with equal args in one eval served the FIRST result — e.g. a
Filesystem.List after a Delete returned the pre-delete listing. That is a
world-read served stale from cache: a silent §5 fail-open in the bootstrap
engine, not a witness quirk.

Fix (4 edits, transitive by construction): an effect-dispatch odometer on
InterpContext, ticked at the single eval_service_call chokepoint; the memo
refuses to STORE any call during which the odometer advanced. An observed
effect poisons cacheability — exactly the ladder's "FreshEffect/WorldRead is
never memoized" law, enforced at the realizer instead of by a vacuous uses-gate.
Value::eq stays the sole equality authority; pure calls still memoize.

Known residue (named): world-effecting BUILTINS (e.g. observed_peak_resident_bytes,
filesystem via the service path already ticks) — the odometer covers service
dispatch; a builtin-effect tick is the follow-up if a pure-memoized builtin ever
reads the world.

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

* Delete/List on the Filesystem service (operator Q2) — closes P2's persistent-tier gap

The cited Filesystem service exposed only Write/Read, so P2's SpacePacked budget
enforcement on the on-disk store was unrealizable (named gap in the P2 landing).
Adds the two missing operations, keeping the extdeps interface faithful to the
real dependency:

- filesystem_io.dag: Delete + List operations (List readonly)
- file transport gains a verb property (parse: 00_core file_transport_node +
  02_parse parse_file_fields thread `verb`; interpreter: dispatch_file honors
  verb "delete"/"list" via remove_file / sorted read_dir). Absent verb keeps the
  original content-param convention (write iff `content` param, else read).
- artifact_store_fs: artifact_fs_delete / artifact_fs_list wrappers
- witness: artifact_fs_delete_then_misses_holds — put -> listed -> delete ->
  miss -> unlisted, green by wet execution (also the discriminating input that
  surfaced the memo fail-open fixed in the parent commit)

Regen-synced (v1_compiler_parse.rs, v1_std_core.rs). Persistent-tier eviction
(the SpacePacked enforcer using List+Delete) is the follow-up now that the ops
exist.

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

* P4 v0: realize packing — width against MEASURED peaks, refuse-not-fabricate

The memory-safe packing half of `realize` (spine FLAG D), consuming P1's
measured space so the exit-137 failure mode (memory-blind packing OOMs) becomes
arithmetic. std.realize_pack:
- MeasuredPeak = PeakMeasured | PeakUnknown, derived from CostAccount.basis
  (P1's Measured space vs a Predicted guess)
- HostBudget = BudgetReadable | BudgetUnreadable — the typed read
- realize_pack_width -> RealizeVerdict = PackedWidth | MaturationReserve | BudgetRefused:
  * measured peak + readable budget -> PackedWidth min(independence, budget/peak),
    reusing realization_width.memory_bounded_shard_count (20% headroom reserved —
    the maturation-reserve margin; 100/25 packs to 3, not 4)
  * unknown peak -> MaturationReserve width-1 (first-run subject runs alone, its
    receipt converts it next round — the governor's admission logic, modeled)
  * unreadable budget -> BudgetRefused, NEVER the conservative_fallback_width
    fabrication (realization_width.dag:109 — the live §5 absorbing-fallback the
    memory-control audit flagged: budget unreadable answered with a number)

Witnesses (6, green by execution): packs within budget; capped by independence;
never exceeds budget (the exit-137 arithmetic control, W*peak <= budget by
construction); unknown-peak -> maturation reserve; unreadable-budget -> refuses;
measured-vs-predicted peak discrimination.

Remaining for P4: the width-1 fabrication in memory_aware_spawn_width is now
superseded for the measured path; wiring realize_pack into the executor's
per-runnable scheduling (consuming real getrusage receipts) is the integration
step. The math + refusal discipline land here first, green.

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

* Design: space complexity — the dual of the time/termination analysis

Operator direction (2026-07-16): extend the complexity analysis to space (the
gap). Derived, not measured (§4: bounded/forward ⇒ checked not discovered —
measuring peak RSS is the reflection-evidence cop-out). Two readings: asymptotic
(O(n)) AND concrete derived bytes ("known/defined to these bounds"). Underivable
= counted frontier now, hard error later (fail-closed ratchet).

The key finding that makes it a dual, not a new analysis: ComplexitySummary
already carries work/span/output_size as CostExpr (axis-agnostic), and CostSum
is a fold — time SUMS over iterations, space takes the MAX (sequential residency
releases). That is exactly P1's space_measure_seq=max lifted to CostExpr. So
peak_space = space_of(work) — one transform swapping sum/max, accumulator term
reusing output_size, recursion depth bounded by the SAME DescentEvidence that
proves termination. Two readings of one descent structure (§2).

Folds five threads onto one page: audit F2/F3 (space unobserved/underived), P1
(the residency algebra — reused as the transform), P4 (re-point pack input from
MeasuredPeak to derived bound; retire the reactive governor), the 2026-07-12
ruling (derived not authored literals), the allocation model (the derived
per-witness bound IS the up-front allocation; Σ ≤ budget = GUARANTEED mode at
witness grain). Sequence: witness-grain concrete space first (closed closures),
then asymptotic, then re-point P4, then ratchet the frontier to error.

Bound into the doc graph via the witness-realization P1 note (which this
supersedes as the keystone); orphan wall green.

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

* Space complexity increment 1a: peak-working-set derivation, the dual of time

The space-complexity analysis's core, as the structural dual of the existing
time cost-expr — green by execution, no rebuild (interpreted from source).
In src/v1/complexity.dag, beside the cost algebra it duals:

- space_of(work: CostExpr) -> CostExpr : the transform. Sequential steps RELEASE
  so time's CostAdd becomes CostMax; concurrent steps CO-RESIDE so time's CostMax
  becomes CostAdd (P1's space_measure_seq=max / space_measure_par=add, lifted to
  CostExpr); a fold's CostSum collapses to its body's peak (iterations release).
  CostUnknown passes through fail-closed.
- fold_peak_space(body_peak, output_size) : adds the accumulator/output_size term.
- eval_cost_expr_concrete / eval_size_expr_concrete : lower a closed expr to
  concrete bytes (Absent on any unknown/free var — refuses, never fabricates).

Witnesses (6, green by execution, --source-root src/v1):
- reducing_fold_is_constant_space: O(n) time fold -> O(1) space (the headline)
- sequential_releases_max_not_sum / parallel_coresides_add_not_max: the P1 duals
- concrete_derived_bytes: closed expr -> exact bytes (40)
- fold_that_builds_is_linear_space: output_size 100*4 + body 4 -> 404 bytes
- unknown_cost_is_fail_closed_space: CostUnknown -> unknown space, concrete refuses
  (the SpaceBoundUnknown counted bottom; hard-error ratchet is the later stage)

Design: space-complexity-design.md §2. Not floor-enrolled yet — imports
v1.compiler.complexity so needs --source-root src/v1 (like the v1-internal
tests); enrollment (host bin or v1-root discovery) is the follow-up, alongside
the ComplexitySummary.peak_space field (38 construction sites) and the P4
re-point onto the derived bound.

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

* Space complexity increment 2: asymptotic reading (O(n) etc.), space order below time

The second reading the operator asked for — asymptotic space class — reusing
std.induction's CostBound/cost_poly on space_of(work). Green by execution, no
rebuild (interpreted). In src/v1/complexity.dag:

- cost_expr_degree(e) -> Int? : polynomial degree. CostSum over a size var = +1
  factor of n; seq/par take MAX degree; products ADD; bare log = degree 0
  (sub-linear); Absent = frontier (fail-closed, never a fabricated degree).
- space_asymptotic_bound(work, param) = degree_to_bound(cost_expr_degree(space_of(work)))
  -> ConstantBound | cost_poly(...) | ForeverBound. time_asymptotic_bound is the
  same on the raw work, for the side-by-side.

Because space_of collapses the CostSum a reducing fold's TIME carries, space
order is <= time order by construction. Witnesses (4, green):
- reducing_fold: O(n) TIME (degree 1), O(1) SPACE (ConstantBound)
- nested_reducing_loop: O(n^2) time, O(1) space (both CostSums collapse — the
  striking dual)
- parallel_region: constant space
- frontier_maps_to_forever_bound: CostUnknown -> ForeverBound, not a degree

Design: space-complexity-design.md §3. Increments remaining: wire peak_space into
ComplexitySummary (rebuild-gated, 38 sites), re-point P4, ratchet the frontier.

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

* Wire space-complexity into ComplexitySummary (peak_space + concrete fill)

Extend the landed space-complexity analysis (space_of / fold_peak_space /
eval_cost_expr_concrete) into the compiler's per-function summary.

- ComplexitySummary gains an OPTIONAL peak_space: CostExpr?. Optional so the
  P0 field wall (04_infer) skips it: all ~38 existing construction sites stay
  unchanged, an absent peak_space = the SpaceBoundUnknown counted frontier
  (fail-closed staging). Verified: complexity.dag entry-compiles 0 diagnostics.

- Derived once at the finalized per-function summary (get_or_compute_summary's
  `simplified`) via derive_peak_space: space_of(work) for a scalar result,
  additive fold_peak_space(space_of(work) + output_term) for a collection
  result (the `result` output_size entry). Intermediate/error/external/seed
  summaries leave peak_space absent by design.

- cost_account_space_from_summary(summary, size_env) -> ByteSize? fills
  CostAccount.space (basis Derived): eval peak_space at a closed size_env to a
  concrete ByteSize; absent peak_space or an underivable expr returns none,
  never a fabricated bound.

- New witness complexity_summary_space_witness_test.dag (4 test fns, green by
  interpretation): derived peak yields expected bytes; absent peak -> none;
  underivable (CostUnknown) peak -> none (RED control); reducing-fold work is
  O(1) space regardless of n.

Follow-up (out of scope): regen + rebuild-to-seed to activate the compiled
realization.

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

* P4 re-point: pack against the DERIVED bound, not measured peak — seam closed

Operator direction (derive, don't measure — §4). std.realize_pack re-pointed off
P1's measured peak onto the statically DERIVED space bound:
- MeasuredPeak/PeakMeasured/PeakUnknown -> DerivedBound/BoundDerived/BoundUnknown
- measured_peak_of(CostAccount) -> derived_bound_of(derived_space: ByteSize?):
  Present = the derived working-set bound, Absent = SpaceBoundUnknown (the
  fail-closed frontier). P4 is now decoupled from CostBasis — it consumes the
  ByteSize? that cost_account_space_from_summary (eeeda2b, the subagent's
  ComplexitySummary wiring) produces. That closes the seam:
  ComplexitySummary.peak_space -> space_of derivation -> cost_account_space_from_summary
  -> ByteSize? -> derived_bound_of -> realize_pack_width.
- realize_pack_width / realize_fits_budget take DerivedBound; BoundUnknown -> the
  width-1 maturation reserve (a not-yet-derivable subject runs alone, not a
  fabricated number); the refuse-not-fabricate discipline unchanged.

Measurement (P1's ObservePeakResidentAtSubject) is demoted to at-most a
falsifier, never a scheduler input — the whole memory-control line is now
derived, not observed.

Witnesses (6, green by execution, interpreted — no rebuild): packs within
budget (headroom-reserved 3, not 4); capped by independence; never exceeds
budget (the exit-137 arithmetic control); BoundUnknown -> maturation reserve;
unreadable budget -> refuses; derived-vs-frontier bound discrimination (the new
ByteSize? seam).

Remaining for P4: activate in the seed (regen — gated with the space-complexity
seed activation) + wire realize_pack into claim_executor per-runnable scheduling.

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

* Regen seed: activate space-complexity peak_space in the compiled compiler

regen_stage0 activated the complexity.dag changes (peak_space field + space_of +
concrete evaluator, and the get_or_compute_summary derivation) into the generated
seed v1_compiler_complexity.rs — the one file that changed (surgical; the other 94
generated files byte-identical). Built on srv1 (128 cores, 4m17s cold / 2m34s
rebuild — off the memory-constrained Pi that watchdog-crashes on this crate).

regen_stage0 --verify: regen_divergence_count=0 — committed stage0 matches a fresh
self-compile, so the byte fixed point holds with peak_space live. The compiled
compiler now derives peak_space during real complexity analysis (previously only
interpreted from source).

Remaining (flagged by the wiring pass): the interpreter RAISES on an omitted
optional field while the seed reads None gracefully — latent-safe today
(cost_account_space_from_summary is only called on simplified summaries, which
always set peak_space), reconcile when a broader consumer lands.

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

* Space classes in ComplexityReport (observable on real code) + floor-classify new witnesses

Two things the srv1 corpus validation surfaced.

1. Observability: ComplexityReport gains space_classes: Map<String,String> beside
   function_classes — build_complexity_report now derives it via
   classify_complexity(space_of(work)) per function, so the derived SPACE order
   is observable for every REAL gunbc function (not just synthetic CostExpr
   witnesses). TopoBuildAcc threads it; empty_complexity_report seeds it.

2. Floor classification (validation caught my new witnesses breaking the hermetic
   floor — neither a space-complexity logic regression):
   - The three space witnesses import v1.compiler.complexity, unresolvable in the
     discovered corpus's roots -> a FATAL resolve halt at entry 46. Excluded from
     discovery (they run in the v1 lane via --source-root src/v1; host-bin
     enrollment like diagnostics_witness is the proper follow-up).
   - artifact_store_fs_witness does real Filesystem.Write -> hermetic refuses
     (correctly). Excluded from hermetic discovery (wet lane), same pattern as the
     existing ci_deploy_observed_wet / host_effect_apply wet exclusions.

Interpreted entry-compile green; srv1 regen+rebuild+corpus re-validation follows.

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

* Fix the debt srv1 corpus validation caught: residue wildcards + the last wet witness

The srv1 corpus run (1900 PASS, and the space-complexity seed activation proven
corpus-safe) surfaced 4 failures, all from witnesses I added this session — none
a logic regression:

- 2 non_fold_residue FAILs: my witnesses + realize_pack used `_ =>` wildcards over
  closed coproducts (CostExpr, CostBound, RealizeVerdict) — the §4 residue the lens
  bans. Fixed by making them exhaustive/behavioral: realize_pack + its witness
  list every RealizeVerdict arm; the space witnesses now assert through the
  concrete evaluator (eval_cost_expr_concrete, exhaustive Optional) and the
  polynomial degree (cost_expr_degree) instead of matching CostExpr/CostBound
  structure — cleaner behavioral tests (sequential releases -> eval 50 not sum 80;
  parallel co-resides -> eval 80 not max 50) with ZERO wildcards.
  non_fold_residue_clean_holds -> true (0 unrostered residue, re-verified).
- 2 emit_source_store FAILs: real Filesystem.Write in hermetic mode. The path is
  test/claim/manual/ (not test/manual/), so the existing exclusion missed it;
  added emit_source_store_test.dag explicitly (wet lane).

All rewritten witnesses green by interpretation; final srv1 corpus re-validation
follows.

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

* Regen seed: space_classes into the compiled compiler (merged-tree consistency)

regen_stage0 on the merged tree (main-merge #6780/#6783 + my space-complexity
work) changed exactly one seed file — v1_compiler_complexity.rs — activating
space_classes (the ComplexityReport space-order surfacing) in the compiled
compiler. main-merge seed was already consistent; this is the clean delta for
my complexity.dag change, keeping regen --verify green.

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

* P4 handoff: executor cutover is a bridge call, not a self-host dependency

Records the corrected framing in the plan's P4 section: claim_executor is the
terminal bootstrap kernel (not a self-host emit target) and already interprets
.dag, so it can call realize_pack through run_in_context_with_args rather than
forking the packing law into Rust (§2) or waiting on the 27-module frontier.
Seam: surface the derived bound, read the governor's budget, call realize_pack,
advisory-first then demote the governor.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Fix compile-clean gate: move space-complexity witnesses out of dag/ tree

The three space-complexity witnesses import v1.compiler.complexity (a src/v1
module), but lived in dag/test/claim/. The whole-tree compile-clean gate
compiles [dag, src/v2] WITHOUT src/v1, so their imports could not resolve —
red as 'module v1.compiler.complexity not found' whenever a src/v1 touch
forces the whole-tree baseline. Discovery-exclusion handled the runner but
not the gate; a dag/ file simply cannot import from src/v1.

Move them to src/v1/test/claim/ (compiled with src/v1, not swept by regen's
seed-closure walk, not in discovery scan dirs) and drop the now-dead exclusion
substrings. All 6+4+4 test fns pass from the new home via
claim_batch --source-root src/v1 --source-root dag --source-root src/v2.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Fix batch-4 gate regressions: extdeps authority anchor + drop redundant frontier binding

- extdeps_external_authority_gate: artifact_store_fs.dag (P2, new) was the only
  extdeps/realization module missing the extdeps_external_authority_anchor every
  sibling declares. Add it (Https -> the realization dir, matching v1_handler).
  All 9 realization modules now carry exactly one anchor.
- self_host_realized_comparison / cleanup: drop emitted_crate_partition_plan_doc_provenance
  from frontier.dag. It was a doc-reachability workaround added when the design doc
  was orphaned; main #6828 now links it from DESIGN.md (line 92), so the row is a
  redundant duplicate binding (unreferenced). frontier.dag is now byte-identical to main.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Fix self_host_realized_comparison: drop v2 import from relocated witnesses

Moving the space witnesses to src/v1/ (to fix compile-clean) put them in
regen_stage0's compile surface ([src/v1, dag]) — but they still imported
v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } (src/v2, not in
regen's roots), so 'regen_stage0 --emit-fresh' failed with unresolved import,
and self_host_realized_comparison_reads_real_bytes then couldn't read the
fresh-emitted bytes (No such file or directory) -> Bool(false).

The v2 import fed only a 'data live_tree_disposition = SubstrateInputsOnly'
metadata decl for discovery-based affected-set selection, used in no test fn
and moot now that these run manually. Drop the import + decl; the witnesses
become pure [src/v1, dag] (std + v1.compiler.complexity), compile clean under
both regen and the manual runner, and all 6+4+4 test fns still pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Delete homeless space-complexity witnesses (operator: 2026-07-18); declare Rust-test follow-up

The three space-complexity .dag witnesses test v1.compiler.complexity (a src/v1
compiler-internal module) and had no clean home: dag/ fails the compile-clean
gate's cross-layer import ([dag, src/v2] roots, no src/v1), and src/v1/ makes
regen_stage0 --emit-fresh emit them as unregistered stage0 seed files (breaking
self_host_realized_comparison). The analysis stays proven in-seed by execution
(regen, runs every compile); the discriminating behavioral REDs are recorded in
space-complexity-design.md as a declared follow-up to re-add as Rust tests in
compiler_tests.rs when P4 makes the coverage load-bearing.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <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