fix(web): closing Settings or Usage no longer jumps back to a quote's source#29013

merged5
main
fix/issue-29002
opened2d agobyJJulius Marminge
View on GitHubTwo-way sync enabledPR last imported 10h ago

Problem

After Go to source on a quote, the thread URL keeps #assistant-citation=…. Closing Settings or Usage, or pressing the sidebar Back button on Pull requests, then scrolls the thread back to the quote's source, even after the user has scrolled away. To reproduce: Go to source on a sent quote, scroll to the end of the thread, open Usage, and press Esc. The thread jumps back up to the source.

Change

The return location for Settings, Usage, and the sidebar utility pages is recorded in mainAppLocation.ts, and that record kept the full href, citation hash included. Returning navigated to it as a new history entry, and the thread treated the restored hash as a new Go to source. The tracker now records the href without a leading #assistant-citation= fragment, using withoutAssistantCitationHash from assistantCitationNavigation.ts, where the hash prefix already lives. The path, the search, and any other hash are kept. Go to source itself, shared citation links, and reloads are unchanged.

Scope and approval

Fixes pingdotgg/t3code#29002

Verification

  • mainAppLocation.browser.test.tsx (new) goes to the thread through assistantCitationNavigation, then leaves through Usage (close) and Pull requests (sidebar Back). It fails on main because both return hrefs keep #assistant-citation=…. It also fails when only the Settings/Usage return is fixed and not the sidebar Back. It passes with this change. assistantCitationNavigation.test.ts still passes, and vp run check:changed passes.
  • Runtime check in the web dev server (fresh database, Replay (dev) provider, Chromium 1280×800, a thread of about 20 turns with one quoted message). The values are the timeline scroller's scrollTop against its maximum:
StepBefore (main 05c0ed7da6)After (this branch)
Go to source0, URL gains #assistant-citation=0, URL gains #assistant-citation=
Scroll back to the end1971 of 1971, hash kept1971 of 1971, hash kept
Open Usage, close with Esc0 of 1971 (back at the source)1971 of 1971, no hash
Go to source, end, open Settings, close with Esc18 of 19711971 of 1971, no hash
Go to source, end, Pull requests, sidebar Back0 of 20562084 of 2084 (end), no hash
Go to source again after a return0, the source is revealed
No-hash control: Usage open, then close2084 of 2084
#proof-anchor control: Settings close, then Pull requests Backat the end both times, #proof-anchor kept
  • Not checked: before/after recordings are not attached. Desktop (Electron hash history) was not run; it uses the same tracker, and reading TanStack's hash history shows that location.href has the same path#hash shape there. Pressing Esc on Pull requests and the navigation.back shortcut use browser history rather than this saved location, and this change does not touch them.

Triaged, fixed and reviewed by Claude Opus 5.5 (Claude Code) with GPT-6.1 Sol (Codex) reviews, running the T3 Code issue flow.

🤖 Generated with Claude Code

Takeover

No code changes; evidence and verification added below. The "Not checked: before/after recordings are not attached" and "Desktop was not run" lines above are now covered: before/after recordings for every return path are below, and a real Electron run is included (P1).

Evidence

Before dd6c05ec31 (merge-base) · After 77041abe04 (head). Environment: real web app from each checkout, fresh database per side (T3CODE_DEV_SEED=0), the same synthetic Replay (dev) thread of about 20 turns with one sent quote, driven through the app's own controls. Playwright 1.60.0 / Chromium 148, Linux, 1280×800 (R4 390×844), dark, DPR 1, 100% scale, reduced motion, fixed clock. Diff0 = absolute RGB delta ×16; DiffT32 = channel delta > 32/255. Each step is narrated with its timestamp in the narrated index; the fixture matrix lists the rows.

Scroll values are the timeline scroller's scrollTop / max after returning, with the user scrolled back to the end after Go to source:

Row · 1280×800 · darkBeforeAfter
R1 Usage → Eschash kept, 0 / 3040 (back at source)no hash, 3040 / 3040
R2 Settings → Appearance → closehash kept, jumps to sourceno hash, 3040 / 3040
R3 Pull requests → sidebar Backhash kept, jumps to sourceno hash, 3040 / 3040
R7 Go to source again after the returnsource revealedhash restored, source revealed at 0

Recordings, before · after: R1 + R7 before · after; R2 before · after; R3 before · after.

Controls, head only (after 77041abe04):

RowResultCapture
R4 390×844, sidebar sheet → Usage close and Pull requests → Backboth return to the end, no hash, 3670 / 3670sheet · recording
R5 thread with no hash, both returnsordinary URL kept, end 1108 / 1108sheet · recording
R6 ?proof=return#proof-anchor, both returnssearch and unrelated hash kept, end 1108 / 1108sheet · recording
R2-extra command palette, backdrop, project settings closeonly the citation hash removed, end keptsheet · recording
R3-extra Usage opened over Pull requestsreturns to the exact /pull-requests?…&q=… URL, then Back returns to the thread endsheet · recording
P1 real Electron 44.10 (hash history), Usage Esc and Pull requests Backboth remove only the citation fragment, end 2864 / 2864sheet · recording

What else changed between Before and After: the transcript position (source versus end) and with it the quote chips, timeline markers and the composer's translucent blur over different content; the diagnostic overlay text; synthetic message timestamps from separate seeds. Header, sidebar and utility panels outside the overlay have zero changed pixels at zero threshold. No other product change.

Scripts (uploaded, not committed): seed · driver · additional driver · rebuild wrapper · all scripts · pixel stats.

Verification log
  • Mode: evidence only, no code changes; head 77041abe04 unchanged.
  • Proof audit (GPT-6.1 Sol, Codex): pass 1 derived the matrix (R1–R7 runtime rows, B1/B2 code-mapped branches, P1 Electron supplemental, P2 not applicable). Pass 2 rounds: round 1 INSUFFICIENT (R2–R6: overlay covered R4 controls, loading skeletons in review frames, early narration); round 2 INSUFFICIENT (overlay labels a step behind, R4 overlay over quote text, clipped R3-extra URL, missing SHA labels); round 3 SUFFICIENT on every row after the recaptures and retiming.
  • An independent rebuild of R1 at the head matched the delivered capture with zero product pixels changed (30 pixels differ, all in the overlay's elapsed-time digit).
  • Not exercised: direct citation links and reloads (the change does not touch them), and artificial empty or malformed citation hashes (code-mapped only).
  • Tests: unchanged from the PR (mainAppLocation.browser.test.tsx, assistantCitationNavigation.test.ts).
  • CI: 41/41 checks green on 77041abe04; no conflicts with current main.
  • Evidence by GPT-6.1 Sol (Codex) step agents; lead Claude Opus 5.5 (Claude Code), in T3 Code.

Checks

21 successful · 19 skipped
All checks passed
c63f0ff

Added 4 commits

  • Merge remote-tracking branch 'origin/main' into fix/issue-2900277041ab
  • fix(web): closing Settings or Usage no longer reopens the last quote source8e6567b
  • test(web): reproduce #29002 citation hash replayed by return navigationbd86a51
  • test(web): reopen the quote source before each return in the #29002 testc6bf28c
Synced from GitHub

Approvability

Verdict: Approved at 77041ab

Macroscope's review found this PR approvable — Saved return links now drop citation fragments so closing Settings or Usage, or returning from sidebar utility pages, does not jump back to a quote’s source. The change is confined to client-side navigation and preserves other URL state.

No code changes detected at c63f0ff. Prior analysis still applies.

You can add or adjust custom eligibility rules. Learn more.

[gpt-6.1-sol][Codex] on behalf of shivam.

Issue-watch handoff for https://github.com/pingdotgg/t3code/issues/29002: this automation thread found your PR during its initial ownership check, at head 77041abe0468bbb5b91c485bafb5a6df1b26385f. I read the issue and PR, but started no reproduction, tests, or implementation. Your PR records coverage for Usage, Settings, and sidebar Back; desktop verification remains unverified in its description. Leaving the fix and testing with you and settling the duplicate automation thread.

Synced from GitHub

Review in Change Stack →

No actionable comments were generated in the recent review.

Walkthrough

The return-location tracker now removes assistant citation hashes before saving URLs for Usage, Settings, and sidebar utility pages. Browser tests check that returning from Usage and Pull requests leads to the thread path without the citation hash.

Changes: Assistant citation return locations

Layer / File(s)Summary
Strip citation hashes and verify return navigation
apps/web/src/lib/assistantCitationNavigation.ts, apps/web/src/components/sidebar/mainAppLocation.ts, apps/web/src/components/sidebar/mainAppLocation.browser.test.tsx
A new helper removes assistant-citation hashes from URLs. The tracker uses it when saving return locations. Browser tests check return navigation from Usage and Pull requests.

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Medium

Merge Risk: External image Minimal · up to 77041

No actionable merge-blocking risk was identified in the reviewed change.

Pre-merge checks: Passed 4
Check nameStatusExplanation
Title checkPassedThe title clearly and concisely describes the primary fix: preventing Settings or Usage from returning to a quote source.
Linked Issues checkPassedIssue [#29002] requires the saved return location to avoid replaying a stale #assistant-citation= hash. startMainAppLocationTracking now applies withoutAssistantCitationHash before saving modal …
Out of Scope Changes checkPassedThe changed production code and the new browser test directly support issue [#29002]. The helper centralizes the hash removal used by the return-location tracker. The test covers both the modal close …
Description checkPassedThe pull request description includes the required Problem, Change, Scope and approval, and Verification sections. It explains the bug, implementation, linked issue, focused tests, runtime checks, lim…
Full details: Linked Issues check

Explanation

Issue [#29002] requires the saved return location to avoid replaying a stale #assistant-citation= hash. startMainAppLocationTracking now applies withoutAssistantCitationHash before saving modal and sidebar return URLs. The helper leaves URLs without that prefix unchanged. The new browser test covers return from Usage and Pull requests after citation navigation and expects the thread path without the citation hash. The change does not alter Go to source navigation.

Full details: Out of Scope Changes check

Explanation

The changed production code and the new browser test directly support issue [#29002]. The helper centralizes the hash removal used by the return-location tracker. The test covers both the modal close path and the sidebar Back path described by the issue and PR.

Full details: Description check

Explanation

The pull request description includes the required Problem, Change, Scope and approval, and Verification sections. It explains the bug, implementation, linked issue, focused tests, runtime checks, limitations, screenshots, recordings, and agent details.

Finishing Touches
Generate docstrings
  • Commit to this branch
  • Create a new PR
Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

CodeRabbit Verify

  • Run CodeRabbit Verify to test the changes in this pull request.
External image Recent review info
External image Run configuration
External image Commits

Reviewing files that changed from the base of the PR and between dd6c05ec313c6c870c7a7688e87143da5084031d and 77041abe0468bbb5b91c485bafb5a6df1b26385f.

External image Files selected for processing: 3
  • apps/web/src/components/sidebar/mainAppLocation.browser.test.tsx
  • apps/web/src/components/sidebar/mainAppLocation.ts
  • apps/web/src/lib/assistantCitationNavigation.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 8 remain after this review.

Added 1 commit

  • Merge branch 'main' into fix/issue-29002c63f0ff