Files
alkstore/tasks/suite-tx-commit-atomicity-rows.md
T

3.6 KiB
Raw Blame History

id, name, status, depends_on, scope, risk, impact, level, tags
id name status depends_on scope risk impact level tags
suite-tx-commit-atomicity-rows Contract-suite rows — outbox/keyed-publish tx commit-atomicity + with_tx panic probe pending
moderate low phase implementation
wave-5
contract-suite
tx-seam

Description

Add the tx-seam commit-atomicity rows to alkstore-contract-suite/src/properties.rs and wire them into both engines' suite targets, discharging three backlog rows (core-contract.md §Verification backlog): "outbox_enqueue_tx commit-atomicity on both engines" (ADR-014), "publish_with_key_tx commit-atomicity on both engines" (ADR-015 §2), and the N-5 with_tx panic-disposition probe (the waves-1–2 general review's ordered wave-5 add — the panic path "can only be fully pinned once a real engine's handle exists").

Rows to add:

  • outbox_enqueue_tx_commit_atomicity — rollback drops the backing-queue job row together with the business write (no ghost job; run_once afterwards claims nothing); commit makes the job claimable by run_once exactly when the business write commits (drive a real delivery through the Delivery closure); the stamped opts are the outbox's derived 60/5/5 set, get_job-visible and identical on both engines (ADR-014 §1, ADR-010 §3a). The reserved/empty outbox-name validation legs already pin in the exemplar row — do not duplicate them.
  • publish_with_key_tx_commit_atomicity — rollback drops the keyed event row with the business write (no ghost event); commit makes it visible to read_since (and a subscriber attach); the key round-trips on the committed event. The empty-Some-key InvalidName leg already pins in the exemplar — do not duplicate.
  • with_tx_panicking_closure_rolls_back — a closure that panics mid-flight ⇒ rollback with no residue (the uniform no-ghosts list: job/event/notify/offset — ADR-021 §4's drop = rollback through the panic path), and the store remains usable afterward (the SQLite writer slot replenished — the wave-3 stranding fix's property, now pinned at contract level). Mechanics hint: the panic crosses an await inside with_tx's own future, so drive it via tokio::spawn + JoinError::is_panic() (a catch_unwind around an async closure does not see the panic point); assert the panic surfaced and the post-panic state. This is N-5's probe against real engines for the first time — the SQLite handle-on-lease Drop impl and the pg pooled-object discard arm must both survive it.

Acceptance Criteria

  • Three rows exist, version-stamped (ADR-014 §1, ADR-015 §2, ADR-021 §4, ADR-007 as applicable)
  • Rows wired into both engines' contract_suite.rs targets
  • SQLite column green server-less; pg column green against the harness server
  • The panic probe passes on both engines (no writer-slot stranding, no pooled-object leak) — if an engine fails here, that is a real defect: stop, record, fix engine-side before completing the task
  • cargo test -p alkstore-sqlite -p alkstore-postgres green (pg rows skip cleanly server-less); clippy -D warnings; fmt clean

References

  • docs/architecture/core-contract.md §Verification backlog (outbox tx commit-atomicity; keyed-publish tx commit-atomicity)
  • docs/architecture/decisions/014-outbox-tx-enqueue.md §1
  • docs/architecture/decisions/015-streams-depth.md §2
  • docs/architecture/decisions/021-tx-reads-and-value-shape-fixes.md §4
  • docs/reviews/001-waves-1-2-general-review.md (N-5)
  • tasks/sqlite-engine-seam-tx.md (the Drop impl N-5's probe exercises)

Notes

To be filled by implementation agent

Summary

To be filled on completion