AIP-20: Build create-review-worktree skill - #266
jodavis-claude wants to merge 3 commits into
Conversation
Implements same-repo isolation via EnterWorktree + gh pr checkout, cross-repo isolation via a sibling-clone git worktree add when one exists, and a scratch gh repo clone fallback otherwise. The deterministic classify/finish-cross-repo logic lives in create_review_worktree.py, pytest-tested (mocked subprocess + one real, non-mocked git integration test) mirroring decide_cleanup_action.py's precedent; the native EnterWorktree call itself stays as thin SKILL.md prose, since it is only callable from the agent's own tool-use turn.
jodavis-claude
left a comment
There was a problem hiding this comment.
First-pass review of AIP-20 (create-review-worktree). Exit criteria are met and the deterministic classification/cross-repo logic is thoroughly tested (35 passing pytest tests, including one real non-mocked git integration test for the sibling-worktree path). One correctness/fault-tolerance issue found in the sibling-worktree branch handling (inline comment below) that I'd like addressed before sign-off; one minor documentation clarity note as well.
…olation path git worktree add -b <branch> ... created a named branch in the sibling clone's own repo that the immediately-following gh pr checkout never reused (it creates/switches to the PR's own real head branch instead). This orphaned the transient branch permanently, and made a second review of the same owner/repo/number fail outright since -b refuses to reuse an existing branch name. Switched to git worktree add --detach, since gh pr checkout creates/switches the real branch on its own right after. Added a real-git integration test that asserts no review-<owner>-<repo>-<number> branch is left behind in the sibling clone.
'Skip step 3 entirely' sat right after step 2's own internal numbered list (which has its own item 3), reading as if step 2's own item 3 were optional. It actually referred to the top-level Cross-repo section that follows. Reworded per review feedback.
jodavis-claude
left a comment
There was a problem hiding this comment.
Sign-off review for AIP-20 (create-review-worktree).
Prior review threads (2/2 resolved):
- Stray branch left in sibling clone (Priority 2, correctness/fault-tolerance) — fixed in commit c75849a.
finish_cross_repo()'s sibling-worktree path now usesgit worktree add --detach <target_dir> HEADinstead of-b <branch>, so no orphanedreview-<owner>-<repo>-<number>branch is left behind in the sibling clone, and a second review of the same PR no longer fails with "branch already exists". Verified: new regression testtest_finish_cross_repo_sibling_worktree_does_not_leave_a_stray_branch_in_sibling_cloneis a real (non-mocked) git integration test that fails against the pre-fix code and passes against the fix. Thread resolved. - SKILL.md "skip step 3" wording ambiguity (Priority 5, documentation clarity) — fixed in commit 67f3921. Reworded to "The Cross-repo section below does not apply to the same-repo path," matching the reviewer's suggested wording and removing the ambiguity with step 2's own internal item 3. Thread resolved.
New issues in modified files (commits c75849a, 67f3921): none found. Reviewed create_review_worktree.py's changed lines, SKILL.md's changed line, and the new test's mocking pattern (matches the existing _passthrough_except_gh real-git precedent already used by the sibling class in this file, not a new deviation).
Verification: all 36 tests pass (python3 -m pytest test_create_review_worktree.py -q → 36 passed).
Approved — no further changes requested.
Work item
AIP-20: Build
create-review-worktree, a skill that, given a resolved PR reference (fromresolve-pr-reference's JSON output), stands up an isolated working copy checked out to that PR's head — anEnterWorktreeworktree for a same-repo PR, agit worktree addfrom a sibling clone or a scratchgh repo clonefor a cross-repo PR — so every later Code Review Helper deliverable can operate on the PR's code without touching the reviewer's own checkout.Changes
plugins/dev-team/skills/create-review-worktree/SKILL.md(new) — the skill itself. Classifies which isolation mechanism a resolved PR needs, then either (a) same-repo: calls the nativeEnterWorktreetool, runsgh pr checkout <number> -R <owner>/<repo>, and returnsisolation_kind: enterworktree, or (b) cross-repo: delegates to the script'sfinish-cross-repocommand, returningisolation_kind: sibling-worktreeorisolation_kind: scratch-clone. Documents an explicit return contract (isolation_kind,worktree_path,head_ref) since the spec's prose didn't fix one.plugins/dev-team/skills/create-review-worktree/scripts/create_review_worktree.py(new) — deterministic classification and cross-repo execution logic:parse_owner_repo,get_current_repo,get_repo_root,sibling_matches,classify_isolation,finish_cross_repo, and amain()CLI (classify/finish-cross-reposubcommands, JSON in, JSON out).plugins/dev-team/skills/create-review-worktree/scripts/test_create_review_worktree.py(new) — 35 pytest tests covering every deterministic branch, including one real (non-mocked) local git integration test for the sibling-worktree path.Design decisions
classify_isolation/finish_cross_repoget full branch-coverage pytest (mirroringdecide_cleanup_action.py's precedent), while the untestableEnterWorktreecall stays as thin, manually-verified SKILL.md prose.git remote get-url originagainst the targetowner/repo, case-insensitively — resolves an ambiguity the spec left open.git worktree add/gh repo clone/gh pr checkoutfailures propagate asRuntimeErrorwith the underlying stderr — no structured failure taxonomy invented for this component..claude/worktrees/review-<owner>-<repo>-<number>/..feature/Gherkin harness exists anywhere in this repo (confirmed via search), so permissing-test-harnessnone was invented. The real-git integration test is the closest existing analog for exercising the Orchestrator's primary wiring end-to-end.Testing completed
plugins/dev-team/skills/create-review-worktree/scripts/test_create_review_worktree.py: 35 unit/integration tests, all passing (python3 -m pytest test_create_review_worktree.py -q→35 passed).