Skip to content

store: enforce ADR 0049 mutation seal (W5) - #368

Merged
vicondoa merged 26 commits into
v3from
adr046-w5
Aug 2, 2026
Merged

store: enforce ADR 0049 mutation seal (W5)#368
vicondoa merged 26 commits into
v3from
adr046-w5

Conversation

@vicondoa

@vicondoa vicondoa commented Aug 1, 2026

Copy link
Copy Markdown
Owner

Summary

  • land ADR 0049 store-owned mutation seal across the resource store, redb backend, and resource API
  • add external compile-fail fixtures, policy assertions, and committed API-surface snapshots
  • retain the redb proof corrections and storage schema contract with changelog coverage

Validation

  • make test-rust-api-surface — pass
  • make test-rust — pass
  • D2B_ENABLE_FIXTURE_BUILD=1 make test-fixture-contracts — pass
  • make test-policy — pass
  • make test-drift — pass
  • make test-proofs — pass
  • make test-runtime-ledger — pass
  • make test-nix-unit — pass
  • make test-flake — pass
  • make check-tier0 — pass
  • make check-inventory — pass
  • make test-lint — pass
  • make test-changelog — pass
  • make test-performance-budgets — skipped by its documented advisory manifest policy; not used as evidence
  • focused external seal tests and full-scale redb proof fixtures — pass

Review

  • ten-seat binding panel: pending
  • required checks: pending

Merge

  • target v3; do not merge until the binding panel is unanimous and required checks are green

vicondoa added 26 commits July 31, 2026 16:55
…W5 )

Wave 5 is 146 work items across twelve parallel groups, against Wave 4's
32. At that size a shared-file collision that Wave 4 absorbed in a
follow-up round would collide across several groups at once, so the
scope and shared-file decisions are settled here rather than argued at
review.

Three specification corrections. The canonical crate names are the ones
that exist: d2b-session, d2b-resource-client and d2b-zone-routing are
workspace members with source, while d2b-bus-session, d2b-client,
d2b-bus-client and d2b-zone-router are absent everywhere. The zone
bundle DTO takes the crate root, matching the sibling generation_bundle
that Wave 4 shipped, because a bundle is an emitted artifact rather than
a resource and v3/ holds the resource object model.

Three unmet obligations. The canonical RSS fixture registers its watches
only after its last write, so it never executes the clone-per-watcher
path and cannot be cited as evidence that the fan-out correction works.
Latency targets stay recorded rather than met while no pinned runner
exists. The standing debt that names the production store chain is
carried in explicitly so no reviewer has to reconstruct it.

Two specification gaps carried forward unchanged: the derivation output
layout that zone-control-015 needs, and the security-key backing set.

Two inferences flagged for confirmation: per-round prep against the
binding panel's one-snapshot requirement, and landing redb with its
consuming slice on the Wave 3 precedent for rtnetlink and nftnl.
Keep host path authority out of the Zone runtime contract by carrying only validated broker-resolved identifiers. Require the ownership, filesystem, lock, marker, replacement, durability, and publication posture needed for fail-closed store open and replacement.
…W5 )

The store-004 slice was originally told to guard the whole-process RSS
measurement by checking pgrep -a cargo and waiting if the machine was
busy. That guard was wrong three ways, and the wave nearly took its
keystone evidence from it.

It watches the wrong processes: cargo forks rustc, and the memory is in
the children. When this was caught the host was running five rustc
processes totalling about 4.7 GB, a nix build at 8.8 GB resident, and a
nix eval at 3.0 GB. None are named cargo, so the check read as near-idle.

The wait belongs to nobody. The load came from unrelated worktrees
running multi-hour gates, which a slice agent has no authority to wait on.

Most importantly the bias runs toward a false pass. Under memory pressure
the kernel reclaims, so a maximum-RSS high-water mark reads lower. A
loaded measurement is biased toward passing the 24,576 KiB gate that
unblocks the entire wave critical path.

The slice may take a provisional reading for its own feedback. The
measurement of record is taken by the integrator on a quiet machine with
the precondition and machine state recorded beside the number.
The Zone resource store needs one bounded, fully durable engine before the watch and runtime layers can consume it. Preserve D106 by keeping redb API-neutral and binding the concrete bridge through a store-instance mutation port in d2b-resource-api. Correct replay and live fan-out so old envelopes are never decoded and matching watchers share immutable batches.
Operator decision: coding lanes move from gpt-5.6-sol to gpt-5.6-luna at
reasoning effort xhigh. The panel binding is untouched and stays on
github-copilot/gemini-3.1-pro-preview at effort high, so a lane still
cannot both author a change and attest to it.

The switch is safe against panel-attest because ensure_panel_binding is
an allowlist rather than a denylist: it admits only the exact panel
provider, model and effort, so it rejects gpt-5.6-luna records for the
same reason it rejected gpt-5.6-sol. No coding-model constant exists in
the delivery tooling.

One guard did depend on the old name. The manifest assertion in
policy_adr046_work_items existed, by its own comment, to catch a
manifest that reintroduces the coding model as a panel binding, but it
tested for the literal gpt-5.6-sol. Moving the coding model would have
left it passing while the regression it guards became undetectable, so
it now pins the whole gpt-5.6 family. That is strictly stronger, stays
correct across future rebindings, and collides with no Gemini panel
model. Verified by planting a new-coding-model spelling in a generated
artifact and confirming the assertion fails, then restoring.

Three prose sites that named the coding model are updated so the
specification does not assert a stale fact.
Evaluate the per-Zone storage artifact instead of treating source text as rendered evidence. Enumerate workspace metadata so direct redb use cannot spread beyond the backend while retaining the exact proof pin.
Preserve store-owned envelope layers and deletion state while making\nidempotent replay independent of minted identities. Quarantine ambiguous\nwriter failures, bind reads and cursors to their transaction lifetime, and\nleave watch policy to its owning coordinator.\n\nSeal the backend to API-owned verified mutation evidence and require explicit\npublication evidence before initializing an empty database.
Reject resource types whose active validator is not represented by a trusted\ncompiled contract. This keeps dynamic schemas fail-closed until their signed\ncontract decoder is available.
Reject production store instantiations whose mutation type is not the API-owned\nverified evidence. This closes the remaining safe-Rust trait fabrication path.
Add a test-only exec-status helper that duplicates the handed status fd with CLOEXEC before exec and closes the parent writer before waiting. The receipt race now scans /proc only after EOF confirms target exec, preserving the CMSG_CLOEXEC invariant.
@vicondoa
vicondoa merged commit 2c66560 into v3 Aug 2, 2026
59 checks passed
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