Skip to content

feat(mailbox): add trusted-host local durable journal and receipts - #5377

Merged
auser merged 63 commits into
mainfrom
feat/4630-durable-mailbox-journal
Nov 13, 2026
Merged

auser merged 63 commits into
mainfrom
feat/4630-durable-mailbox-journal

Conversation

@auser

@auser auser commented Nov 12, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Add a production trusted-host accepted_local_durable mailbox tier. The helper persists an encrypted, bounded local journal and signed receipt outside the source VM lifecycle; a guest verifies the V2 receipt before clearing its pending send. This does not claim host-blind confidentiality, whole-host rollback detection, or the independent witness required by accepted_durable.

What changed

  • Bind signed retention, boot authority, key custody, admission posture, and quota to local journal opening; recover delivery, deduplication, expiry, and ACK state across helper restarts.
  • Keep V1 accepted_durable behind independent authority; add distinct signed V2 local receipts and exact same-ID retry semantics.
  • Add a dedicated local-durable guest outbox and boot-bound reader/ACK path, plus protocol, integration, and production-helper BDD witnesses.
  • Update ADR-057, CLI/reference documentation, and relevant gate expectations for the new tier.

Validation

  • TMPDIR=/tmp cargo test --workspace — passed on final PR head 7f06f10, including doctests, after making guest-port outbox fixtures and cold-ACK write failure deterministic. Focused guest-agent tests (88/88) also passed.
  • cargo check --workspace and cargo clippy --workspace -- -D warnings — passed.
  • just check::gated — passed.
  • cargo run --locked --offline -p xtask -- check-all — 84 gates clean.
  • Focused BDD A production helper persists a local receipt and guest ACK — passed (host-process loopback, not a booted VM).
  • Live GCP/KVM witness just lab::gcp-kvm just bdd::live-ci — authorized and run, but not passing: the first runs exposed a root-run harness and then a missing systemd user session bus. Both harness failures were corrected. The c8b755f run reached booted Firecracker BDD and passed 7/8 scenarios; the final network-secret scenario selected QEMU with a Firecracker-only kernel and failed. The 34e6f9f rerun also passed 7/8; the final OCI-egress witness refused Firecracker because isolated homes lacked a discoverable pinned binary. The GCP harness now verifies the installed binary against the release lock and passes its absolute path explicitly. On 2999b08, TMPDIR=/tmp CLOUDSDK_COMPONENT_MANAGER_DISABLE_UPDATE_CHECK=1 CLOUDSDK_CORE_DISABLE_PROMPTS=1 just lab::gcp-kvm just bdd::live-ci passed 8/8 selected live scenarios and 89/89 steps. The other 459 BDD scenarios were intentionally outside the selected ci_live tag, not covered by this run. This lane does not boot a guest for the new local-durable mailbox receipt/ACK; the mailbox-specific BDD witness remains host-process loopback. Result archive: /tmp/mvm-gcp-kvm-results/20261113T020139Z-63438/mvm-gcp-kvm-results.tar.gz (exit-status 0). The Spot VM was deleted and verified absent.

Scope and review

Partial work toward #4630. Its broader host-blind, snapshot, and external-effect acceptance criteria remain unchecked; this PR must not close the issue. Ready for code review. The full workspace suite passed on 2e5ec98 after eliminating two nondeterministic guest-agent test fixtures (closed-peer ACK write and outbox lock contention). The Linux test-only Clippy safety-comment placement was fixed in e90577f. Final PR head 7f06f10 integrated main; its Rust footprint gate, cargo fmt --all -- --check, full workspace suite, and required CI checks passed. The selected GCP live-ci lane passed on earlier 2999b08; it did not exercise a booted mailbox. All required CI checks passed on 7f06f10 (15 successful, 2 skipped); PR #5377 entered the main merge queue and landed as 6850b98. The independent current-head local workspace suite passed; #4630 remains open with broader unchecked criteria.

auser added 30 commits November 10, 2026 13:05
# Conflicts:
#	crates/mvm-agentd/src/bin/mvm-guest-agent/mailbox.rs
#	crates/mvm-agentd/src/mailbox_outbox.rs
#	crates/mvm-core/src/mailbox/frame.rs
#	crates/mvm-hostd/src/mailbox_launch.rs
#	crates/mvm-hostd/src/mailbox_process.rs
#	crates/mvm-hostd/src/mailbox_service.rs
#	crates/mvm-hostd/tests/mission_demo.rs
Persist unsigned receipt state and a destination-signed admission intent in versioned encrypted records. Sign durable receipts only after journal and anchor commitment; refuse the legacy callback path. Add recovery and failure-path witnesses without claiming a deployed checkpoint or history-key provider.
Replace local FileJournalAnchor acceptance expectations with explicit refusal across service and process restart. Exercise signed lease and ACK recovery only behind a test-scoped compare-and-advance anchor; the real service remains dev-ephemeral and production-refusing.
The old corrupt-anchor fixture could only fail because its helper lacked admitted posture. Assert that actual fail-closed boundary instead of claiming local-anchor verification that never ran.
The old integration fixture required unverified helper posture and local-file accepted_durable. Preserve its missing-posture refusal; the verified-token mailbox-process unit test covers lifecycle exit. Based on guest owner test handoff 6e75656.
Recheck retained authority-signed enrollment, Receive capability and lease, plus the guest ACK signature, before recovery advances the anchor. Require current boot, session and expiry authorization on an exact committed ACK retry. Exercise malicious history-key record rewrites and stale duplicate attempts under a test-only CAS anchor.
Refuse the legacy unsigned host ACK for any guest-leased message at admission and replay, while retaining it for never-leased host messages. Exercise the live refusal and a forged encrypted recovery record with matching MAC and mock anchor.
Authenticate mailbox, epoch and history-key version in v3 records and admission intents. Keep constructors test-scoped until verified restart authority exists; refuse raw-key durable admission. Preserve original accepted receipt state for future local lost-verdict reconciliation and reject silent v2-to-v3 reinterpretation.
Demonstrate that decoded key IDs, versions, epochs and authorization domains are not authority even when a test custody source returns the same key bytes. Document the signed plan and restart-manifest precondition for any production opener.
@auser
auser marked this pull request as ready for review November 13, 2026 02:05
@auser
auser enabled auto-merge November 13, 2026 04:07
@auser
auser disabled auto-merge November 13, 2026 04:36
@auser

auser commented Nov 13, 2026 •

Copy link
Copy Markdown
Collaborator Author

Updated head f7536f6584 by merging current main to remove the footprint-ratchet conflict; the only manual resolution retained the full Rust measurement and raised the branch ceilings to 985,000 SLOC / 1,252,000 physical lines. Current-head CI now has Test and Invariant green. Auto-merge remains disabled pending the stated independent review gate; the earlier selected GCP live-ci result does not witness a booted local-durable receipt/ACK on this head.

@auser
auser enabled auto-merge November 13, 2026 07:21
@auser
auser disabled auto-merge November 13, 2026 08:02
@auser
auser added this pull request to the merge queue Nov 13, 2026
Merged via the queue into main with commit 6850b98 Nov 13, 2026
17 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