-
Notifications
You must be signed in to change notification settings - Fork 0
fix(permissions): keep board-access reads behind confirmed writes #3330
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Chris0Jeky
wants to merge
17
commits into
main
Choose a base branch
from
audit/3328-permission-read-ownership
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
f963ae5
test(permissions): reproduce read and session races
Chris0Jeky 457c259
fix(permissions): bind access state to reads and sessions
Chris0Jeky 72c1de9
fix(permissions): deduplicate grant settlement by stable id
Chris0Jeky ed3ffbc
test(permissions): pin grant settlement deduplication
Chris0Jeky 421122b
test(permissions): invalidate operations on token rotation
Chris0Jeky fa4ee41
fix(permissions): invalidate ownership on token rotation
Chris0Jeky 3b275ee
test(permissions): preserve access cache across token refresh
Chris0Jeky e00f5d6
fix(permissions): preserve access cache across token refresh
Chris0Jeky 5a86d81
docs(permissions): preserve access cache on token refresh
Chris0Jeky 2676cce
test(permissions): retry unresolved access read after token refresh
Chris0Jeky 1bfe9b7
fix(permissions): retry unresolved reads after token refresh
Chris0Jeky eb70563
docs(permissions): record unresolved-read retry contract
Chris0Jeky dc66fd7
fix(permissions): reconcile stale mutations after refresh
Chris0Jeky 00a9bf0
fix(permissions): reconcile stale mutations after active reads
Chris0Jeky a6fd963
fix(permissions): retry reconciliation after token rotation
Chris0Jeky 0f9cad1
fix: retry cached permissions after token refresh
Chris0Jeky 112585b
Separate token refresh from re-login ownership
Chris0Jeky File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| # Board-access read and session ownership | ||
|
|
||
| Status: draft PR #3330, 2026-09-21. Base: `307c3b8b50bec1cb0bfaea3e570a942bcb1d4451`. | ||
|
|
||
| ## Reproduced defects | ||
|
|
||
| A board-access read could settle after a confirmed grant, update or revoke and replace newer client state. Same-board reads were last-response-wins, one shared loading Boolean could clear while other boards still loaded, and pending reads or mutations retained permission to publish after account replacement. | ||
|
|
||
| The first lifecycle correction treated every token refresh as a full cache reset and could blank an unchanged Board Access route. The preservation correction then exposed a second boundary: when refresh happened during an unresolved first read, the old owner was retired but the unchanged board route did not refetch. | ||
|
|
||
| ## Contract | ||
|
|
||
| - One read owner exists per board; unrelated boards remain concurrent. | ||
| - A successful mutation advances that board's generation and retires older reads. | ||
| - User identity, authentication or demo-session replacement advances the epoch, clears cached access, retires operations and resets loading/error. | ||
| - Token-only rotation preserves settled board caches, suppresses old-token UI settlement and restarts only active board reads that do not yet have a cache entry. | ||
| - An empty array is a settled authoritative cache and is not retried merely because it is empty. | ||
| - The retry retains the exact board ID captured by the active read. | ||
| - Success, failure, toast and cache writes require the initiating lifecycle epoch. | ||
| - Loading is derived from current operation tokens, not whichever call settles. | ||
| - Grant, update and revoke mutations are never replayed. | ||
|
|
||
| Server authorization remains authoritative. This corrects truthful client cache behavior and does not claim a server-side authorization bypass. Same-entry mutation serialization remains in stacked PR #3335. | ||
|
|
||
| ## Test-first evidence | ||
|
|
||
| The original ownership suite covers read-versus-grant/update/revoke races, reverse reads, independent loading, same-user logout/login, replacement-session mutation settlement, stale failures and stable-ID grant deduplication. | ||
|
|
||
| Review-regression head `6bbf8d04139bef2dca91d290b910e1c07a8e76aa` ran canonical Node 24 frontend qualification on Ubuntu and Windows. Lint, typecheck, production build and PWA validation passed on both platforms. Ubuntu JUnit recorded **7,161 tests, exactly 2 failures, 0 errors**, both loaded-cache preservation cases. | ||
|
|
||
| Issue #3352 added test-only head `d28697ede737ec42ae3e696c7a7cedcb753de347`, covering token rotation while `board-1` has an unresolved first read and no cache entry. A dependency-free runner transpiled and executed the actual production module: | ||
|
|
||
| - before the retry correction: `getAccess` was called once and loading became false after rotation; | ||
| - after the correction: `getAccess` was called twice for the same board, old-token settlement was suppressed and the fresh-token result populated the cache. | ||
|
|
||
| Hosted exact-head qualification remains authoritative; the supplemental runner does not replace it. | ||
|
|
||
| ## Remaining gates | ||
|
|
||
| Current production correction: `3c7746ee0330406a4e6b84c1a5bc253b02a7aa08` before this documentation commit. | ||
|
|
||
| Exact final-head lint, typecheck, production build, complete Vitest on Ubuntu and Windows, Required CI, Extended, Self-Test and repeat independent review remain required. Stacked mutation-order PR #3335 must later be reconciled to this corrected parent and requalified. | ||
|
|
||
| No merge, release or deployment qualification is claimed. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.