Store: define begin_effect / settle_effect(disposition) settlement seam (#216) - #248
Conversation
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
Warning Review limit reached
Next review available in: 37 minutes Limit details: You’ve used the included review currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?Wait for the limit to reset, then comment An organization admin can change what happens after included review limits in Billing. How do review limits work?CodeRabbit enforces per-developer PR review limits within each organization. For paid Pro and Pro+ reviews, CodeRabbit uses a developer's included PR review attempts over the past 7 days to set the current hourly allowance. At typical activity levels, the full plan allowance applies. Higher sustained activity can lower the allowance until earlier attempts leave the 7-day window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (5)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
e558024 to
ee10a92
Compare
What
Defines the two-phase settlement seam SHAPE for non-rollbackable external
effects (spec #208 D-003), and pilots it on the Gmail draft pending-write fence.
Store::begin_effect(PendingWriteFence, AuditDescriptor) -> BeginEffect:claims the pending-write fence and appends its audit row in one
Immediatetransaction. ReturnsBeginEffect::Fenced(EffectFence)on asuccessful claim, or
BeginEffect::AlreadyFenced(no write) on a lostconcurrent claim — matching
claim_pending_draft_write's contract.Store::settle_effect(EffectFence, EffectDisposition, AuditDescriptor):routes on the typed
EffectDispositiondelivered by Effect Truth B+C: typed EffectDisposition and disposition-driven settlement (T2+T3) #238 — the samefinalize / cancel / retain authority as
settle_reservations:ConfirmedSuccess→ finalize (resolve the fence)ConfirmedFailure/NotAttempted→ cancel (resolve the fence)DeliveryUnknown→ retain + fence (leave the rowpending; no duplicate send)Each transition is paired with its audit row in one
Immediatetransaction.pipeline/approval_draft.rs::create_approved_draftnow drives itsfence claim through
begin_effectand its settlement throughsettle_effect.The connector call stays in the pipeline; the store owns only fence + audit.
claim_pending_draft_write_conn/resolve_pending_draft_write_connon-transaction helpers; the standaloneclaim_/resolve_pending_draft_writewrappers become#[cfg(test)](theironly remaining callers are regression tests).
Why
Per the ticket coordination note and DIRECTION.md: this ticket defines the seam
that Effect Truth #198 fills with disposition logic. #238's typed
EffectDisposition+settle_reservations()and #215'swith_audited_effectare merged, so
settle_effectreuses the existing typed disposition androutes to the existing settlement authority — no new disposition
classification (that stays in #198). The seam also closes a Ledger gap: the
fence claim was previously written with no paired audit row;
begin_effectnowaudits it.
Verification
./scripts/check.shis green for this change. New seam-shape tests(
store/effect_settlement_tests.rs) prove:DeliveryUnknownretains + fences(no duplicate send),
ConfirmedSuccess/ConfirmedFailure/NotAttemptedresolve the fence with a paired audit row, and a second
begin_effectfor thesame fingerprint claims no second fence and writes no audit row. Full kernel
suite (1146 tests) green.
Implementation notes (five-line summary)
EffectDispositioninstead of a newDispositionenum (per dispatch, supersedes the stale CodeRabbit plan);
begin_effectbuilt on
with_immediate_tx+append_audit_conn(notwith_audited_effect,which always audits) so the lost-claim no-op writes nothing; new
draft.pending_write_openedaudit kind on the claim path.EffectDispositionshould move belowstore(store now referencescrate::api::...::EffectDisposition); deferred to Effect Truth Slice A-C: Characterise, type, and settle (Epic) #198.NotAttemptedunreachable at settlement in the pilot but handled.store/effect_settlement.rs.Closes #216
Summary by cubic
Introduces a two-phase settlement seam for non-rollbackable external effects and pilots it on Gmail draft writes. Previously the pipeline claimed the draft fence without an audit and resolved fences directly; now
begin_effectclaims and audits atomically, andsettle_effect(disposition)finalizes/cancels or retains with a paired audit, leaving delivery-unknown fences open to prevent duplicate sends.StoreAPIs:begin_effect(PendingWriteFence, AuditDescriptor) -> BeginEffectreturnsFenced(EffectFence)orAlreadyFenced;settle_effect(EffectFence, EffectDisposition, AuditDescriptor)routes:ConfirmedSuccess→ finalize;ConfirmedFailure/NotAttempted→ cancel;DeliveryUnknown→ retain and keep fencepending. Each write pairs with its audit in one Immediate transaction.create_approved_draftnow uses the seam; the connector call remains in the pipeline. Lost claims writedraft.pending_write_fencedand skip the provider; inline outcome→disposition mapping is temporary until Effect Truth (Effect Truth Slice A-C: Characterise, type, and settle (Epic) #198).draft.pending_write_openedon successful claims; settlements use supplied kinds (draft.created,draft.creation_failed,draft.delivery_unknown) with references.claim_pending_draft_write_conn/resolve_pending_draft_write_conn; old wrappers are#[cfg(test)]. New modulestore/effect_settlement.rs; re-exportsBeginEffect,PendingWriteFence.Written for commit ee10a92. Summary will update on new commits.