sdk: journal guard combinator enforces reserve-before-effect#629
Merged
Conversation
Add Journal::guard to the nexum-sdk keeper: it reserves the submission key with the encoded body, runs the async submit closure, then disposes of the reservation as the closure's Disposition directs (Commit on accept, Release on a known non-accept, Park on a rate-limit hint, Retain for reconcile). The reserve-effect-commit order is fixed by the API shape, so a caller cannot run the effect unreserved or leave the marker unsettled; an existing marker short-circuits without running the closure. The combinator factors out the pattern the videre-sdk keeper run and the composable-cow run already inline, without changing either; markers stay on plain set. Tests cover the combinator semantics over the mock store and drive it through the reserve/commit/reconcile path with the FlakyCommit and counting-venue fixtures, asserting exactly-once and no stranded reservation.
mfw78
force-pushed
the
feat/609-sdk-guard
branch
from
July 25, 2026 10:58
6e5578e to
7905afc
Compare
mfw78
added a commit
that referenced
this pull request
Jul 25, 2026
Rewire submit_ready onto Journal::guard: the six inline journal.mark/reserve/commit/release calls that carry the #572 reserve-before-effect ordering fold into one guard call, with the venue outcome mapped to a Disposition (Accepted commits, requires-signing and known refusals release, an unknown outcome retains for reconcile). Behaviour is identical: all 23 composable-cow run tests including w1/w2/w3 and anti_572 pass unchanged. The remaining code is the CoW-specific outcome handling (refusal clear, retry ledger, tracing) that no primitive absorbs; the value is that the durable-effect ordering is no longer inlined, so a second venue's keeper reuses it rather than re-deriving it. Part of #609. Stacks on the Journal::guard combinator (#629).
mfw78
added a commit
that referenced
this pull request
Jul 25, 2026
Rewire submit_ready onto Journal::guard: the six inline journal.mark/reserve/commit/release calls that carry the #572 reserve-before-effect ordering fold into one guard call, with the venue outcome mapped to a Disposition (Accepted commits, requires-signing and known refusals release, an unknown outcome retains for reconcile). Behaviour is identical: all 23 composable-cow run tests including w1/w2/w3 and anti_572 pass unchanged. The remaining code is the CoW-specific outcome handling (refusal clear, retry ledger, tracing) that no primitive absorbs; the value is that the durable-effect ordering is no longer inlined, so a second venue's keeper reuses it rather than re-deriving it. Part of #609. Stacks on the Journal::guard combinator (#629).
mfw78
added a commit
that referenced
this pull request
Jul 26, 2026
Rewire submit_ready onto Journal::guard: the six inline journal.mark/reserve/commit/release calls that carry the #572 reserve-before-effect ordering fold into one guard call, with the venue outcome mapped to a Disposition (Accepted commits, requires-signing and known refusals release, an unknown outcome retains for reconcile). Behaviour is identical: all 23 composable-cow run tests including w1/w2/w3 and anti_572 pass unchanged. The remaining code is the CoW-specific outcome handling (refusal clear, retry ledger, tracing) that no primitive absorbs; the value is that the durable-effect ordering is no longer inlined, so a second venue's keeper reuses it rather than re-deriving it. Part of #609. Stacks on the Journal::guard combinator (#629).
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
Adds a
Journal::guardcombinator to the nexum-sdk keeper: it reserves the submission key with the encoded body, runs the async submit closure, then disposes of the reservation as the closure'sDispositiondirects (Commiton accept,Releaseon requires-signing or a terminal refusal,Park { until }on a rate-limit hint,Retainto leave the marker RESERVED for the reconcile pass). The result is aGuarded<T>:Ran(T)when the closure ran,Skipped(Mark)when an existing COMMITTED (idempotent duplicate) or RESERVED (reconcile-owned) marker short-circuited it without running the effect.Why
The reserve-before-effect, commit-or-release-after pattern is inlined by both the videre-sdk keeper run and the composable-cow run; a hand-rolled caller can mis-sequence it and either run an effect unreserved or strand a reservation. The combinator fixes the ordering by API shape so it cannot be mis-sequenced (#609, ADR-0014). It is purely additive: the existing keeper run, reconcile pass, and composable-cow run are behaviour-unchanged, a commit-write fault stays best-effort (the marker rides to reconcile, never a release), and the Journal's single-key markers stay on plain
set.Testing
nix develop --command just cigreen (fmt, clippy-D warnings, doc, wasm module builds, workspace tests), plusjust check-venue-agnosticandjust check-cow-orderbook-onlyboth green. New unit tests incrates/nexum-sdk/tests/keeper.rspin the combinator semantics (reserve visible before the effect, commit/release/park/retain dispositions, skip-on-marker, reserve-fault aborts before the effect); new tests incrates/videre-sdk/src/keeper.rsdrive it through the reserve/commit/reconcile path with the FlakyCommit and counting-venue fixtures, asserting exactly-once submission and no stranded reservation.AI Assistance
Implemented with AI assistance under maintainer direction.
Part of #609.