fix(auth): stop claiming command records were store-loaded - #144
cursor[bot] wants to merge 17 commits into
Conversation
Keep the session-authorization adapter beside the landed account-link module.
Derive the assessment-session resource from the stored participant tenant and the loaded session so a transport cannot invent a matching scope and then command a different session. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Keep the loaded session unchanged when the proof is expired or names a different session, and still fail closed on illegal lifecycle transitions. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Compare the verified actor to the loaded participant tenant and session instead of rebuilding a ResourceScope. Tenant mismatch is reported before ownership so a foreign-tenant inconsistent pair cannot hide as OwnerMismatch. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Store tenant, participant reference, anonymous status, and creation time so command authorization can load the participant instead of rebuilding it from the proof. Exact replay is idempotent; tenant or time rebinding fails closed; linked participants stay out of this slice. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Record the opened successor so architecture views do not leave the assessment-participant slice unlabeled. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
#114 already owns assessment_participant plus append-only identity-link history on migration 0021. This successor keeps the #104 command-auth contract fix and does not open a colliding anonymous-only persist slice. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Command authorization compares the verified actor to supplied participant and session values. It does not accept a ResourceScope and does not claim those aggregates were store-loaded. Align rustdoc, ADR-0003, SECURITY_AND_DATA, UML Activate, TRACEABILITY, and CHANGELOG. Use a session created after publication and before exclusive proof expiry. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Backtick the publication and exclusive-expiry instants in the command authorization fixtures, and name honesty successor #135 in TRACEABILITY. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Point command-authorization honesty at the opened successor so reviewers do not treat #135 as the landing head. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
There was a problem hiding this comment.
Honesty slice is correctly scoped: the as-built command gate compares caller-supplied ParticipantRecord and AssessmentSession, does not accept a caller-built ResourceScope, and does not mutate on deny. Fail-closed order is time → expiry → participant tenant → owner → session. No authorization fail-open.
Residual honesty still blocks treating this head as the landing vehicle:
- Persist pointer is stale. Docs and the architecture contract still require Active PR #133. The live persist/reload successor is #147 (prefer over #133 / #124 / #114). This is the same class of leftover pointer this slice removed for #114.
- Command-test module docs still say a transport must load from the product store. The gate does not require or prove that.
- Target UML mermaid still says
authorize anonymous command from loaded recordsafter the as-built disclaimer. The load step is already the precedingA->>DBarrow; the gate step should say supplied records.
Do not self-approve. Do not add HTTP or a second persist implementation here. Keep persist on #147. Independent last-push approval and exact-head checks remain merge gates. A successor on this run retargets the pin and leftover load wording.
Sent by Cursor Automation: Fix Issues
| "{label} must not name superseded #114 as the current participant persist landing" | ||
| ); | ||
| assert!( | ||
| document.contains("#133"), |
There was a problem hiding this comment.
| @@ -0,0 +1,435 @@ | |||
| //! Contract tests for anonymous command authorization against supplied aggregates. | |||
| //! | |||
| //! A transport must load the participant and assessment session from the product store, | |||
There was a problem hiding this comment.
Leftover overclaim. These tests construct in-memory aggregates; the as-built gate does not require or prove a store load. Say the transport should load before calling the gate, or that these tests pass supplied records. Do not say a transport must load.
|
|
||
| C->>A: activate session | ||
| A->>DB: load assessment_participant + assessment_session | ||
| A->>A: authorize anonymous command from loaded records |
There was a problem hiding this comment.
Target sequence already loads on the previous arrow. from loaded records still reads as if the command gate performed or proved the load. The as-built disclaimer on line 281 is honest; this mermaid step should say supplied records so the two layers stay distinct.
Point command-authorization honesty at the opened successor so reviewers do not treat #135 as the landing head. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Point command-authorization honesty at the opened successor so reviewers do not treat #135 as the landing head. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Point command-authorization honesty at the opened successor so reviewers do not treat #135 as the landing head. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
* test(auth): bind anonymous proof to exact session resource * feat(auth): bind anonymous proof to exact session resource * feat(auth): expose anonymous session authorization * style(auth): apply rustfmt to anonymous authorization tests * test(auth): pin anonymous denial precedence * docs(auth): explain anonymous session authorization * feat(auth): authorize anonymous commands from loaded session Derive the assessment-session resource from the stored participant tenant and the loaded session so a transport cannot invent a matching scope and then command a different session. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com> * feat(auth): apply session commands only after anonymous authorization Keep the loaded session unchanged when the proof is expired or names a different session, and still fail closed on illegal lifecycle transitions. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com> * fix(auth): classify anonymous commands from loaded records Compare the verified actor to the loaded participant tenant and session instead of rebuilding a ResourceScope. Tenant mismatch is reported before ownership so a foreign-tenant inconsistent pair cannot hide as OwnerMismatch. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com> * feat(participant): persist anonymous assessment identity Store tenant, participant reference, anonymous status, and creation time so command authorization can load the participant instead of rebuilding it from the proof. Exact replay is idempotent; tenant or time rebinding fails closed; linked participants stay out of this slice. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com> * docs(traceability): name Active PR #118 for participant persist Record the opened successor so architecture views do not leave the assessment-participant slice unlabeled. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com> * revert(participant): leave persist/reload on Active PR #114 history on migration 0021. This successor keeps the #104 command-auth contract fix and does not open a colliding anonymous-only persist slice. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com> * fix(auth): tell the truth about supplied command records Command authorization compares the verified actor to supplied participant and session values. It does not accept a ResourceScope and does not claim those aggregates were store-loaded. Align rustdoc, ADR-0003, SECURITY_AND_DATA, UML Activate, TRACEABILITY, and CHANGELOG. Use a session created after publication and before exclusive proof expiry. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com> * fix(auth): satisfy clippy doc-markdown on command timeline Backtick the publication and exclusive-expiry instants in the command authorization fixtures, and name honesty successor #135 in TRACEABILITY. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com> * fix(auth): stop claiming command records were store-loaded and named superseded #114 as the persist landing. The gate compares supplied records only; persist/reload remains Active PR #133. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com> * docs(traceability): name honesty successor Active PR #144 Point command-authorization honesty at the opened successor so reviewers do not treat #135 as the landing head. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com> * fix(auth): name persist landing #147 and drop leftover load claims The command gate still compares supplied records. Docs and the architecture contract now name Active PR #147 for persist/reload, forbid the leftover #133 pointer, and stop saying the gate authorized from loaded records. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com> * docs(traceability): name honesty successor Active PR #159 Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com> * fix(auth): name persist landing #158 instead of superseded #147 Identity persist/reload landing moved to #158. Keep the command gate honest about supplied records and stop pinning the leftover #147 pointer. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com> * fix(auth): drop closed #158 persist landing and loaded names Name persist/reload as Target, forbid the closed pointer, and call command-test records supplied. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com> * docs(traceability): name honesty successor Active PR #225 Record the opened successor so architecture views do not leave the command-auth honesty slice labeled as closed #159. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com> * fix(auth): keep anonymous authorization after rebase onto main Preserve account-link and anonymous-credential modules beside the session-command authorization entry point so this honesty head stays mergeable without claiming participant persist on this branch. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com> * docs(traceability): drop merged Active PR leftovers after rebase After rebasing onto 0c695b9, exclusive outbox leases, observation clocks/membership, and claim-next scoring-job poll are protected-main truth. Keep #225 as the Active PR for supplied-record anonymous command authorization. Persist/reload of assessment_participant remains Target. Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com> --------- Co-authored-by: Seongho Bae <me@seonghobae.me> Co-authored-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>


Superseded
This command-record store-load honesty slice is fully contained in #159. Do not merge this predecessor.
Fresh ancestry evidence immediately before closure:
858b628f52f374be012864595a32b42b1220b3e65ee49d86b858079cb83fcd5fe6a88932cb56395d#159 retains the as-built supplied-record disclaimer, removes remaining misleading load wording, and updates active persistence-lane pointers. #159 remains Draft and subject to exact-head CI/security/review gates. Closing this PR does not promote successor behavior to protected-main truth.