Skip to content

feat(ship): thread one ChatGPT conversation across a unit's plan and code review - #649

Merged
BorisTyshkevich merged 2 commits into
mainfrom
docs/chatgpt-review-seed-session
Aug 8, 2026
Merged

feat(ship): thread one ChatGPT conversation across a unit's plan and code review#649
BorisTyshkevich merged 2 commits into
mainfrom
docs/chatgpt-review-seed-session

Conversation

@BorisTyshkevich

Copy link
Copy Markdown
Collaborator

Summary

Corrects and implements the "one unit, one ChatGPT session" rule added to the /ship
skill after #630 phase 5. That rule's wording ("plan authoring, every plan-review round,
every PR code-review pass... all belong in the SAME conversation") was broader than the
chatgpt-review.mjs CLI actually supports: each session record is scoped to one CLI
mode + target (session.mode !== options.mode is a hard rejection), so a
plan-author-mode session and a pr-mode session were always separate conversations
by construction — confirmed by every phase 1-5 ship-log entry, which each show distinct
conversation URLs for plan review vs. code review.

What changed

  • scripts/lib/cli.mjs: new --seed-from-session <handle> value flag, mutually
    exclusive with --session.
  • scripts/chatgpt-review.mjs: when starting a fresh session (no --session) with
    --seed-from-session given, copy the named session's conversationUrl and
    lastResponseFingerprint into the new session record, and pass that session through
    to the browser driver (previously only --session did this — --seed-from-session
    alone would have silently opened a fresh chat despite the seeded record). pageFor()
    then reopens that existing tab/conversation instead of starting a new one. The new
    session still gets its own pass counter for its own mode (a pr-mode cap still counts
    only pr-mode passes).
  • tests/core.test.mjs: two new tests — the CLI flag itself, and an end-to-end run()
    proof that seeding threads the prior conversation through to the browser driver
    without mistaking its last message for an uncollected response.
  • skills/ship/references/code-review-pass.workflow.mjs: accepts an optional
    seedFromSession arg, used only on pass 1, and tightens the retry instructions so a
    mid-pass retry replaces --seed-from-session with --session rather than trying to
    pass both (the CLI rejects that combination).
  • skills/ship/SKILL.md / skills/ship/references/review-loops.md: rewritten to
    describe the real mechanism — same-mode resumes always reuse --session; crossing
    modes (plan authoring → PR code review) uses --seed-from-session once to thread the
    conversation, then --session from there.
  • skills/chatgpt-review/README.md / SKILL.md: documented the new flag for direct
    use outside /ship.

Tests

skills/chatgpt-review's own suite: 45/45 passing (43 pre-existing + 2 new). Full
repository gate (check:types/check:arch/check:schemas/check:examples/npm test/npm run build): green — this change touches only skills/**, outside the
coverage-gated src/** tree.

Scope note

Process/tooling only — not part of #630's own delivery contract, so it ships as its own
PR rather than folding into phase 6's diff, matching the precedent set by #647.

Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_01LwFPT465eDJqYcRa8HGNLz

BorisTyshkevich and others added 2 commits August 8, 2026 11:07
…code review

chatgpt-review.mjs scopes each session record to one CLI mode+target, so a
plan-author-mode session and a pr-mode session were always separate
conversations by construction — the "one unit, one ChatGPT session" rule
added after #630 phase 5 was broader than the tool actually supports.

Add --seed-from-session <handle>: starts a brand-new session for the current
mode (its own pass counter) but reopens an existing session's conversation
instead of a fresh chat, copying conversationUrl and lastResponseFingerprint
so the "recover an uncollected response" check doesn't mistake the seed
conversation's last message for this mode's own answer. --session and
--seed-from-session are mutually exclusive.

Wire it into code-review-pass.workflow.mjs (seedFromSession arg, used only on
pass 1) and correct review-loops.md/SKILL.md to describe the real mechanism:
same-mode resumes always use --session; crossing modes (plan authoring -> PR
code review) uses --seed-from-session once, then --session from there.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LwFPT465eDJqYcRa8HGNLz
code-review-pass.workflow.mjs and plan-review-loop.workflow.mjs told the
review-runner agent to redirect chatgpt-review's JSON output to a fixed
literal example filename (chatgpt-review-pr.json / chatgpt-review-plan.json)
reused across every PR/unit and every pass for an entire /ship run that can
span many hours.

Observed live on #630 phase 6, pass 2: the review-runner agent's own
structured-output step reported an old, already-resolved review (a
different PR's, from hours earlier) as this pass's result, even though the
real command for this PR/pass had already run and posted a correct comment
moments before. The coordinator only caught this by cross-checking the
actual posted GitHub comment against the workflow's returned session/SHA/
findings.

Derive a unique filename per invocation (PR number + pass, or plan file slug
+ pass) and require the agent use it exactly, instead of a generic example
it's been observed copying verbatim across unrelated passes.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LwFPT465eDJqYcRa8HGNLz
@BorisTyshkevich

Copy link
Copy Markdown
Collaborator Author

Added a second, related fix to this branch: code-review-pass.workflow.mjs and
plan-review-loop.workflow.mjs told their review-runner agent to redirect
chatgpt-review's JSON output to a fixed literal example filename
(chatgpt-review-pr.json / chatgpt-review-plan.json), reused across every
PR/unit and pass for an entire /ship run spanning many hours.

This caused a real incident on #630 phase 6, PR #648, pass 2: the review-runner
agent's structured-output step reported a stale, already-resolved review (from
a different, already-merged PR, hours earlier) as this pass's own result — even
though the real command for PR #648's pass 2 had already run and posted a
correct comment moments before. I only caught the mismatch by cross-checking
the workflow's returned session handle/reviewed SHA/comment URL against the
actual GitHub comment.

Fixed by deriving a unique output filename per invocation (PR number + pass,
or plan-file slug + pass) instead of a generic reused example.

@BorisTyshkevich
BorisTyshkevich merged commit eb5a348 into main Aug 8, 2026
8 checks passed
@BorisTyshkevich
BorisTyshkevich deleted the docs/chatgpt-review-seed-session branch August 8, 2026 09:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant