feat(session): start created sessions from published releases - #138
cursor[bot] wants to merge 38 commits into
Conversation
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.
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>
There was a problem hiding this comment.
Stale comment
Do not merge #138 in parallel with the command-history lineage.
created_session_for_start/start_created_assessment_sessioncorrectly forceAssessmentSession::newso a suspended or retired release cannot begin a new session. That start boundary is the right product cut. This head is still the #121 created-only persist/load stack: noassessment_session_command, no stale-prefix reject, no header-rowFOR UPDATE. A buyer who Activate/Pause on this head still loses later state on restart.Landing vehicle for persist/load/command-history is #146 (successor of #129/#125). Rebase the start boundary onto #146 after that lock head is green; do not open a third persist lineage. HTTP
POST /v1/sessionsand RFC 9457 remain the next buyer-visible gap and still depend on #87. Do not land #100.Sent by Cursor Automation: Fix Issues
There was a problem hiding this comment.
Stale comment
Created persist/load/start landing vehicle
Head
bb18b06is the correct successor of #121/#109/#106/#61 for Created-session persist, load, andstart_created_assessment_session.Verified:
- Start is
AssessmentSession::newthen persist. Unpublished/suspended/retired fail before insert.- Load uses
from_persisted_createdand does not re-check publication.- Invalid stored identity, out-of-range timestamp, and later stored state fail closed.
- HTTP / OpenAPI /
POST /v1/sessionswere not invented on this branch.Activate-after-restart is out of this Created-only slice; later-state/command-history remains #129 (and any successor that rejects stale shorter history). Do not land #100 (
0020).Next buyer-visible gap after this lands is HTTP start, which still needs #87 and #98. Do not open another Created persist PR.
Independent last-push approval and exact-head required checks remain required. This review does not approve.
Sent by Cursor Automation: Fix Issues
There was a problem hiding this comment.
Review of bb18b06 (Created persist/load/start)
No blocking correctness or security defect on this head. Unpublished, suspended, locale-mismatch, numeric/blank refs, and zero timestamps fail in AssessmentSession::new before persist_assessment_session runs. Load reconstitutes via from_persisted_created and is not treated as authorization. Exact replay is idempotent; rebinding and later stored states fail closed. Docs keep this slice as Active PR #138, not protected-main Implemented.
Do not merge from this comment. Independent last-push review is still required. Prefer this head over #121, #109, #106, and #61. Do not land draft #100. Later-state/command-history landing remains #129 (do not merge #125). HTTP POST /v1/sessions remains #87 + #98 + the HTTP landing vehicle (#149); do not add routes on this branch.
Residuals that belong on later slices, not a competing start PR
persist_assessment_sessionstill accepts any Created aggregate, including reconstitution. ADR-0005 already says persist is not the start boundary. HTTP must callstart_created_assessment_session/created_session_for_start.- Start trusts the caller-supplied
InstrumentRelease. Compose with #98 published-release load in one transaction before HTTP start. - Retired coverage lives on
session_release_binding; optional on a successor test only.
Next action
Keep #138 as the Created persist/load/start landing vehicle. Reviewers: approve only an unchanged check-clean head. Do not open another start-composition PR (#153 is a same-title duplicate — close or retarget it onto this head). After this lands, rebase #129 onto it.
Sent by Cursor Automation: Fix Issues
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>
There was a problem hiding this comment.
Review of bb18b06 (Created persist/load/start)
No blocking correctness or security defect on this head. Unpublished, suspended, locale-mismatch, numeric/blank refs, and zero timestamps fail in AssessmentSession::new before persist. Load is not authorization. Docs keep this as Active PR, not Implemented.
Landing vehicle is now #164. That successor keeps this persist/load/in-memory-start contract and adds start_created_assessment_session_from_stored_release so start reads stored publication state in the same transaction. Prefer #164 over this PR, #121, #109, #106, #61, and #98. Do not merge this PR in parallel with #164.
Do not merge from this comment. Independent last-push review is still required on #164. Later-state/command-history landing remains #154 (do not merge #125). HTTP POST /v1/sessions remains #87 + #149 after #164; do not add routes here.
Sent by Cursor Automation: Fix Issues
Processing consumption rows now require claim_deadline_at after #81. Seed the wall-clock deadline and prove binary restore preserves it.
|
Pushed This remains the created persist/load/start landing. Do not merge until exact-head checks and independent last-push approval succeed. Rebase #129 onto this head after it lands. Never self-approve. |
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
|
Hourly loop: prefer this start slice over closed #125. Exact head |
… success The library Display wrap test cannot use expect_err because postgres::Client is not Debug, and the let-else success arm is unreachable coverage.
|
Hourly loop: preferred session-start slice. Exact head |
|
Closing as superseded by protected-main implementation. Current protected main |


Why
PR #121 can persist and load a Created session after a later suspend or retire, but it has no start boundary.
persist_assessment_sessionaccepts any Created aggregate, including one fromfrom_persisted_created. A buyer who starts a session after the release is suspended would otherwise persist a reconstituted identity and bypassAssessmentSession::new.What this PR does
created_session_for_start/start_created_assessment_sessionso a new session callsAssessmentSession::newfrom a currently published release and then persists.InvalidReference.Out of scope
POST /v1/sessions/ OpenAPI / RFC 9457 (feat(api): add safe RFC 9457 problem-details primitive #87)load_assessment_sessionas authorizationTest plan
cargo test --test session_start --test session_persisted_identity --test session_release_binding --test documentation_architecture_contract --test traceability_active_pr_contractcargo clippy --all-targets -- -D warningscargo test --test postgres_assessment_session_persistence(needsTEST_DATABASE_URL)This is the successor to #121 for Created persist/load/start. Prefer this head over #121, #109, persist-only #106, and #61. Do not land draft #100 (
0020). Do not merge #125. Later-state/command-history landing is #129; rebase #129 onto this head after it lands rather than opening another later-state PR. Do not merge until exact-head checks and independent last-push approval are satisfied.