Skip to content

feat(session): lock stored publication during start - #227

Draft
cursor[bot] wants to merge 43 commits into
mainfrom
cursor/bc-d042267d-8de0-4748-9d62-d8b9790a8778-c268
Draft

feat(session): lock stored publication during start#227
cursor[bot] wants to merge 43 commits into
mainfrom
cursor/bc-d042267d-8de0-4748-9d62-d8b9790a8778-c268

Conversation

@cursor

@cursor cursor Bot commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

Why

PR #196 locks instrument_release during persist classification, but stored-release start still loaded with an unlocked SELECT. A participant start can insert after a concurrent Suspend or Retire commits.

What this PR does

  • Keep the fix(instrument): lock publication row during persist classification #196 persist-classification FOR UPDATE contract.
  • Lock load_published_instrument_release with SELECT FOR UPDATE so stored-release start holds the publication row until commit.
  • Prove the start lock and the source contract.
  • Record the start lock in ADR-0005, TRACEABILITY, AS_BUILT, and CHANGELOG.

Prefer this head over #196 for combined Created-only publication locks. Prefer #180 for command-history + start lock. Do not merge #196, #180, #164, or draft #100 in parallel. Do not merge until exact-head checks and independent last-push approval are satisfied.

Open in Web View Automation 

seonghobae and others added 30 commits August 14, 2026 10:46
Store participant and published-release identity for SessionState::Created
with exact replay and fail-closed rebinding. Command-replay persistence
stays outside this first slice.
Assert the Database error message and source, and fail the replay
SELECT after ON CONFLICT by redirecting search_path so classify
runs instead of the insert.
Treat landed PostgreSQL readiness as Implemented and keep #61 as the
Active created-session persist slice.
Treat landed migration rollback coverage as Implemented and keep #61
as the Active persist slice.
Linux llvm-cov leaves the isolated query_one ? tail uncovered unless
the Err arm is an explicit match. Keep the search_path redirect test.
Linux branch coverage missed the later AND operands of exact-replay
classification. Rebind each stored field independently, and prove a
domain-legal u64::MAX creation time fails closed as ValueOutOfRange.
The replay SELECT failure constructed Database evidence without
checking its safe display text or source, leaving those two production
lines uncovered on Linux.
SHOW transaction_isolation can fail after the caller transaction is
already aborted. Persist must surface that as a typed database error
instead of leaving the probe Result uncovered.
Satisfy clippy::manual_let_else in the library test that instantiates
AssessmentSessionPersistenceError::Database.
Name instrument_version_ref in the public persist contract and assert the
committed version column. Keep TRACEABILITY, changelog, and as-built schema
at Active PR #61 rather than promoting the slice to protected-main truth.

Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Restore persisted created-session identity from PostgreSQL without asking
whether the original release still accepts new sessions, so later suspend
or retire cannot rewrite provenance. Missing rows return none; later
stored states and malformed lookup references fail closed.

Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Name the opened successor so TRACEABILITY, as-built schema, and ERD
point at the persist-and-load head instead of the persist-only #106 slice.

Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
cursoragent and others added 13 commits August 16, 2026 15:33
Require the as-built table to name persist-and-load Active PR #109, not persist-only #61. Cover reconstitution of numeric or blank participant, release, and version references, and exercise load-path Database, InvalidStoredIdentity, and ValueOutOfRange through realistic PostgreSQL failures.

Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Point TRACEABILITY, ERD, and the as-built physical-schema table at the coverage successor so queue decisions do not land uncovered #109 or persist-only #61.

Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Add a start composition that calls AssessmentSession::new then persist so a
suspended or retired release cannot begin a new session and reconstitution
cannot be used as the start path. Load remains a lookup, not authorization.

Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Point TRACEABILITY, as-built, ERD, and the documentation contract at the
start-composition successor. #121 remains the uncovered-start predecessor.

Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Cherry-pick #98 so start can read the stored publication state instead of
trusting a caller-supplied in-memory InstrumentRelease.

Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Load the exact instrument release in the same transaction before persist
so a stale in-memory Published object cannot start a session after the
stored release is suspended or retired.

Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Retarget as-built, ERD, and TRACEABILITY from in-memory-start #138 to
the stored-release composition landing vehicle.

Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Hold SELECT … FOR UPDATE on instrument_release when classifying an existing
row so a Duplicate published result cannot lose the row to a concurrent
Suspend or Retire before the caller transaction ends.

Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Hold SELECT … FOR UPDATE on the published instrument_release row while
start_created_assessment_session_from_stored_release classifies and
inserts, so a concurrent Suspend or Retire cannot hide from that start.

Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Keep Active PR #196 as the persist-classification lock. Name the start-load
FOR UPDATE on this head without promoting either lock to Implemented.

Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Keep #196 as the persist-classification lock. Prefer #227 for combined
Created-only publication locks and #180 for command-history start lock.

Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
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.

2 participants