Skip to content

feat(identity): bind account capability to current link event - #222

Closed
seonghobae wants to merge 24 commits into
mainfrom
cursor/bc-221d9e35-a7f3-457b-9833-f5444c4aa5dd-4a31
Closed

seonghobae wants to merge 24 commits into
mainfrom
cursor/bc-221d9e35-a7f3-457b-9833-f5444c4aa5dd-4a31

Conversation

@seonghobae

Copy link
Copy Markdown
Contributor

Why

PR #206 ends a matching current Keyverse binding and makes later recover return None. A buyer who already recovered that participant still held a participant_ref that could be treated as an account grant after unlink or rebound. Assessment sessions stay on the stable participant; only account-linked capability must die with the current link_event_ref.

TDD

RED grant_account_linked_capability and accept_account_linked_capability were missing. GREEN grants a capability bound to the current link event, accepts it only while that binding still matches, rejects the grant after unlink or rebound, and fails closed on expired, unknown-time, or foreign-tenant proofs.

Scope

Out of scope

  • HTTP account-link transport / OpenAPI
  • Live Keyverse token verification
  • Invalidating anonymous assessment sessions (they stay on participant_ref)

Operator next action

Review the link-event-bound account capability. Prefer #206 for persist unlink. Do not merge #206, #176, #160, #147, #133, #124, or #114 as substitutes for this grant/accept gate. Do not merge this PR until exact-head checks and independent last-push approval are satisfied. Never self-approve.

cursoragent and others added 22 commits August 16, 2026 15:25
A buyer who links an anonymous assessment to a Keyverse account must
still see that link after process restart. Persist assessment_participant
plus append-only link and link-end evidence, reload through the domain
lifecycle, and fail closed on conflicting replay or a subject already
bound to another participant.

Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Keep TRACEABILITY, ADR-0020, ERD, and as-built schema pointing at the
opened persist/reload vehicle instead of an unnamed Active PR.

Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
The Active PR #114 naming commit stored an empty ADR-0020. Restore the
accepted decision, including the #114 persistence status and APA 7
references, so identity-link governance is not silently deleted.

Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Apply each identity link and then its matching ends in one transaction so a complete in-memory unlink+relink aggregate survives restart. Cover one-shot persist, exact replay, and subject reuse after unlink.

Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Add a tenant-scoped current-subject lookup so a returning Keyverse login can find the same product-owned participant after the anonymous session token is gone. Ended or replaced subjects stay unfindable until they are current again.

Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Renumber the identity-link migration so it does not collide with #113 scoring-job health indexes on 0021. Name Active PR #124 as the merge candidate over #114.

Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Remove the accidentally committed build tree and ignore /target so later local verification cannot leak compiler outputs into the identity-link successor.

Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
A missing current_participant_identity_link row no longer hides a
returning Keyverse login or lets another participant bind the same
issuer-scoped subject. Lookup and uniqueness now read append-only
link rows that have no matching end.

Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Name the Active PR vehicle as the successor of #124 so TRACEABILITY,
ADR-0020, and the as-built schema do not treat projection-only lookup
as the landing contract.

Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Add a composite foreign key so a link-end or current projection cannot
point at another participant's identity-link row. Name Active PR #133
as the landing vehicle over #124 and #114.

Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Exact replay of the same identity-link history now reconciles the derived
current projection so operator repair cannot hide a returning login behind
a missing unique enforcer or leave a stale row after unlink. Name Active
PR #133 in TRACEABILITY instead of superseded #124.

Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Point TRACEABILITY, ADR-0020, ERD, and the as-built schema at this
successor so operators do not merge superseded #133, #124, or #114.

Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
A buyer who proves control of both the anonymous session and a Keyverse
account can persist that link and later recover the same product-owned
participant from a still-valid account proof. Expired proofs fail before
persist or lookup.

Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Point TRACEABILITY, ADR-0020, UML, and the as-built schema at the hosted
dual-proof persist/recover commands so operators do not treat persist-only
#147 as the last identity-link landing vehicle.

Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Point TRACEABILITY, ADR-0020, ERD, and the as-built schema at this
successor so operators do not merge superseded #147, #133, #124, or #114.

Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
#158 rebuilds current projections after restore. #160 adds dual-proof
write/recover commands. They share persist files, so merge them
sequentially after rebase instead of treating either as a replacement.

Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
A still-valid account proof must not receive a participant whose current
tenant, issuer, or subject no longer match that proof. Keep the loaded
record only when the current binding still matches, and cover expired,
other-tenant, and ended-subject recover paths.

Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Keep TRACEABILITY, ADR-0020, ERD, and the as-built schema pointing at
the opened recover current-binding successor instead of an unnamed
#160 follow-up.

Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Add hosted unlink so a still-valid Keyverse proof can end the matching
current binding. Reload stored history before authorization so a stale
in-memory record cannot unlink a rebound subject. Exact replay is
idempotent; expired proofs and unused accounts fail closed.

Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Record #206 as the write/recover/unlink landing over #176. Keep #202 as
the inspect-line unlink vehicle and #158 as restore reconcile.

Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
Unlink already stops recover from returning the participant. A previously
recovered participant_ref could still be treated as an account grant.
Bind that grant to the current link_event_ref and re-check it so unlink
or rebound fails closed.

Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
@coderabbitai

coderabbitai Bot commented Aug 16, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 0bff2147-8820-460b-a5d4-85dca3a5a027

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

cursoragent and others added 2 commits August 16, 2026 16:47
Record the post-recover grant/accept gate as Active PR #222 so
traceability and ADR-0020 keep persist unlink (#206) distinct from
link-event-bound account capability.

Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>
A grant issued against a stored current binding must fail closed after
persist_authorized_account_unlink, matching recover returning None.

Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assessment

Unique slice on c3531c7 is SOUND for the grant/accept gate. grant_account_linked_capability binds the grant to the current link_event_ref. accept_account_linked_capability re-checks proof expiry, unknown time, foreign-tenant proof, and current participant/tenant/issuer/subject/link_event_ref. Unlink or rebound fails closed. Anonymous assessment sessions stay on participant_ref. No public constructor can forge AccountLinkedCapability.

Queue

Prefer #236 a667395 for the unique event-bind proof: same-subject relink under a new link_event_ref must reject the ended grant, including accept against load_participant_identity_history. Prefer #222 for the grant/accept introduction if #236 is not the landing vehicle. Prefer #206 for persist unlink. Keep #202/#210 inspect-line. Keep #158 restore.

Do not merge #215 over this head. That HTTP recover path does not call accept_account_linked_capability and still races persist files.

Next after check-clean

HTTP account-link transport (OpenAPI 3.2.x, RFC 9457) must reload current history in the same transaction as the privileged command, then call accept_account_linked_capability. Do not fold live Keyverse verification into that slice. Do not invalidate anonymous sessions on unlink.

Do not merge until exact-head checks and independent last-push approval are satisfied. Never self-approve.

View PR

Open in Web View Automation 

Sent by Cursor Automation: Fix Issues

cursor Bot pushed a commit that referenced this pull request Aug 16, 2026
Keep #222 as the grant/accept gate and name #236 as the same-subject
relink proof so operators land the unique link-event invariant.

Co-authored-by: Seongho Bae <seonghobae@users.noreply.github.com>

Copy link
Copy Markdown
Contributor Author

Closing as superseded, not merged. Fresh ancestry proof shows #236 head 2d4676e7 is an exact descendant of this head c3531c7c (ahead_by=2, behind_by=0). #236 preserves the link-event-bound grant/accept gate and adds the same-subject unlink→relink proof that prevents an ended capability from surviving a new event, so keeping #222 open would duplicate the same landing lineage.

@seonghobae seonghobae closed this Aug 16, 2026
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