Skip to content

feat(web): pin turn diff baselines - #10150

Open
sarjann wants to merge 2 commits into
pingdotgg:mainfrom
sarjann:feat/pinned-turn-diffs
Open

feat(web): pin turn diff baselines#10150
sarjann wants to merge 2 commits into
pingdotgg:mainfrom
sarjann:feat/pinned-turn-diffs

Conversation

@sarjann

@sarjann sarjann commented Sep 5, 2026

Copy link
Copy Markdown

What Changed

Add a pinned baseline to the web/desktop diff scope menu, using the server's existing checkpoint-range API.

  • Pin baseline compares the saved state after a completed turn with Latest turn. Start of thread (Turn 0) includes the first captured turn's changes.
  • Selecting a numbered Turn fixes the comparison endpoint; Latest turn resumes following completed turns. New completed turns preserve the baseline and any fixed endpoint.
  • The scope label shows both endpoints. Unpin baseline returns to a single-turn diff; working-tree and branch scopes clear the pin.
  • Completed turns with no individual file changes are muted and labeled No changes. They remain selectable when valid for the range; endpoints before the baseline are disabled.

Pins are stored per client, thread, and environment. Comparison caches and review state distinguish both endpoints. Includes focused store/range tests and a short user-guide section.

Why

Work often spans an implementation turn and a small follow-up correction. Reviewing those turns separately makes it harder to see the combined result. Pinning a saved baseline lets users review the net changes across that chunk of work.

Scope is limited to web and the shared desktop UI. No server, contract, mobile, or development-infrastructure changes. Imported CLI sessions can only compare snapshots captured by T3; Turn 0 does not reconstruct earlier CLI history.

UI Changes

Before After
Existing diff scope menu Pin baseline submenu including Turn 0

Pinned comparison labels

Follow latest: Turn 18 → Latest turn keeps Turn 18 as the baseline while the endpoint advances with completed turns. The menu below shows numbered endpoints and the new No changes labels.

Turn 18 to Latest turn with endpoint choices

Fixed endpoint: choosing Turn N changes the label to Turn 18 → Turn N and keeps both endpoints fixed. This example uses Turn 14 → Turn 16 to show a range with code changes.

Fixed comparison from Turn 14 to Turn 16

Validation

  • 120 focused tests passed: diffPanelStore.test.ts and ChatView.logic.test.ts.
  • Web TypeScript check passed.
  • Targeted lint completed with existing warnings and no errors; formatting and diff whitespace checks passed.
  • Manually verified in the current web build: pin Turn 14 to Latest, switch to Turn 16, and unpin back to the single-turn view. Checked Turn 0 availability, disabled earlier endpoints, and No changes labels.
  • Mobile is intentionally outside this PR and was not tested.

Checklist

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes
  • I included a video for animation/interaction changes

Implemented with GPT-6-Astra using Codex CLI in T3 Code.

Note

Add pinned baseline support to diff panel turn comparisons

  • Adds the ability to pin a completed turn or the thread-start snapshot as a diff baseline, then compare a fixed or latest-following endpoint turn against it via the scope menu in DiffPanel.tsx
  • Extends diffPanelStore.ts with DiffBaseline and DiffPanelSelection types, pinBaseline and selectLatestTurn actions, and a getCheckpointDiffRange helper that returns null for unavailable or reversed endpoints
  • Updates the completion effect in ChatView.tsx so a pinned-baseline comparison is not replaced when a new turn completes; unpinned selections still auto-select the latest turn
  • Reconciliation now independently validates the endpoint and the pinned baseline, clearing invalid baselines and falling back to branch scope when no checkpoints remain
  • Adds user-facing documentation for baseline pinning, thread-start comparisons, and scope menu behavior in source-control.md
  • Behavioral Change: reconcileTurnSelection in diffPanelStore.ts now clears an unavailable pinned baseline and falls back to branch scope when the available turn list is empty; previously the selection stayed on the removed turn

Macroscope summarized e2d94ea.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 5, 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-05T15:46:52.186701Z 00f8001 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.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Sep 5, 2026

@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: 00f8001de0

ℹ️ 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 apps/web/src/components/DiffPanel.tsx Outdated
<DropdownMenuSubTrigger>Pin baseline</DropdownMenuSubTrigger>
<DropdownMenuSubContent className="w-64">
<DropdownMenuItem
disabled={!latestTurn}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Disable Turn 0 when the baseline ref is absent

When Git is initialized during a running turn, CheckpointReactor intentionally records the completion checkpoint without creating the missing turn-0 baseline (CheckpointReactor.ts:240-274; its test confirms the ref remains absent at lines 1285-1287). This item is nevertheless enabled whenever any checkpoint summary exists; selecting it calls the full-thread diff, which always uses checkpointRefForThreadTurn(threadId, 0) with fallback disabled (CheckpointDiffQuery.ts:257-263), so this advertised comparison returns an error instead of a diff. Gate the option on actual turn-0 baseline availability or make the API handle the missing initial snapshot.

Useful? React with 👍 / 👎.

(summary) => summary.turnId === baselineTurnId,
);
const baselineTurnCount =
baselineTurnId === THREAD_START_DIFF_BASELINE ? 0 : baselineTurn?.checkpointTurnCount;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Medium components/DiffPanel.tsx:220

Pinned comparisons produce the wrong result for imported summaries without a stored checkpointTurnCount: baselineTurnCount becomes undefined, so getCheckpointDiffRange falls back to the preceding-turn diff and the label/cache omit the pinned baseline. The Turn menu also enables older endpoints with an inferred count because undefined < baselineTurnCount is false, and selecting one then yields no patch. Use inferredCheckpointTurnCountByTurnId[turnId] as the fallback both when computing baselineTurnCount and when disabling menu entries.

🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/web/src/components/DiffPanel.tsx around line 220:

Pinned comparisons produce the wrong result for imported summaries without a stored `checkpointTurnCount`: `baselineTurnCount` becomes `undefined`, so `getCheckpointDiffRange` falls back to the preceding-turn diff and the label/cache omit the pinned baseline. The Turn menu also enables older endpoints with an inferred count because `undefined < baselineTurnCount` is false, and selecting one then yields no patch. Use `inferredCheckpointTurnCountByTurnId[turnId]` as the fallback both when computing `baselineTurnCount` and when disabling menu entries.

@macroscopeapp

macroscopeapp Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR adds a persisted, user-facing baseline-comparison workflow across the web diff UI, selection store, and proactive diff opening, rather than a small mechanical change. Unresolved findings cover unavailable Turn 0 baselines and imported summaries, so the behavior warrants human review.

Not approved because:

  • 1 blocking correctness issue found at or above your repo's Minimum Blocking Severity

Adjust the Minimum Blocking Severity for this repo — including turning it Off — in Settings. You can add or adjust custom eligibility rules. Learn more.

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

Labels

size:L 100-499 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant