Proof audit, pass 1 — [#32548](https://git.cafe/pingdotgg/t3code/pull/32548), also [#32548](https://github.com/pingdotgg/t3code/pull/32548)

Reviewed head [e4601a1](https://github.com/pingdotgg/t3code/commit/e4601a1cc864e6fc7f5971cc89108437335c3a18), source branch `fix/pr-comment-link-focus`, against supplied main merge-base [ac5e48c](https://github.com/pingdotgg/t3code/commit/ac5e48c612061895511f549d363a2186a6a005ea). The supplied worktree's local branch is `pr-32548`; its HEAD matches the requested revision, the base is an ancestor, and the worktree is clean. Audit is read-only. No server, browser session, agent turn, code edit, forge comment or push was started.

Findings

1. **No row has sufficient maintainer visual evidence yet.** This feature is click → load/reveal → scroll → mark/focus, with behavior after another click, scrolling or asynchronous layout changes. A still cannot prove the transition, focus, retention, or lack of later movement. All reveal and lifecycle rows below require a **recording** plus a small DOM/state transcript. The contributor's light-theme stills are useful references, not accepted pass-1 maintainer proof.
2. **F19 is contradicted by the current persistence policy (P2).** The body says a pending reveal is not persisted and rehydration rebuilds PR surfaces without it. However, [rightPanelStore.ts:1187](https://github.com/pingdotgg/t3code/blob/e4601a1cc864e6fc7f5971cc89108437335c3a18/apps/web/src/rightPanelStore.ts#L1187) persists thread surface objects unchanged, including `revealUrl`. Dropping that property through `pullRequestSurface` happens in [migratePersistedRightPanelState](https://github.com/pingdotgg/t3code/blob/e4601a1cc864e6fc7f5971cc89108437335c3a18/apps/web/src/rightPanelStore.ts#L532), installed only as the version migration. Installed Zustand middleware calls migration only when the stored version differs. An isolated reproduction with that installed middleware and the production version/partialize/migrate policy reports `persistedContainsReveal: true`, `migrations: 0`, and the same `restoredReveal` after re-creation. This is **source and middleware evidence, not a real-client recording**. Trigger: click a comment while activity is pending, then reload before settlement; the thread panel can resume and reveal it without a new click. Strip `revealUrl` from serialization or normalize every hydration, and add an actual same-version persistence regression test. Closing/reopening a still-pending tab deserves its own checkpoint too: [reopenClosedView.ts:155](https://github.com/pingdotgg/t3code/blob/e4601a1cc864e6fc7f5971cc89108437335c3a18/apps/web/src/reopenClosedView.ts#L155) passes the complete remembered surface back to `openPullRequest`.
3. **The existing screenshot PR is too small to prove page-in.** [#29332](https://github.com/pingdotgg/t3code/pull/29332) has four issue comments, two review threads, and three retained review-summary items: nine conversations, although the displayed comment count is 13. Paging counts conversations, in steps of ten, not comments. [#33684](https://github.com/pingdotgg/t3code/pull/33684) supplies 19 review threads plus five issue comments, before its retained review summaries. Enable both filters to put its oldest conversation beyond two pages.
4. **Surface/forge claims need explicit limits.** Both production panel callers are changed. Desktop's embedded panel shares web; the OS-link coordinator supplies neither a thread nor panel ref and still navigates without the fragment. Native mobile is unchanged. GitLab is reachable through authenticated `glab`. Forgejo has neither `fj` nor `tea` installed here and is unit-only for this pass. GitCafe and Azure DevOps currently supply null comment URLs; they cannot reveal an individual comment through this matcher. GitHub mirror fixture links must resolve through a GitHub-capable project, not merely a GitCafe-origin project with the same repository name.

Contributor evidence inspected

- [before-issue-comment.png](https://github.com/MdSadiqMd/t3code/blob/pr-assets/pr-comment-link-focus/pr-comment-link-focus/before-issue-comment.png): light theme, 1280×800, thread side panel at Description. Reference for F01's before state only.
- [after-issue-comment.png](https://github.com/MdSadiqMd/t3code/blob/pr-assets/pr-comment-link-focus/pr-comment-link-focus/after-issue-comment.png): same light layout, marked issue comment under Comments, ten hidden. Reference for F01's final pose; focus and the click/scroll cannot be determined.
- [after-resolved-reply.png](https://github.com/MdSadiqMd/t3code/blob/pr-assets/pr-comment-link-focus/pr-comment-link-focus/after-resolved-reply.png): same light layout, nested reply marked, seven hidden. Reference for F07's final pose; automatic opening, scroll stability, and focus cannot be determined.

**Accepted coverage: zero matrix rows.** Do not upgrade a row because an image resembles its final frame or because the PR body says it was manually checked.

Render-path inventory

- [RightPanelSurfaceContent](https://github.com/pingdotgg/t3code/blob/e4601a1cc864e6fc7f5971cc89108437335c3a18/apps/web/src/components/chat/RightPanelSurfaceContent.tsx#L62) has one production caller, [ChatView](https://github.com/pingdotgg/t3code/blob/e4601a1cc864e6fc7f5971cc89108437335c3a18/apps/web/src/components/ChatView.tsx#L3177). Its changed `pull-request` case renders capability-unknown ghost, unsupported-server notice, or a keyed detail panel. `visible` and active surface gate shortcuts, not rendering/reveal. PR reference/host/environment, saved detail tab, thread context, composer draft target, Back availability, and active/hidden panel affect the surrounding chrome. All other switch cases (`null`, preview, terminal, diff, pull-requests list, side-chat, device, files/file) are unchanged and do not receive reveal props. Inline, maximized and sheet wrappers inherit the same changed content. Chat uses a sheet at viewport width ≤980px; the sheet has a second width rule at ≤760px. Minimum inline panel width is 360px.
- [PullRequestDetailPanel](https://github.com/pingdotgg/t3code/blob/e4601a1cc864e6fc7f5971cc89108437335c3a18/apps/web/src/components/pullRequest/PullRequestDetailPanel.tsx#L260) has exactly two production callers: the thread case above and [PullRequestsPage](https://github.com/pingdotgg/t3code/blob/e4601a1cc864e6fc7f5971cc89108437335c3a18/apps/web/src/components/pullRequest/PullRequestsPage.tsx#L1520). The permissions browser test is a harness caller. Thread uses local selected-tab state plus `detailTab`; page uses the guide-run store (`tabOnPage`) and a synthetic panel ref, default page context, no composer, and a list-entry seed. Both pass reveal and settlement. New target lookup branches: no URL; no detail; URL with no matching loaded comment; matched comment; miss with activity still pending; cached miss needing one host invalidation; invalidation failure; old versus post-invalidation activity; newer URL superseding a request. Found comments switch Summary; unavailable Code/Guide falls back to Summary. Summary can mount fresh or already be mounted invisibly beside Timeline/Code/Guide. Detail-null cold loading, cached-detail activity loading, detail failure/not-found, and activity-only failure are different render paths. Header expanded/condensed geometry changes during scroll and is part of F01/F14 evidence. `onRevealSettled` is optional in harnesses but present at both production callers.
- [PullRequestSummaryTab](https://github.com/pingdotgg/t3code/blob/e4601a1cc864e6fc7f5971cc89108437335c3a18/apps/web/src/components/pullRequest/PullRequestSummaryTab.tsx#L495) has one production caller, the detail panel, plus its existing browser-test harness. `detail.comments` plus `reviewThreads` normalize into loose comments and threads. Thread copies can contain comments absent from the flat list; empty threads disappear; IDs deduplicate flat/thread cards; roots precede replies. Only the targeted article gets `tabIndex=-1`, `data-linked-comment`, border and ring. Linked item bypasses both filters as a whole conversation; unrelated items remain filtered. The linked marker survives request settlement, and another link replaces it. Reveal count drives both section and finished-conversation reopening.
- Summary branches: activity pending → ghost; no activity plus error → compact error/retry; loaded → optional truncation warning, no comments, all comments filtered (singular/plural), or conversation list. Filter counts count all comments in included/excluded conversations; paging counts conversations. Counts 0/1/2 and page boundaries 10/11/20/21 collapse into empty, one-card, first-page, and older-page fixtures; exact arithmetic boundaries belong in the existing logic test, not a four-way screenshot grid. Newest/oldest reverse the visible page and place the older button below/above respectively; “show only 10” appears after page-in. A target near the bottom clamps at the scroll limit instead of always reaching a fixed offset.
- `renderItem` paths: ordinary loose issue/review/review-comment card; unfinished thread root plus zero/one/multiple indented replies; finished thread/standalone dismissed review through `CollapsedComment`. Root has location/Fix/Add to chat where allowed; replies omit location/Fix/Add to chat. Outcome badge (`approved`/`changes-requested`/`dismissed`), other review-state text, or no badge; path absent/present, line absent/present, outdated absent/present; reactions absent/present. Empty/HTML-only visible body may omit the body unless editable. Own editable comments show an edit control/editor, while reviews cannot be edited by this path. Pending handoff disables Fix and substitutes its preparing label. Thread context shows Add to chat and “Fix”; page lacks Add to chat and uses “Fix in a thread.” Long identities/paths, those actions and reactions wrap at narrow widths.
- [CollapsedComment](https://github.com/pingdotgg/t3code/blob/e4601a1cc864e6fc7f5971cc89108437335c3a18/apps/web/src/components/pullRequest/PullRequestSummaryTab.tsx#L252) has exactly one caller: the finished-item branch. Props: root, editing permissions/draft/saving, detail, optional thread, label Resolved/Review dismissed, visible-body null/text, reply count 0/1/many, replies null/list, more-replies null/notice, Add to chat absent/present, reactions, reveal count and root-only linked article props. Closed state may show one-line plain preview. Manual opening animates; reveal opening does not. A reply reveal opens the surrounding root but marks/focuses the nested reply. Re-closing then clicking the same link must reopen it again.
- [Section](https://github.com/pingdotgg/t3code/blob/e4601a1cc864e6fc7f5971cc89108437335c3a18/apps/web/src/components/pullRequest/PullRequestSummaryTab.tsx#L417) has exactly three callers in Summary: Description (initially open, keep mounted), Checks (initially closed), Comments (initially open, actions and reveal count). Manual close adjusts the sticky heading's anchor and animates; reveal opens Comments immediately. Description editor/read-only markdown/empty fallback and Checks stale/empty/check rows remain unchanged, but shared collapse behavior should be exercised in F11. Checks success/failure/cancelled, no URL/link, Fix absent/present/pending, reviewer/label zero/many, capability-dependent pickers, title/branch/state/merge/stack chrome are pre-existing content variants. They change scroll distance/header density, not the reveal algorithm. Sample empty versus dense content through F10/F14/F38; do not create a Cartesian grid for every unchanged action menu.
- [holdCommentInView](https://github.com/pingdotgg/t3code/blob/e4601a1cc864e6fc7f5971cc89108437335c3a18/apps/web/src/components/pullRequest/PullRequestSummaryTab.tsx#L367): no summary scroller → return (harness-only); otherwise align below owning sticky section heading plus 8px; observe the scroller's direct child sections; focus with preventScroll unless active element is contenteditable/input/textarea/select. Stop on wheel, touchstart, pointerdown, keydown; also on node disconnected or marker removed when resize callback runs. Its ref may be called with null or after already scrolled: those do nothing. Long comment bodies have a pre-existing 240px clamp, Show full/less, focus expansion, delayed markdown/media; these affect offsets and must be in the recording, not inferred from a final frame.
- [useOpenChangeRequestLink](https://github.com/pingdotgg/t3code/blob/e4601a1cc864e6fc7f5971cc89108437335c3a18/apps/web/src/lib/openPullRequestLink.ts#L49) callers: ChatMarkdown (user and assistant markdown; PR description/comment markdown, links and preview callback), BrowserDocumentFrame (explicit iframe document link), DesktopWebLinkCoordinator (no refs), and `useOpenPrLink`. Wrapper callers: ChatComposer, MessagesTimeline citations, SidebarThreadRow, ThreadPullRequestsPanel, BranchToolbarBranchSelector. Existing stored PR chips normally contain plain PR URLs; use F17/F32 as their regression coverage rather than inventing comment-bearing chip data. Entry gates: preference off; Meta/Ctrl/middle click external; unparseable link/no suitable project/config unavailable → fallback. With a thread/panel ref, a nonempty hash sets reveal; a bare trailing `#` has no nonempty hash. A later plain URL clears pending reveal; modified/external clicks do not. Without refs it navigates to `/pull-requests` without transferring the fragment (known unsupported path). Same-host sibling repositories may borrow a host-capable project; refs constrain the environment. No server/contracts/mobile implementation changed.

Seeding the real client

1. Use the capture owner's isolated dev state and the normal dev runner; do not start against live user data, change origins, or modify this review worktree. Follow [test-t3-app](https://github.com/pingdotgg/t3code/blob/e4601a1cc864e6fc7f5971cc89108437335c3a18/.agents/skills/test-t3-app/SKILL.md). Register a real GitHub-capable project in that environment. A fixture git repository with a committed file and the appropriate public forge `origin` is enough for repository identity and PR metadata; full PR data is fetched from the forge, not from the message text. It need not contain a checkout of the target PR to render Summary. Use a real checkout when exercising Code. Do not change this worktree's origin to make GitHub links resolve. Register a separate GitLab-capable project for the GitLab rows.
2. Settings → search “Open pull requests in T3 Code” → on. It is the client preference `pullRequestLinksOpenInApp`. Theme comes from the normal appearance control. The comment-filter menu persists `{bots,resolved}` under `t3code:pull-request-comment-filter:v1`; default is `{false,false}`. Prefer driving its menu; an isolated storage seed before loading is also adequate.
3. Free simplest seed: `node apps/server/src/bin.ts thread start --base-dir .t3 --provider devReplay --model showcase <project> - < <scratch>/links.md`. This creates a **user** markdown message containing the fixture links and a stock Replay assistant response, through the real thread/server path. User and assistant messages share the same link handler. The stock `showcase` does **not** echo arbitrary prompts into its assistant response.
4. If assistant-origin evidence is required, copy the replay agent and its showcase transcript into capture scratch, replace the final assistant-message frame's text with the same link list, make the copied scenario file path absolute, and register that copied script as a local ACP provider through Settings → Providers. Use that free scenario. Label this as an assistant-message seed; the application and forge reads remain real. This is an unexecuted recipe in pass 1, not a claim that a custom driver has run. Do not patch the checked-out replay transcript or use a paid model just to render links.
5. Thread route: `/$environmentId/$threadId`; obtain the actual identifiers from the thread-start result. Page route: `/pull-requests` with repository, number, selectedHost, selectedProjectId and selectedEnvironmentId search fields. A route alone identifies a PR, not a comment. The page's comment/description markdown carries `PULL_REQUESTS_PANEL_REF`, so click an actual comment link in that markdown to test its separate reveal/tab store. On the GitHub fixture, showing bots and expanding the CodeRabbit overview issue comment exposes links to its review thread.
6. Deterministic stale cache, in-flight replacement, typed-focus-at-arrival, unavailable activity, dismissed review, partial replies and unusual body/permission shapes cannot be guaranteed by a stable public PR without forge writes or races. Mount the actual changed panel/Summary in a **labelled browser harness** using the existing browser-test render/setup patterns. Gate RPC/query results with deferred responses and explicit release, not sleeps; never call these a real-app integration capture. Do not patch production websocket responses and silently present that as forge evidence.

Verified public fixture index (read-only API observations)

- **GH-A:** [#29332](https://github.com/pingdotgg/t3code/pull/29332). Loose human [issue comment 6709928633](https://github.com/pingdotgg/t3code/pull/29332#issuecomment-6709928633); old bot-only [issue comment 6578681526](https://github.com/pingdotgg/t3code/pull/29332#issuecomment-6578681526); long media-bearing [issue comment 6578832956](https://github.com/pingdotgg/t3code/pull/29332#issuecomment-6578832956). Resolved/outdated root [4443161356](https://github.com/pingdotgg/t3code/pull/29332#discussion_r4443161356), reply [4443234588](https://github.com/pingdotgg/t3code/pull/29332#discussion_r4443234588); resolved/current root at line 799 [4443340868](https://github.com/pingdotgg/t3code/pull/29332#discussion_r4443340868), reply [4443350073](https://github.com/pingdotgg/t3code/pull/29332#discussion_r4443350073). Files alias [4443350073](https://github.com/pingdotgg/t3code/pull/29332/files?w=1#r4443350073) must reveal the same reply. Approved bot [review 5737446760](https://github.com/pingdotgg/t3code/pull/29332#pullrequestreview-5737446760) has an HTML-comment-only body, giving a visible-body-empty review fixture. Empty COMMENTED reviews are intentionally not rendered by the GitHub normalizer.
- **GH-B:** [#33684](https://github.com/pingdotgg/t3code/pull/33684). At least 24 conversations before retained review summaries. Oldest resolved current root [4521046840](https://github.com/pingdotgg/t3code/pull/33684#discussion_r4521046840), reply [4522306600](https://github.com/pingdotgg/t3code/pull/33684#discussion_r4522306600). All 19 observed threads are resolved, so enable resolved/bots for pagination proof. The bot-only [issue comment 6758773740](https://github.com/pingdotgg/t3code/pull/33684#issuecomment-6758773740) is another filtered target. Recheck counts at capture time; this PR is active.
- **GH-C:** [#32682](https://github.com/pingdotgg/t3code/pull/32682). Unresolved/current [4503934173](https://github.com/pingdotgg/t3code/pull/32682#discussion_r4503934173), path `apps/web/src/speech/useDictationShortcut.ts`, line 69; unresolved/outdated [4503916592](https://github.com/pingdotgg/t3code/pull/32682#discussion_r4503916592), path `packages/client-runtime/src/voice-input/controller.ts`, no current line. Both have one comment at observation; use a harness for an unresolved reply. Enable bots for a clean unfiltered baseline. Thread resolution can change; verify it before capture.
- **GL-A:** [GitLab merge request !267203](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/267203). Loose [note 4201607884](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/267203#note_4201607884); resolved diff root [4161411004](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/267203#note_4161411004), reply [4161546203](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/267203#note_4161546203). Confirmed by authenticated `glab api projects/gitlab-org%2Fgitlab/merge_requests/267203/discussions?per_page=100`; no notes were created. Server adapter constructs comment URLs with `#note_<id>`, and a fresh detail read must succeed or they are null.
- **Forgejo:** `fj` and `tea` absent after checking the task PATH additions. The app provider requires one, so this is unit-only here. Do not substitute a GitCafe mirror capture: it is a different adapter and has null comment URLs.
- **Bitbucket:** generic URL-fragment matching can apply when its comment `links.html.href` carries a fragment, but no authenticated Bitbucket fixture was established. Unit-only here; no running-app support claim.
- **GitCafe/Azure DevOps:** null URL inputs are a unit-only negative case; a comment-specific successful reveal is not currently seedable through these adapters.

Minimum capture profiles and acceptance

`W` = 1440×900, normal inline thread panel at 540px; `D` = dark, `L` = light. `P` = 1440×900 Pull requests page, default panel width about 720px. `C` = 1440×900 with inline panel dragged to 360px. `S` = 900×900 thread sheet (the 761–980px branch). `N` = 390×844 narrow web sheet (≤760px branch), touch input. `X` = 1440×900 maximized panel. `H` = labelled browser harness at 1440×900/540px unless the row specifies another profile.

The table gives the minimum **viewport × theme × fixture** tuples. Do not multiply every row by every profile: W/L is the default behavioral run; repeat the plain and nested marked targets in W/D to judge both highlight styles. S/D and N/L cover the two sheet widths; C/L covers dense wrapping; X/L covers maximized/resize behavior. Combine several checkpoints into one recording at a fixed profile. For actual before/after proof, capture F01 and F07 on main at the supplied base and on the PR at identical W/L and W/D; capture the remaining affected transitions on the PR. A single still of a ring never substitutes for a recording.

Each recording should show the source link, click, selected Summary, target identity and mark, sticky-heading clearance, and settled frame after markdown/media. Attach a transcript identifying `document.activeElement`, `[data-linked-comment]`, the summary scroller/heading/target rectangles, scrollTop, pending reveal settlement, and relevant read counts. Assert alignment to **the actual heading height + 8px**, allowing normal bottom-of-list scroll clamping; do not hard-code the contributor's 48px observation. Check parent/chat/page scroll positions stay fixed. Keep typing contents and pairing/auth tokens out of shared evidence.

Fixture matrix — pass-1 status

All IDs are stable checkpoint names. “Changed” includes the behavior added by this diff; “regression” marks a pre-existing branch that the changed helper/shared component must preserve. “Missing” means no accepted maintainer capture, not a claim the implementation fails.

| ID / named fixture | Changed path; data and starting state | Seed / reachability | Minimum capture tuple and required observation | Status |
|---|---|---|---|---|
| F01 Ordinary issue link | Changed: loose issue article, loaded or fresh PR, Summary open, nonempty body | Real app GH-A, human issue 6709928633 | **recording W/L and W/D**, matching main before: click → correct card, ring, focus, condensed header, no outer scroll | MISSING; contributor still covers final-pose reference only |
| F02 Hidden bot, scroll limit | Changed: bots=false, resolved=false; oldest bot-only loose comment | Real app GH-A issue 6578681526 | **recording W/L**: only linked conversation bypasses filter, hidden count changes, bottom clamp is valid | MISSING |
| F03 Open review root, current | Changed: unfinished thread root, path + line, no replies, Fix/Add to chat actions | Real app GH-C root 4503934173; bots=true | **recording W/L**: root gets mark/focus; location is visible and not hidden by heading | MISSING |
| F04 Open review root, outdated | Changed: unfinished root, outdated label, no current line | Real app GH-C root 4503916592; bots=true | **recording W/L**: distinct outdated/location shape revealed correctly | MISSING |
| F05 Open thread reply | Changed: unfinished thread with root + one reply, root action header vs reply header | Labelled H; no unresolved public reply was established | **recording C/L**: narrow target reply receives the mark/focus, root does not; controls wrap cleanly | HARNESS MISSING |
| F06 Resolved root | Changed: resolved=false filter hides whole conversation; resolved root + multiple replies, current path/line | Real app GH-A root 4443340868 | **recording W/L**: one hidden conversation becomes visible and opens without height animation; root marked | MISSING |
| F07 Resolved outdated reply | Changed: hidden resolved/outdated conversation, target is nested reply | Real app GH-A reply 4443234588 | **recording W/L and W/D**, matching main before: opens root immediately, reveals/focuses only nested reply, stays aligned | MISSING; contributor still is final-pose reference only |
| F08 Resolved current reply, Files alias | Changed: resolved reply with current path/line, canonical versus `/files?w=1#rN` links | Real app GH-A reply 4443350073 and its Files alias | **recording S/D**: both links reveal same reply in sheet, repeated link works | MISSING |
| F09 Dismissed standalone review | Changed: finished loose review, label Review dismissed, no thread/replies, null visible body | Labelled H with DISMISSED review; public candidates inspected have none | **recording W/L**: hidden dismissed review becomes an open marked article, no phantom replies/body | HARNESS MISSING |
| F10 Empty-body review verdict | Changed: retained bot approval, review badge, no visible body and no editor | Real app GH-A review 5737446760; H variant CHANGES_REQUESTED/nonstandard state label | **recording W/L**: review anchor matches; badge-only card focuses/marks; no blank body hole | MISSING; extra badge/text shapes are labelled harness variants |
| F11 Closed sections and re-close | Changed shared Section and CollapsedComment: Comments closed, conversation closed, then manually close/reclick | Real app GH-A F06/F07; also toggle Description (keepMounted) and Checks (default closed) | **recording W/L**: click reopens Comments + conversation without motion; manual close/open still anchors and animates normally | MISSING |
| F12 Older than two pages, newest first | Changed: ≥21 filtered-in conversations, target not in newest ten; page-in rounds to ten | Real app GH-B oldest root 4521046840; both filters=true | **recording W/L**: target pages in, older button remains below, show-only-ten appears; shrink then re-click pages it in again | MISSING |
| F13 Older pages, oldest first | Changed: same target/page size, opposite order and older-button position | Real app GH-B; switch order before click | **recording W/L**: oldest target visible, older button above list, no duplicated/lost root/replies | MISSING |
| F14 Deferred height, long body, resize | Changed hold: long Description/markdown/media above target; body >240px, clamp and Show full/less | Real GH-A bot overview/long human comment; deterministic delayed media in labelled H if cache makes real load immediate | **recording X/L**: reveal, delayed growth and panel resize retain clearance until user intent; expand/collapse body then respect manual position | MISSING; controlled delay must be labelled |
| F15 Retarget and repeat after settlement | Changed: settled A remains marked, click B, scroll away, click B again | Real app GH-A issue → resolved reply → same reply; default filters | **recording W/L**: only latest card marked, previous forced-visible conversation may leave filter, repeated click re-scrolls/reopens | MISSING |
| F16 Non-Summary tab, two stores | Changed local thread tab vs page guide-run tab; fresh Summary mount and previously mounted hidden Summary | Real app, both callers; select Timeline, Code, Guide if enabled without running a guide, then a comment link | **recording W/L and P/L**: both paths switch/persist Summary and reveal; plain link leaves prior tab intact in F17 | MISSING |
| F17 Plain URL and bare trailing hash | Regression: no fragment, trailing `#`, new and existing panel with Code/Timeline selected | Real app GH-A PR URL without comment; stock wrapper links can supply plain URL | **recording W/L**: fresh panel behaves as before; warm tab/scroll remain unchanged; no new pending reveal | MISSING |
| F18 Settled close/reopen and reload | Regression: reveal settled, close tab/reopen via shortcut, reload, or revisit thread | Real app GH-A; use the normal closed-view action | **recording W/L**: URL may retain fragment but no fresh reveal/forced Summary from reopening alone; do not require component-local marker to survive remount | MISSING |
| F19 Pending reload / pending reopen | Changed lifecycle: URL still pending at reload, same storage version 14; also close before load and reopen | Labelled H gate activity; real client gate/reload for final proof | **recording W/L**: verify “click-only, not restored request” claim; record serialized/restored state | **CONTRADICTED** by source + isolated middleware reproduction; app recording absent |
| F20 Pending replacement/cancellation | Changed: A awaiting activity, click B; separate sequence A → plain PR URL; old response resolves last | Labelled H with deferred query/invalidation responses; real app cannot guarantee response order read-only | **recording W/L**: only B reveals; plain link cancels A; stale callback cannot settle/scroll a newer request | HARNESS MISSING |
| F21 Cold detail/activity arrival | Changed: no detail/no snapshot → detail ghost; cached detail but no activity → Comments ghost; then target arrives | Real first open for normal path; labelled H for controlled intermediate phases | **recording W/L**: no early wrong target/tab jump; target revealed after activity; ghost replaced cleanly | MISSING; controlled phases HARNESS MISSING |
| F22 Cached miss, fresh hit | Changed one-host-read state: activity lacks target; old in-flight response then invalidation and fresh target | Labelled H using real saved activity with target withheld until post-invalidation reply | **recording W/L** + ordered RPC transcript: wait for fresh host data, reveal once, no extra invalidation loop | HARNESS MISSING |
| F23 Final miss / non-comment hash | Changed: unknown/deleted/minimized comment or generic section fragment; no match after fresh host read | Real GH-A with a deliberately nonexistent anchor/non-comment hash; H for definite removed/minimized shape | **recording W/L**: one host refresh then settle, no invented mark/focus or forced Summary, later valid link works | MISSING |
| F24 Invalidation failure | Changed failure branch: missing target, invalidate denied/disconnected, stale data otherwise present | Labelled H with invalidate Failure; do not revoke real credentials or alter forge | **recording W/L**: expose no-reveal outcome and settlement, then retry click after reconnect; record failure, not successful reveal | HARNESS MISSING |
| F25 Activity error and recovery | Changed reveal waits across activity error; no activity shows compact error, stale activity can remain displayed | Labelled H; real PR plus deterministic activity Failure and Retry release | **recording W/L**: error/Retry vs retained stale content; recover and reveal correct comment | HARNESS MISSING |
| F26 Detail/capability unavailable | Regression guard: capability unknown/unsupported; detail-null loading, detail not-found/access error; cached detail still usable | Labelled H for each guard, real invalid PR only if useful | **recording W/L** if exercising retry; guard stills can supplement: no false comment/focus, retries usable | HARNESS MISSING; unchanged guard layouts need no separate full theme grid |
| F27 Partial conversation / missing reply | Changed: commentsTruncated warning, loaded target vs missing target beyond reply window; thread commentCount > loaded and cursor-only variant | Labelled H; root + 0/1/multiple loaded replies, moreReplies 0/1/many, optional host URL | **recording W/L**: loaded target reveals; unloaded target cannot; preserve warning, count and View on host rather than fabricate reply | HARNESS MISSING |
| F28 Focus while typing | Changed guard: during delayed load focus moves to composer contenteditable, input, textarea or select; control case noneditable button/body | Real app delayed activity + composer for contenteditable; labelled H for other fields | **recording W/L** + activeElement transcript: scroll/mark but preserve typing focus; ordinary control focuses article | MISSING; extra field cases HARNESS MISSING |
| F29 User scroll-intent release | Changed: wheel, touchstart, pointerdown and keydown stop resize hold; target change/unmount must not move another panel | Real app GH-A; delay/growth after release in labelled H | **recording W/L** for wheel/pointer/key, **N/L** for touch: scroll/mark remains user-controlled after later growth, no outer-page jump | MISSING |
| F30 Pull requests page markdown source | Changed second caller: null threadRef, synthetic panel ref, no Add to chat, page tab store | Real `/pull-requests` GH-A; show bots, expand bot overview 6578832956, click its review-thread link | **recording P/L**: comment source inside PR page opens/reveals on same page; correct Summary and page action labels | MISSING |
| F31 Rendered HTML document source | Changed hook caller: iframe document link carries real thread ref rather than markdown anchor | Real app: scratch HTML file with GH-A link opened in thread document preview; explicit click | **recording W/L**: document click routes to native PR panel and reveals comment; no paid turn required | MISSING |
| F32 Link gates / wrapper callers | Regression: setting off, Meta/Ctrl/middle click, unsupported URL, no project/config; plain toolbar/sidebar/composer/citation links | Existing hook/link tests for controlled gates; real app preference and modifiers; wrapper URLs usually have no fragment | **recording W/L** for setting/modifier user-visible route; source/test assertions for unavailable config and same/cross-environment resolution | MISSING visual gate proof; existing tests inspected, not executed |
| F33 GitLab loose note | Changed generic hash match, Merge request terminology, real GitLab activity URL mapping | Real app GL-A note 4201607884 via authenticated glab and GitLab-capable project | **recording W/L**: click note → correct MR/marked/focused loose comment | MISSING; reachable, not unit-only |
| F34 GitLab resolved reply | Changed nested resolved note path and root opening on non-GitHub host | Real app GL-A reply 4161546203; resolved filter=false | **recording W/L**: open containing discussion, mark/focus reply, preserve path and MR wording | MISSING; reachable, not unit-only |
| F35 Forgejo comment fragment | Changed generic matching of stored html_url fragment, root/reply data as adapter provides | Unit-only here: neither fj nor tea installed; no authenticated Forgejo app path established | No live capture required for pass 1; generic matcher/filter test plus normalized adapter URL evidence, explicitly no integration claim | UNIT-ONLY; generic test source present, not run |
| F36 Bitbucket comment fragment | Changed generic matcher if normalized links.html.href includes fragment | Unit-only here; no authenticated Bitbucket fixture established | No live capture required; URL-fragment matcher/normalizer evidence, not a GitHub substitution | UNIT-ONLY; source inspected, not run |
| F37 Null comment URL adapters | Regression/unsupported input: GitCafe and Azure URL=null cannot match any fragment | Unit-only negative case; real panel can show PR but cannot reveal its comments | No successful-reveal capture claim; verify null URL returns no target, common missing-target path is F23 | UNIT-ONLY; source-confirmed limitation |
| F38 Empty / all-hidden / editable dense shapes | Regression + changed target article: no items; one/many all filtered; null/ghost author; absent/long path; blank own editable comment; nonempty editor/saving; reactions and Fix/Add to chat/pending | Labelled H with actual Summary and real card subcomponents; no forge comment writes. Use F10 for noneditable empty body and F05 for reply variant | **recording C/L** for filter/reveal/editor focus transitions; labelled stills for static empty/dense poses. Include no-check/stale-check and empty/dense Description only as scroll-distance samples | HARNESS MISSING; pre-existing decorations do not require every provider/theme permutation |

Verification performed and limits

- Read exact full diff and production callers, relevant store hydration/reopen code, URL resolver and forge normalizers, browser/logic test source, dev Replay seeding code, and contributor screenshots.
- Refreshed PR metadata/body, review metadata, linked [#32547](https://git.cafe/pingdotgg/t3code/issues/32547), and head-bound status through cafe. At observation the requested head matched, with 28 successful checks, two pending and none failing. This is contextual CI state, not visual evidence, and is not a merge-readiness verdict.
- Read GitHub fixture data with explicitly authorized read-only `gh api`/GraphQL, and GitLab fixture data with `glab api`.
- Ran only the isolated in-memory persistence policy reproduction; no repo test suite or real client capture was run in this matrix-only pass. The two new tests cover generic anchor/filter logic and store set/replace/settle; they do not exercise DOM scrolling/focus, asynchronous host miss settlement, pagination rendering, collapsed reveal motion, or same-version hydration.
- Web/desktop embedded renderer applies. Native mobile and desktop OS-link/no-panel handling remain outside the implementation. Local versus remote transport introduces no new wire shape here; environment selection/fallback is recorded in F32 and should use the existing resolver tests rather than duplicate screenshots.

AI-assisted; verified with the tests and tools listed above.

FRICTION:
- tool | Installed glab api rejects --jq; switched to JSON plus Python and fixture reads succeeded | Read the installed glab api help before choosing jq flags.
- tool | Python urllib readback of the uploaded report returned HTTP 403; curl readback succeeded with HTTP 200 and matching bytes for both uploads | Use curl for this service’s public-file verification.
- infra | Neither fj nor tea is installed, preventing the normal Forgejo app-provider path on this VM | Preconfigure one authenticated Forgejo CLI if live Forgejo evidence is required; otherwise retain the explicit unit-only row.

VERDICT: INSUFFICIENT F01–F34 and F38 lack accepted maintainer captures (labelled harness where specified); F19's no-pending-reveal-on-reload claim is contradicted; F35–F37 are explicitly unit-only, not live coverage.
