feat(delivery): durable delivery ledger, newest-format only - #484
Merged
schickling-assistant merged 1 commit intoSep 6, 2026
Merged
Conversation
Replace the two per-driver single-binding `delivery-state.json` guards (`CodexDeliveryState` in `src/codex_app_server.rs`, `DeliveryState` in `src/opencode_session.rs`) with one canonical module, `src/delivery_ledger.rs`, holding `st2.delivery-ledger.v1` at `<state-dir>/delivery-ledger.json`. The ledger owns persistence, phase grading, retry authority, binding isolation, validation, quarantine, and durable replacement. Codex and OpenCode only translate their provider observations into `Evidence`. Kept from the design: `Profile::proves`, the monotone phase lattice (attempted < transportAccepted < persisted < consumed), typed `Evidence`, per-filename entries, quarantine, and archive reconciliation via `prune`. Dropped deliberately: every predecessor reader, rollback floor, adoption path, and dead configuration axis. Writers emit the newest format only. Load validation is stricter than the reviewed draft: every entry must rederive its own correlation from its own binding and filename, so an injected entry that merely shares another entry's correlation value can no longer wedge a transport. The atomic write also keeps the `0600` `create_new` hardening the Codex record had, under a temp name unique per process and per write. agent-identity: dev3.direct.omp.43sz6ujq agent-persona: generalist agent-supervisor: unavailable agent-tool: OMP agent-tool-version: 18.1.7 agent-runtime: OMP 18.1.7 tooling-profile: dotfiles@39a19af
schickling-assistant
force-pushed
the
schickling-assistant/2026-09-06-delivery-ledger
branch
from
September 6, 2026 12:19
eb39b71 to
1116c4c
Compare
This was referenced Sep 6, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
One canonical module,
src/delivery_ledger.rs, replaces the two per-driver single-binding delivery guards —CodexDeliveryStateinsrc/codex_app_server.rsandDeliveryStateinsrc/opencode_session.rs. The record isst2.delivery-ledger.v1at<state-dir>/delivery-ledger.json, holding one entry per inbox filename.The ledger owns persistence, phase grading, retry authority, binding isolation, validation, quarantine, and durable replacement. The drivers only translate their provider observations into
Evidence; they no longer carry a delivery state machine each.Retained core:
Profile::proves— a harness may only record a phase it can actually observe. Codex provestransportAcceptedandconsumed; OpenCode provestransportAcceptedandpersisted. A record claiming any other phase is refused at load.attempted < transportAccepted < persisted < consumed;record()never downgrades.Evidence(TransportAccepted/Persisted/Consumed) as the only driver-facing vocabulary.prune(is_unread)keeps the recipient's inbox the settlement authority.Accepted harm
At first open after upgrade, at most one in-flight pre-ledger attempt per seat may be re-sent once; the archive receipt keeps inbox settlement idempotent (decisions Q2/Q7, seat dev3.direct.omp.43sz6ujq). Legacy delivery-state.json files are ignored, not read or deleted.
That is the whole reason this is a from-scratch replacement rather than #471: no predecessor reader, no rollback floor, no adoption path, no writer gate, and no dead configuration axes. Writers emit the newest format only.
Changes against the reviewed #471 draft
Two findings from the #471 architecture review are fixed here rather than carried:
load()accepted an entry whosecorrelation.valuewas merely anchored by some other entry in the record, so an injected entry with an arbitrary filename could load clean and wedge the transport. Here every entry must rederive its own correlation from its own binding and filename (every_entry_must_validate_its_own_correlation).File::createwould have dropped thecreate_new(true).mode(0o600)property the Codex record had, and shared one fixed.<pid>.tmpname between files. The atomic write now creates the temp exclusively at0600under a name unique per process and per write (the_persisted_ledger_is_owner_only_and_leaves_no_temp_residue).The remaining #471 findings (rollback-floor ordering, floor retention until archive, adoption when a ledger file already exists) do not exist here: there is no floor and no adoption.
Known limits
runtime_idrebinding is provenance, not a fence.INVARIANTS
Adds Durable native delivery ownership, proven by eight tests in
src/delivery_ledger.rs, includingbegin_persists_attempted_before_transport(the durable pre-transport write) andforeign_or_malformed_state_quarantines_without_rewriting.Gate
nix build .#st2 --no-link -L(doCheck runs the cargo suite).Replaces #471.
agent-identity: dev3.direct.omp.43sz6ujq
Posted on behalf of @schickling
agent_identitysessionagent_personaagent_supervisoragent_toolagent_tool_versionagent_runtimetooling_profile