Skip to content

fix(board): isolate mutation settlements across logout - #3358

Open
Chris0Jeky wants to merge 4 commits into
mainfrom
codex/3306-session-mutations
Open

Chris0Jeky wants to merge 4 commits into
mainfrom
codex/3306-session-mutations

Conversation

@Chris0Jeky

@Chris0Jeky Chris0Jeky commented Sep 22, 2026

Copy link
Copy Markdown
Owner

Logout can clear the board store while an older board/card/label/comment request is still in flight. Its settlement could repopulate account A's data in account B's store or overwrite B's loading/error state. A queued label write or a board-creation screen could also start follow-up requests under B's credentials.

Capture the existing shared session generation before transport and suppress retired client effects after awaits. Cover board CRUD, card CRUD/move/archive/restore, label and comment mutations, direct read publication, queued label transport, and recovery reads. Both board-creation screens also check session ownership before routing, applying starter packs, or changing workspace summaries. Submitted store requests retain their original result/error; this does not undo server writes. Same-session loading arbitration remains #3305.

Closes #3306.

Parent #3315 landed at 346b3c756875f131fdf83191d218427e50277021. This PR now targets main at head 21776efd83ddc5dce05fd33c0a58aa145750186b. The base merge changes no tracked content, and the review diff against main is byte-identical to the reviewed parent-relative diff. Required CI is being requalified for this head and base. Source ordering PRs #3304/#3312 remain separate and must reconcile these guards before integration.

Validation at 36b98d2b23e7de9a00cd7e7388e9dff5075d84e4:

  • 59 deferred real-Pinia session regressions plus five caller regressions. Initial store proof had 39 failures before the fix; caller proof had five failures before its fix. Final focused run: 91 passed.
  • npx vitest --run --maxWorkers=2: 517 files, 7,426 passed, three existing skips.
  • npm run build (includes typecheck), npm run lint: pass, 11 existing lint warnings.
  • Two Chromium flows pass: blank workspace to first board/card, and Today workspace setup with a starter pack.
  • node scripts/check-docs-governance.mjs and node scripts/check-doc-links.mjs: pass, zero broken links, three existing masking warnings.
  • Fresh production review and the bounded second pass on the caller fix found no HIGH/CRITICAL or nonblocking findings. Hosted required CI remains a merge gate.

The new source lines move the mutation-smoke target from line 667 to 673. The contract and its companion test now identify the same unchanged 50-character expression and columns. node --test scripts/ci/smart-ci/mutation-smoke-contract.test.mjs passes all five tests; the full Smart CI self-test set passes all 608. A separate coordinate review found no issues. Because this touches scripts/ci/smart-ci/mutation-smoke-contract.test.mjs, ADR-0066 requires the maintainer's own review before merge; independent review and CI do not supply that approval.

STATUS records the client boundary. OUTSTANDING_TASKS J.2 records the maintainer-review gate; its 42 human-action rows remain unchecked. Runtime evidence is local under .worktrees/codex-3306-session-mutations/.runtime and will be archived before cleanup.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 22, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-22T18:53:36.910113Z e2fea70 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@Chris0Jeky

Copy link
Copy Markdown
Owner Author

Independent review completed for e2fea70 against parent 7ed5732: no introduced HIGH/CRITICAL blockers or actionable nonblockers. The reviewer inspected stale cache/count/selection/read-epoch publication, error/toast/loading settlement, queued label transport, recovery reads, archive/delete refreshes and caller outcomes. Root owns the executed tests recorded in the PR body.

Bounded Luna test audit disposition: the archive/restore coverage concern is declined because the next-account cases install matching currentBoard/card IDs before settlement; stale archive removes B's card and stale restore replaces it, so the snapshot and no-recovery-GET assertions detect a missing guard. Provenance's successful return remains its existing caller contract; the changed boundary suppresses stale store error/toast effects and does not introduce caller lifetime behavior. No additional fix commit is warranted for either concern.

Remaining: parent #3315 must land, then this PR must be retargeted and its required CI requalified. #3305 and source ordering #3312/#3304 remain separate.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e2fea70d7b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread frontend/taskdeck-web/src/store/board/boardCrudStore.ts
@Chris0Jeky

Copy link
Copy Markdown
Owner Author

Triage of comment 4075257293: confirmed correctness/session-ownership blocker. Although the fulfilled value contract pre-existed, suppressing store commits alone does not finish the #3306 account-switch path: both board-creation callers can continue into global navigation or starter-pack transport and workspace summary invalidation after their session retires.

The first production fix round will preserve original store results/errors and expose the existing shared session capture to the two callers. Each will gate follow-up effects; setup will also recheck after catalog/apply awaits so a switch during the starter-pack phase cannot cross credentials or publish to the next session. Deferred caller regressions will prove the pre-fix failure and the corrected behavior. The PR is not merge eligible while this finding is unresolved.

Separately, CI found a stale mutation-smoke source coordinate. bc543fb moves its contract/companion test range from667 to673 without changing the target expression or column bounds;5contracttests and608SmartCIselftests pass locally. The scripts/ci test-data touch falls under the repository's ADR-0066 maintainer-review gate, so fresh independent review and green CI alone will not authorize merge.

@Chris0Jeky

Copy link
Copy Markdown
Owner Author

Estate ops — merge blocker (eng supervisor bot) — 2026-09-23

GitHub reports CONFLICTING against current base. Human rebase/retarget gate — this bot does not merge or push.

CI / correctness asks after rebase

  1. Re-resolve against parent fix(board): preserve column and assignment save ownership #3315 / current main; re-run Frontend Unit (ubuntu+windows) + E2E Smoke on the rebased head only.
  2. Preserve the session-generation suppress-after-await invariant across board/card/label/comment + both board-creation screens — conflict resolution often drops one store path.
  3. Same-session loading arbitration remains Board store needs operation-owned loading state instead of one shared Boolean #3305 — don’t “fix” conflicts by inlining Board store needs operation-owned loading state instead of one shared Boolean #3305 scope here.

UXQA cross-link (no reseeding)

Logout/session bleed is eng correctness, not a new UX session finding. Broader workspace UX stays on #2901 and ledger #2898. Product stage/#3181 already merged — no product sequencing commentary from this lane.

No merge from this bot.

Copy link
Copy Markdown
Owner Author

DevSecOps Supply Scout — session-trust advisory (2026-09-23 ~02:30 BST)

Live re-check: still DIRTY/CONFLICTING (mergeable=false); exact-head checks are green (0 fail). Estate eng already owns the rebase ask — this adds pattern evidence + the ADR gate so conflict resolution does not drop a store path.

Must preserve on rebase

  1. Session-generation capture before transport + suppress-after-await on every board/card/label/comment settlement path touched here.
  2. Both board-creation callers (incl. WorkspaceSetupModal) re-check ownership after awaits before navigate / starter-pack / workspace summary writes.
  3. Do not pull Board store needs operation-owned loading state instead of one shared Boolean #3305 same-session loading arbitration into the conflict fix.

External class (why this is P0 session trust)

Stale in-flight settlements rewriting client state after logout/switch is a known SPA race class (Vanta session race; cookie restore after logout — Turbo CVE-2025-66803 / GHSA-qppm-g56g-fpvp). Generation-token suppression matches the durable fix shape.

Maintainer gate

Touches scripts/ci/smart-ci/mutation-smoke-contract.test.mjsADR-0066 still requires Chris’s own review after rebase + FE Unit/E2E green. Independent review/CI alone do not authorize merge.

No merge from this scout. Pack: /workspace/handoffs/devsecops-scavenge-2026-09-23/.

@Chris0Jeky Chris0Jeky left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Coordinator verification: session-guard logic correct; blocked on conflicts plus the declared maintainer control-path review. The PR extends the existing on-main boardMutationSessionGeneration mechanism (already proven by columnStore visit guards) to all board/card/comment/label reads and mutations plus both create-board callers: stale continuations still settle for their callers but cannot touch new-session state, routing, summaries, or notifications. The Codex P2 on retired create results is fixed in-PR via the facade captureSession closure with gates between every await in workspace setup. Contract move 667 to 673 plus companion assertion is self-consistent and the green smart-ci contract test independently proves the coordinates; the J-row disclosure matches exactly. Existing-spec edits remove zero assertions. Blockers: CONFLICTING merge state on main, and the control-path touch needs the maintainer review its own J-row declares under ADR-0066 (this verification is not that approval). Required path: update-branch, resolve conflicts, requalify full CI, then maintainer review. Children #3359/#3360 retarget after this lands.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Review

Development

Successfully merging this pull request may close these issues.

In-flight board mutations can repopulate cleared state after logout

1 participant