fix(web): keep earlier PR selections and findings in the composer#25136

draft5
main
fix/issue-24960
opened17d agobyJJulius Marminge
View on GitHubTwo-way sync enabledPR last imported 4h ago

Problem

Adding a second PR code selection or review finding to an existing composer removed the first attachment. An untouched handoff could also lose its request text, and repeated additions duplicated the PR reference.

Change

Accumulate selection and finding handoffs in the existing draft, including restored drafts. Scope attachment IDs to the PR URL, refresh repeated findings with their latest content, and keep repeated requests and PR references single. Both PR entry points use the same composer-store write; Ask, Explain and other replacing actions retain their existing behavior.

Scope and approval

Fixes https://github.com/pingdotgg/t3code/issues/24960

GitCafe: #24960

Triaged bug via the automated issue flow.

Verification

  • Reproduced in the real web app: add line 25, then line 26 to the same composer; the first chip disappeared. The same loss occurred when adding a second finding.
  • Red-first regression tests cover accumulated selections and findings, cross-repository identity, restored drafts, refreshed finding content and repeated requests. The focused logic suite passes 79/79.
  • Composer context and draft-store suites passed 84 tests before the final localized follow-up.
  • vp run check:changed: format, lint, affected-package typecheck, web knip and focused tests pass. The scripts knip phase reports the unrelated main-branch dependency agent-device in scripts/package.json; left untouched.
  • Shared web logic covers browser and Electron entry points. No mobile code, provider protocol or wire contract changed.

Evidence gate remains pending: the recordings demonstrate the bug and earlier fix, but the full matrix has not been recaptured at the final head. Both final code reviews returned MERGE. Proof audit pass 2 returned INSUFFICIENT for final-head I1–I10 and I12, including post-reload addition, repeat suppression, refreshed finding payload, reverse states and settled captures. This draft is not ready for the bugfix gate.

Evidence index · Coverage report · Fixture matrix

Real web app in T3 preview, desktop UA; requested CSS 1440×900 / 390×844, DPR 2. Audit found desktop exports at 1280×800, default font scaling, light/dark. Sanitized findings enter the existing activity query atom; real panel controls and composer handle every action. The host PR was read-only. Driver, fixture, state transcript and diff generator are uploaded in the index; none is committed.

The following are diagnostic captures, not a clean visual regression proof. Baseline is e3592efe7f; desktop after is the earlier 058d0be387; narrow light after is final bd24a99a27; narrow dark was captured during integration and its exact dirty snapshot is unavailable.

Recordings: start with the user sentinel, add A25, then B26; for findings, Fix T1 then T2, and mix a selection with a finding. Each recording contains the corresponding sequence. Desktop pairs below use baseline e3592efe7f and earlier after 058d0be387.

FlowBeforeAfter
I1 selections A then BbeforeI1.mp4afterI1.mp4
I3 findings T1 then T2beforeI3.mp4afterI3.mp4
I4 selection / finding / selectionbeforeI4.mp4afterI4.mp4
I5 unanchored remark / failed checkbeforeI5.mp4afterI5.mp4
I6 aggregate findingsbeforeI6.mp4afterI6.mp4
I7 Ask / Explain replacementbeforeI7.mp4afterI7.mp4

Final narrow B retry: after390lightBVideo.mp4; final reload readback: afterReloadVideo.mp4.

What else changed in captures: live PR metadata/diff changed, baseline precedes the main merge, and narrow frames contain notification/reconnect transients. Full-frame pixel diffs therefore cannot establish that unrelated rendering stayed unchanged. Narrow stills fail the clean settled-frame requirement.

Unverified: final-head repeats and edited-finding payload; remove/re-add interaction; complete fresh-draft and global PR routes; optional guide flow; final narrow findings in both themes; exact-final-head desktop matrix. Reload readback preserved both chips, but adding a new selection after reload was proven by the regression test rather than a final recording. No provider turn was sent. CI and the evidence gate are returned to the dispatcher; no bugfix label was added.

Models: GPT-6.1-sol (Codex harness) and Claude Opus 5.5 (Claude Code harness), orchestrated through T3 Code.

Checks

20 successful · 5 skipped
All checks passed
bd24a99

Added 5 commits

  • Merge main into fix/issue-24960058d0be
  • fix(web): only selections and findings pile up in the composer (#24960)193baed
  • test(web): red test for a second PR selection dropping the first (#24960)41b455d
  • fix(web): adding another PR selection to the agent keeps the earlier one (#24960)52110bc
  • fix(web): PR handoffs survive a reload and refresh re-handed findings (#24960)bd24a99
Synced from GitHub

Really would like to see this get merged, would make reviewing stacked PRs possible!

Synced from GitHub

Note

Generated by claude-opus-5-5 RESPONDING ON BEHALF OF SHARAD

This can be closed: it's already fixed on main. #24990 (03dbb2fb48) closed #24960: every pull request handoff now appends to the draft through appendHandoff, chips merge by id with the newer copy winning, repeats are dropped, and the PR context chip is keyed by URL. One difference: on main, Ask and Explain also append instead of replacing, which was #24990's choice.

The attached script runs a focused test for each behavior this PR describes (stacked selections and findings, two repos with the same PR number, a draft restored after reload, re-fixing a finding with new replies, a second request on one selection) against current main without this PR's source changes. All 8 pass.

To reproduce, run bash prove-pr-25136.sh from a clean t3code checkout after vp i, with gh authenticated.

Result
1PASS #24990 is on main as 03dbb2fb48
2PASS linked issue #24960 was closed as completed by merged PR #24990
3PASS #25136 was branched before #24990 and does not contain it
4 Tests 8 passed (8)
5PASS all 8 claimed behaviors pass on main (b18fefde72) without the PR's source changes
6VERDICT: CLOSE (already-fixed)