-
Notifications
You must be signed in to change notification settings - Fork 0
fix(agents): bind reads to route and session lifetimes #3338
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
Draft
Chris0Jeky
wants to merge
9
commits into
main
Choose a base branch
from
audit/3337-agent-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.
+621
−33
Draft
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
ae52930
test(agents): pin read and session ownership
Chris0Jeky 45a5020
fix(agents): bind reads to route and session lifetimes
Chris0Jeky cff0fda
docs(agents): record request ownership evidence
Chris0Jeky 7b6e137
test(agents): preserve loaded data across token refresh
Chris0Jeky b782870
fix(agents): preserve loaded data across token refresh
Chris0Jeky c483461
docs(agents): distinguish token rotation from identity reset
Chris0Jeky 11ab874
test(agents): retry empty initial reads after token refresh
Chris0Jeky c6a88e7
fix(agents): retry empty active reads after token refresh
Chris0Jeky a2c9b57
docs(agents): record empty-read retry contract
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,53 @@ | ||
| # Agent store request and session ownership | ||
|
|
||
| Status: draft PR #3338, 2026-09-21. Base: `307c3b8b50bec1cb0bfaea3e570a942bcb1d4451`. | ||
|
|
||
| ## Reproduced defects | ||
|
|
||
| `agentStore` previously let every profile, run-list and run-detail response write its shared surface. Route-clear helpers changed visible values but did not invalidate requests. The store also had no session lifetime, so old-account work could settle after logout/login, including login as the same user ID. | ||
|
|
||
| This admitted reverse-settling reads, A-old → B → A-new route reuse, late settlement after route clear, stale error/toast state, false loading clears, and old-session repopulation. | ||
|
|
||
| Independent review then exposed two token-refresh boundaries: | ||
|
|
||
| 1. treating a successful same-user refresh as full identity replacement cleared already loaded agent data; | ||
| 2. preserving settled data alone still stranded an empty first-load route because the old request was invalidated and the unchanged route did not remount or refetch. | ||
|
|
||
| ## Contract | ||
|
|
||
| Profiles, run lists and run details have independent owner lanes. Each owner carries the current session epoch and a unique request token. A newer request retires only the previous owner in its lane. Route-clear helpers invalidate their own lane before clearing visible state. | ||
|
|
||
| User identity, authenticated state and demo-session replacement synchronously advance the epoch, retire all owners, and clear every agent surface, error and loading indicator. | ||
|
|
||
| A token-only rotation: | ||
|
|
||
| - preserves already loaded profiles, runs and detail; | ||
| - retires old-token owners and stale success/failure/toast/loading settlement; | ||
| - restarts only active lanes whose visible surface is still empty; | ||
| - preserves the exact agent/run parameters captured by the active read; | ||
| - never replays a mutation. | ||
|
|
||
| Independent lanes remain concurrent. Demo mode retains its no-network behavior. No API, DTO, route, schema, dependency or backend behavior changes. | ||
|
|
||
| ## Test-first evidence | ||
|
|
||
| Initial test-only head `ae52930c6eb5d5b80a2f6a7347242f4ad60a0036` ran the full frontend suite on Ubuntu and Windows. Both platform jobs passed lint, typecheck, production build and PWA validation, then failed in the new real Pinia suite. Ubuntu JUnit recorded **7,159 tests, 8 failures, 0 errors**, all in the intended ownership schedules. | ||
|
|
||
| Review-regression head `7b6e137d9625ee6b2ba6ad747a4fdecc5fabe172` added the loaded-data refresh schedule. Ubuntu again passed lint, typecheck, build and PWA validation; all ten ownership cases ran and only the new preservation case failed. | ||
|
|
||
| The first corrected head `c48346128982366c0abdf4f1f766246f5cc351dc` then passed Smart CI, Extended and the complete Required CI matrix. Repeat Codex review found the empty-first-load residual described above. | ||
|
|
||
| Test-only head `11ab87461ed4773b99af8e35a6625873a52e2425` adds one deferred real-Pinia schedule spanning profiles, runs and detail. A dependency-free runner transpiled and executed the actual production module: | ||
|
|
||
| - before the retry correction: each API was called once and all three loading flags became false after rotation; | ||
| - after the correction: each API was called twice, old-token settlement was suppressed, and fresh-token results populated all three lanes. | ||
|
|
||
| Hosted qualification for the final correction remains authoritative; the supplemental runner does not replace it. | ||
|
|
||
| ## Remaining gates | ||
|
|
||
| Current production correction: `c6a88e78cc9a306992dd95ae28569fb575c4e286` 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 are required. Review should focus on retry capture, route-clear cancellation, no mutation replay, and avoiding refresh loops. | ||
|
|
||
| This is client-state integrity, not a claim of server-side authorization bypass or transport cancellation. 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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When Extend Session completes while an Agent route's initial read is still pending, this watcher removes that request's ownership and turns off loading; its eventual result is then ignored, but
AgentsView,AgentRunsView, andAgentRunDetailViewdo not issue another read until mount or a route-parameter change, so the unchanged route displays a false empty/blank state. Fresh evidence in the corrected head is that the new refresh regression seeds every surface withexistingdata before rotating the token, leaving the first-load-empty case uncovered. Preserve same-user in-flight reads or restart them under the new token.AGENTS.md reference: frontend/AGENTS.md:L6-L7
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Confirmed and corrected. Test-only head
11ab874adds a deferred real-Pinia schedule that starts empty profile, run-list, and run-detail reads, rotates the token for the same user, and requires all three lanes to restart under the new token while old settlements remain suppressed.A bounded runner transpiled and executed the actual production module: before correction each API was called once and loading dropped false after rotation; current source retries each empty active lane, preserves exact run/detail parameters, suppresses old settlement, and installs fresh-token results. Exact final head is
a2c9b57; hosted Self-Test, Extended, Required CI, and repeat review are still pending, so the PR remains draft and this thread remains open.