claude-dev-env 2.0.2 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/CLAUDE.md +1 -1
  2. package/hooks/blocking/CLAUDE.md +1 -0
  3. package/hooks/blocking/code_rules_shared.py +126 -47
  4. package/hooks/blocking/config/CLAUDE.md +2 -0
  5. package/hooks/blocking/config/verified_commit_context_constants.py +21 -0
  6. package/hooks/blocking/config/verified_commit_gate_output_constants.py +14 -0
  7. package/hooks/blocking/conftest.py +36 -30
  8. package/hooks/blocking/convergence_gate_blocker.py +76 -8
  9. package/hooks/blocking/plain_language_blocker.py +8 -0
  10. package/hooks/blocking/state_description_blocker.py +4 -1
  11. package/hooks/blocking/test_code_rules_shared.py +120 -20
  12. package/hooks/blocking/test_convergence_gate_blocker.py +146 -0
  13. package/hooks/blocking/test_plain_language_blocker.py +15 -0
  14. package/hooks/blocking/test_state_description_blocker.py +15 -0
  15. package/hooks/blocking/test_verified_commit_config_bootstrap.py +18 -0
  16. package/hooks/blocking/test_verified_commit_gate_additional_context.py +134 -0
  17. package/hooks/blocking/tests/test_verified_commit_gate.py +41 -0
  18. package/hooks/blocking/verified_commit_config_bootstrap.py +22 -10
  19. package/hooks/blocking/verified_commit_gate.py +113 -568
  20. package/hooks/blocking/verified_commit_gate_parts/CLAUDE.md +28 -0
  21. package/hooks/blocking/verified_commit_gate_parts/__init__.py +1 -0
  22. package/hooks/blocking/verified_commit_gate_parts/command_tokenization.py +174 -0
  23. package/hooks/blocking/verified_commit_gate_parts/deny_payload.py +53 -0
  24. package/hooks/blocking/verified_commit_gate_parts/deny_reason.py +80 -0
  25. package/hooks/blocking/verified_commit_gate_parts/directory_resolution.py +170 -0
  26. package/hooks/blocking/verified_commit_gate_parts/gated_invocations.py +205 -0
  27. package/hooks/blocking/verified_commit_gate_parts/tests/conftest.py +10 -0
  28. package/hooks/blocking/verified_commit_gate_parts/tests/test_command_tokenization.py +94 -0
  29. package/hooks/blocking/verified_commit_gate_parts/tests/test_deny_payload.py +17 -0
  30. package/hooks/blocking/verified_commit_gate_parts/tests/test_deny_reason.py +38 -0
  31. package/hooks/blocking/verified_commit_gate_parts/tests/test_directory_resolution.py +71 -0
  32. package/hooks/blocking/verified_commit_gate_parts/tests/test_gated_invocations.py +61 -0
  33. package/hooks/hooks_constants/CLAUDE.md +4 -1
  34. package/hooks/hooks_constants/code_rules_path_utils_constants.py +1 -0
  35. package/hooks/hooks_constants/convergence_gate_blocker_constants.py +36 -0
  36. package/hooks/hooks_constants/harness_scratchpad_constants.py +10 -9
  37. package/hooks/hooks_constants/mypy_integration_constants.py +16 -0
  38. package/hooks/validators/mypy_integration.py +145 -24
  39. package/hooks/validators/python_antipattern_checks.py +16 -0
  40. package/hooks/validators/run_all_validators.py +9 -3
  41. package/hooks/validators/test_mypy_integration.py +154 -0
  42. package/hooks/validators/test_python_antipattern_checks.py +112 -1
  43. package/hooks/validators/test_run_all_validators_pretooluse.py +16 -0
  44. package/package.json +1 -1
  45. package/rules/CLAUDE.md +1 -0
  46. package/rules/verified-commit-gate-skip.md +28 -0
  47. package/skills/auditing-claude-config/CLAUDE.md +2 -1
  48. package/skills/auditing-claude-config/SKILL.md +114 -176
  49. package/skills/auditing-claude-config/reference/probe-hook.md +74 -0
  50. package/skills/autoconverge/CLAUDE.md +1 -0
  51. package/skills/autoconverge/SKILL.md +310 -346
  52. package/skills/autoconverge/reference/CLAUDE.md +1 -0
  53. package/skills/autoconverge/reference/copilot-findings.md +51 -0
  54. package/skills/closeout/SKILL.md +7 -9
  55. package/skills/copilot-finding-triage/SKILL.md +5 -7
  56. package/skills/copilot-review/CLAUDE.md +3 -2
  57. package/skills/copilot-review/SKILL.md +119 -155
  58. package/skills/copilot-review/templates/subagent-prompt.md +49 -0
  59. package/skills/fresh-branch/CLAUDE.md +6 -9
  60. package/skills/fresh-branch/SKILL.md +84 -33
  61. package/skills/fresh-branch/scripts/create_fresh_branch.py +445 -0
  62. package/skills/fresh-branch/scripts/fresh_branch_scripts_constants/__init__.py +1 -0
  63. package/skills/fresh-branch/scripts/fresh_branch_scripts_constants/fresh_branch_cli_constants.py +74 -0
  64. package/skills/fresh-branch/scripts/test_create_fresh_branch.py +670 -0
  65. package/skills/pr-converge/SKILL.md +277 -422
  66. package/skills/pr-converge/reference/CLAUDE.md +1 -0
  67. package/skills/pr-converge/reference/progress-checklist.md +168 -0
  68. package/skills/pr-converge/test_step5_host_branch.py +8 -6
  69. package/skills/pr-loop-cloud-transport/SKILL.md +1 -1
  70. package/skills/privacy-hygiene/SKILL.md +68 -115
  71. package/skills/privacy-hygiene/reference/sweep-procedure.md +62 -0
  72. package/skills/session-log/CLAUDE.md +2 -1
  73. package/skills/session-log/SKILL.md +4 -26
  74. package/skills/session-log/templates/frontmatter.md +40 -0
  75. package/skills/skill-builder/CLAUDE.md +8 -7
  76. package/skills/skill-builder/SKILL.md +26 -11
  77. package/skills/skill-builder/references/CLAUDE.md +3 -1
  78. package/skills/skill-builder/references/delegation-map.md +21 -12
  79. package/skills/skill-builder/references/description-field.md +9 -11
  80. package/skills/skill-builder/references/deterministic-elements.md +218 -0
  81. package/skills/skill-builder/references/self-audit-checklist.md +62 -45
  82. package/skills/skill-builder/references/skill-modularity.md +8 -9
  83. package/skills/skill-builder/templates/CLAUDE.md +2 -2
  84. package/skills/skill-builder/templates/gap-analysis.md +15 -0
  85. package/skills/skill-builder/workflows/CLAUDE.md +5 -5
  86. package/skills/skill-builder/workflows/improve-skill.md +18 -9
  87. package/skills/skill-builder/workflows/new-skill.md +23 -15
  88. package/skills/skill-builder/workflows/polish-skill.md +28 -21
@@ -7,6 +7,7 @@ Reference documentation for the `autoconverge` skill. The `converge.mjs` workflo
7
7
  | File | Role |
8
8
  |---|---|
9
9
  | `convergence.md` | Round shape: the static sweep, the three parallel internal lenses (code-review, bug-audit, self-review), deduplication, the fix commit step, the terminal Bugbot, Copilot, and Codex gates, and the definition of a clean convergence. |
10
+ | `copilot-findings.md` | The Copilot gate tiering, per-finding verification, and the `userReview` return contract. |
10
11
  | `stop-conditions.md` | Every condition that ends the run short of ready: budget cap, iteration cap, blocker exit, static-sweep stall, Bugbot, Copilot, and Codex bypass. |
11
12
  | `gotchas.md` | Hard-won lessons from failed runs: PR title validation, conflicting PRs, worktree branch lock, resumed sessions rerooting, and minter issues. |
12
13
  | `closing-report.md` | The closing HTML convergence report the teardown step builds and publishes: data source, build steps, publishing. |
@@ -0,0 +1,51 @@
1
+ # Copilot findings — tier, verify, then route
2
+
3
+ How the autoconverge Copilot gate handles each finding. The hub
4
+ ([`../SKILL.md`](../SKILL.md)) points here; the orchestrating session's
5
+ user-review hold runs the [`copilot-finding-triage`](../../copilot-finding-triage/SKILL.md)
6
+ skill.
7
+
8
+ The Copilot gate tiers each finding: a **self-healing** finding (style, type
9
+ hints, imports, formatting, magic-value extraction, test-only or doc-vs-code
10
+ fixes — nothing that changes observable runtime behavior) flows into the fix
11
+ round with no user notification. A **code-concern** finding (logic, security,
12
+ data handling, error-handling semantics, concurrency — the tier whenever in
13
+ doubt) goes to a verification stage before any routing.
14
+
15
+ Each code-concern finding gets its own verifier agent, all in parallel, inside
16
+ the workflow. A verdict is conclusive only when an actual check ran: the verifier
17
+ executes a command against the flagged HEAD — running the code path with crafted
18
+ inputs, forcing the claimed error condition, or running a purpose-built test —
19
+ and captures its output. The verdict carries
20
+ `{ verdict, checkCommand, checkOutput, evidence }`; a conclusive verdict with an
21
+ empty `checkCommand` or `checkOutput` downgrades to inconclusive.
22
+
23
+ - **confirmed** — the check reproduces the defect. The finding becomes
24
+ self-healing: it joins the fix round carrying its repro, and the fix re-runs
25
+ that same check, adds a regression test where the suite covers the surface,
26
+ lands in one commit, pushes, and replies on the thread with the fix SHA and the
27
+ before/after output. No page.
28
+ - **refuted** — the check shows the code already behaves correctly in the exact
29
+ scenario the finding claims is broken. The workflow replies on the thread with
30
+ the command and output, resolves it, and counts it clean. No page.
31
+ - **inconclusive** — everything else, and the verifier's default: no runnable
32
+ check exists, the check is infeasible here, the results are ambiguous, or the
33
+ fix needs a product decision. Any doubt sorts here. Only inconclusive findings
34
+ page the user.
35
+
36
+ A round whose code concerns all confirm or refute never returns
37
+ `blocker: "user-review"`. On one or more inconclusive findings, the workflow
38
+ stops with `converged: false`, `blocker: "user-review"`, and a `userReview`
39
+ field carrying
40
+ `{ reviewUrl, findings: [{ file, line, severity, tier, title, evidence }] }` —
41
+ `evidence` is the verifier's one-line note stating what check was attempted and
42
+ why it was not decisive.
43
+
44
+ A background workflow cannot hold for a human, so the wait belongs to the
45
+ orchestrating session. On a `blocker: "user-review"` return, run the
46
+ [`copilot-finding-triage`](../../copilot-finding-triage/SKILL.md) skill: send the
47
+ ntfy notification (the per-finding summary and evidence note plus the `reviewUrl`
48
+ Copilot review link), then hold with a 45-minute `ScheduleWakeup` for the user's
49
+ response. When the user answers within the window, follow their direction. When
50
+ the window closes with no response, run normal teardown and report the
51
+ inconclusive findings un-reviewed.
@@ -1,15 +1,13 @@
1
1
  ---
2
2
  name: closeout
3
3
  description: >-
4
- Harvests session obstacles into GitHub issues backed by quoted evidence at
5
- session end, validates each draft with the user, dedupes against open and
6
- closed issues, routes each to its repo, files children then a parent
7
- checklist, and prints a computed cloud handoff prompt. Triggers: /closeout,
8
- close out this session, close out the session, file the session obstacles,
9
- session closeout, harvest session obstacles, end-of-session issue filing.
10
- Near-miss: not session-log, which journals the session to the vault; closeout
11
- files GitHub issues and prints a handoff prompt, and writes no session
12
- journal.
4
+ Harvests session obstacles into GitHub issues backed by quoted evidence:
5
+ validates each draft with the user, dedupes against open and closed issues,
6
+ files children under a parent checklist, and prints a cloud handoff prompt.
7
+ Triggers: /closeout, close out this session, close out the session, file the
8
+ session obstacles, session closeout, harvest session obstacles, end-of-session
9
+ issue filing. Not session-log (vault journal) closeout files issues and
10
+ writes no journal.
13
11
  ---
14
12
 
15
13
  # Closeout
@@ -1,13 +1,11 @@
1
1
  ---
2
2
  name: copilot-finding-triage
3
3
  description: >-
4
- Sorts each Copilot gate finding from a converge run into one of two tiers, then
5
- verifies each code concern with an executed check before routing it: a
6
- self-healing finding is auto-fixed, pushed, and counted toward convergence with
7
- no user page; a confirmed or refuted code concern is handled by the run with its
8
- check evidence; only a code concern the check leaves inconclusive pages the user
9
- over ntfy and holds the run behind a 45-minute gate. Triggers: 'copilot finding
10
- triage', 'user review gate', 'tier copilot findings', 'triage the copilot gate'.
4
+ Tiers each Copilot gate finding from a converge run, verifies each code concern
5
+ with an executed check, then routes it — auto-fix a self-healing finding,
6
+ resolve a refuted one, page the user only for an inconclusive one. Triggers:
7
+ 'copilot finding triage', 'user review gate', 'tier copilot findings', 'triage
8
+ the copilot gate'.
11
9
  ---
12
10
 
13
11
  # Copilot Finding Triage
@@ -6,11 +6,12 @@ Spawns a background subagent that polls the GitHub Copilot reviewer on the curre
6
6
 
7
7
  The main session gathers PR context (number, HEAD SHA, owner/repo, branch), spawns a self-terminating background subagent with a fully filled-in prompt, and returns control at once. The subagent loops on a 6-minute `ScheduleWakeup` cadence: fetch Copilot's latest review, TDD-fix any inline findings, push a commit, reply inline, resolve each addressed thread, re-request review. It stops on convergence, a persistent blocker, `TaskStop`, three consecutive ticks with no Copilot review at the current HEAD, or after 20 ticks.
8
8
 
9
- ## Key file
9
+ ## Key files
10
10
 
11
11
  | File | Purpose |
12
12
  |---|---|
13
- | `SKILL.md` | Four-step orchestration (opt-out check, gather PR context, spawn subagent, report to user), the verbatim subagent prompt template with all placeholders, fix protocol, stop conditions, and ground rules (one commit per tick, honor hooks, preserve draft state, use `copilot-pull-request-reviewer[bot]` with the `[bot]` suffix). |
13
+ | `SKILL.md` | Four-step orchestration (opt-out check, gather PR context, spawn subagent, report to user), fix protocol, stop conditions, and ground rules (one commit per tick, honor hooks, preserve draft state, use `copilot-pull-request-reviewer[bot]` with the `[bot]` suffix). |
14
+ | `templates/subagent-prompt.md` | The background watcher prompt Step 3 passes to the subagent word for word, with placeholders for PR number, owner, repo, branch, and HEAD SHA. |
14
15
 
15
16
  ## Environment opt-out
16
17
 
@@ -1,155 +1,119 @@
1
- ---
2
- name: copilot-review
3
- description: >-
4
- Spawns a background subagent that babysits the GitHub Copilot reviewer on the
5
- current PR: each tick it fixes unaddressed findings against HEAD, re-requests
6
- review, and exits on convergence. Triggers: '/copilot-review', 'watch
7
- copilot', 'babysit copilot review', 'keep re-requesting copilot'.
8
- ---
9
-
10
- # Copilot Review
11
-
12
- Delegates Copilot babysitting to a background subagent so the main session stays free. The subagent loops internally and closes itself on convergence.
13
-
14
- ## Transport check (before any GitHub step)
15
-
16
- Run `command -v gh`; when it succeeds, run `gh auth status`; once the PR scope is resolved, run `gh api repos/<owner>/<repo> --jq .permissions.push` and take `true` as the pass. When any check fails, run the `pr-loop-cloud-transport` skill first, route every `gh` operation in this skill through its substitution matrix, and carry the same routing into the subagent prompt so the spawned watcher inherits it.
17
-
18
- ## When this skill applies
19
-
20
- The user is on a PR branch, wants Copilot (the GitHub Copilot reviewer bot) to keep re-reviewing after each push, and wants findings auto-addressed between ticks — but does not want the main conversation consumed by polling.
21
-
22
- ## The Process
23
-
24
- ### Step 0: Opt-out check
25
-
26
- Before any other work, run:
27
-
28
- ```bash
29
- python "$HOME/.claude/_shared/pr-loop/scripts/reviews_disabled.py" --reviewer copilot
30
- ```
31
-
32
- Exit 0 — Copilot reviews are disabled: respond with the literal line
33
- `/copilot-review is disabled via CLAUDE_REVIEWS_DISABLED.` and stop — do not
34
- spawn the subagent, do not call the Copilot reviewer API, do not run any
35
- other step of this skill. Exit 1 — continue. Gate semantics live in the
36
- `reviewer-gates` skill ([../reviewer-gates/SKILL.md](../reviewer-gates/SKILL.md)).
37
-
38
- ### Step 1: Gather PR context
39
-
40
- From the current repo:
41
-
42
- ```bash
43
- # MCP: pull_request_read(method="get") returns {number, url, head.sha, base.ref, head.ref, isDraft}
44
- ```
45
-
46
- Capture `number`, `head.sha`, owner/repo (from `url`), and branch name. Pass these to the subagent so it does not rediscover them.
47
-
48
- ### Step 2: Spawn the background subagent
49
-
50
- Invoke the `Agent` tool with:
51
-
52
- - `subagent_type: "general-purpose"`
53
- - `run_in_background: true`
54
- - `description: "Copilot review loop for PR #<N>"`
55
- - `prompt`: the full instructions in **Step 3 (Subagent prompt template)**, with placeholders filled in from Step 1.
56
-
57
- Record the returned agent ID. Report to the user in one or two lines:
58
-
59
- - The subagent is running in the background.
60
- - It self-terminates on convergence.
61
- - To stop it early, the user says "stop the copilot loop" and you call `TaskStop <agent_id>`.
62
- - The main session stays free; completion arrives as a notification.
63
-
64
- Let the subagent own the cadence. The skill's job in the main session ends once the subagent is spawned and reported.
65
-
66
- ### Step 3: Subagent prompt template
67
-
68
- Pass this verbatim to the subagent (substituting the bracketed values):
69
-
70
- > You are babysitting the GitHub Copilot reviewer on PR **#[NUMBER]** at **[OWNER]/[REPO]** (branch `[BRANCH]`, current HEAD `[HEAD_SHA]`). Your job: keep the loop running until Copilot returns a clean review against the current HEAD, then stop.
71
- >
72
- > **Per-tick work** (do this now, then on each wakeup):
73
- >
74
- > 1. Resolve current HEAD: `pull_request_read(method="get", pullNumber=[NUMBER], owner="[OWNER]", repo="[REPO]")` and extract `.head.sha`.
75
- > 2. Fetch latest Copilot review via `pull_request_read(method="get_reviews", pullNumber=[NUMBER], owner="[OWNER]", repo="[REPO]")`.
76
- > Capture `commit_id`, `state`, `submitted_at`, `id`.
77
- > 3. Decide the branch:
78
- > - **No review exists:** increment `no_review_count` (see escalation rule below), re-request (step 4), schedule next wakeup, return.
79
- > - **Latest review's `commit_id` != current HEAD:** increment `no_review_count`, re-request (step 4), schedule next wakeup, return.
80
- > - **Latest review's `commit_id` == current HEAD with unresolved inline findings:** reset `no_review_count` to 0, TDD-fix them, push, reply inline on each thread, resolve each addressed thread, re-request (step 4), schedule next wakeup, return.
81
- > - **Latest review's `commit_id` == current HEAD and clean:** report convergence to the parent with a one-sentence summary and terminate. The loop is done; skip the ScheduleWakeup call.
82
- >
83
- > **Escalation rule:** `no_review_count` starts at 0, counts consecutive ticks where no Copilot review exists at the current HEAD, and resets to 0 on every push and every review sighted at HEAD. When it reaches 3, Copilot is not delivering reviews — report the stall to the parent with the count and the last request timestamp, then terminate without scheduling another wakeup.
84
- > 4. Re-request Copilot via `request_copilot_review(owner="[OWNER]", repo="[REPO]", pullNumber=[NUMBER])`.
85
- > The reviewer ID **must** be `copilot-pull-request-reviewer[bot]` with the `[bot]` suffix — empirically verified: `Copilot`, `copilot`, and `github-copilot` all return `requested_reviewers: []` with no error, silently no-op.
86
- > 5. Schedule the next wakeup with `ScheduleWakeup`:
87
- > - `delaySeconds: 360`
88
- > - `reason`: one short sentence on what you are waiting for.
89
- > - `prompt`: the literal sentinel `<<autonomous-loop-dynamic>>` so the next firing re-enters these instructions.
90
- >
91
- > **Fix protocol** (step 3, third branch):
92
- >
93
- > - Read `$HOME/.claude/skills/pr-fix-protocol/SKILL.md` and apply it — it carries the shared fix sequence, the reply-and-resolve unit, and the unresolved-thread sweep.
94
- > - Read each referenced file:line.
95
- > - Write a failing test first when the finding has behavior to test. For pure doc or comment nits that have no behavior, go straight to the fix.
96
- > - Stage the fix and create one new commit on the existing branch: `git add <files> && git commit -m "fix(review): ..."`.
97
- > - Push the new commit: `git push origin [BRANCH]`.
98
- > - Reply inline via `add_reply_to_pull_request_comment(owner="[OWNER]", repo="[REPO]", pullNumber=[NUMBER], body="...", commentId=<comment_id>)`, referencing the new commit SHA; then resolve each addressed thread via `pull_request_review_write(method="resolve_thread", pullNumber=[NUMBER], owner="[OWNER]", repo="[REPO]", threadId="<PRRT id>")`, harvesting the `PRRT_…` id from `pull_request_read(method="get_review_comments", ...)`. Reply first, then resolve — atomic per thread, per the protocol.
99
- >
100
- > When a pre-push, pre-commit, or other hook rejects the change, solve it. Read the hook's error message, diagnose the root cause in the code or test, and fix that. Then rerun the commit or push. Hooks exist to catch real problems; treat each rejection as new evidence to act on.
101
- >
102
- > **Stop conditions:**
103
- >
104
- > - Convergence (clean review against HEAD): report one-sentence summary to parent and terminate.
105
- > - Blocker you have exhausted fix attempts on (API auth failure persists, CI regression whose root cause falls outside this PR, a hook you have investigated and cannot resolve in one commit): report the specific blocker and its diagnosis to the parent, then terminate without scheduling another wakeup.
106
- > - Parent sends `TaskStop`: terminate immediately.
107
- > - `no_review_count` reaches 3 (escalation rule above): report the stall and terminate.
108
- >
109
- > **Safety cap:** after 20 ticks without convergence, stop and report. This is the total-tick runaway guard, distinct from the 3-consecutive-no-review escalation; that many rounds means something structural is wrong with the loop.
110
-
111
- ### Step 4: Report back to the user
112
-
113
- After spawning, tell the user in one or two lines: subagent ID, PR URL, that it will notify on convergence or blocker. Nothing else.
114
-
115
- ## Stopping the subagent
116
-
117
- - Convergence subagent stops itself.
118
- - Blocker subagent reports and stops.
119
- - User says stop → `TaskStop <agent_id>`.
120
- - User asks what loops are running → `TaskList`.
121
-
122
- ## Ground rules (for the subagent)
123
-
124
- - **Append commits.** Each tick adds one new commit on the existing branch with `git commit` and `git push origin [BRANCH]`.
125
- - **Honor pre-push and pre-commit hooks.** When a hook rejects the change, read its output, fix the underlying issue (the failing test, the missing constant, the broken import), and retry. Solve, do not punt.
126
- - **Respect the PR's current state.** Whatever draft-vs-ready state the PR has when the loop starts is the state the subagent preserves. The user decides when to flip it.
127
- - **One fix commit per tick.** Batch all of the current tick's findings into a single commit; the next tick handles the next review round.
128
- - **Use `copilot-pull-request-reviewer[bot]` with the `[bot]` suffix for the reviewer ID.** That exact spelling is load-bearing — it is the only form the API accepts.
129
-
130
- ## Examples
131
-
132
- <example>
133
- User: `/copilot-review`
134
- Claude: [reads PR context, spawns background subagent with the Step 3 template, reports "subagent X watching PR #123; will notify on convergence"]
135
- </example>
136
-
137
- <example>
138
- User: "babysit copilot on this PR until it's clean"
139
- Claude: [same as above]
140
- </example>
141
-
142
- <example>
143
- Subagent tick fires, latest Copilot review is against an older commit.
144
- Subagent: [re-requests review, schedules next wakeup, returns]
145
- </example>
146
-
147
- <example>
148
- Subagent tick fires, Copilot has 2 unaddressed inline findings on HEAD.
149
- Subagent: [TDD-fixes both, one commit, pushes, replies inline on both threads, resolves both threads, re-requests review, schedules next wakeup]
150
- </example>
151
-
152
- <example>
153
- Subagent tick fires, latest review is clean against HEAD.
154
- Subagent: [reports convergence to parent, terminates — no further wakeups]
155
- </example>
1
+ ---
2
+ name: copilot-review
3
+ description: >-
4
+ Spawns a background subagent that babysits the GitHub Copilot reviewer on the
5
+ current PR: each tick it fixes unaddressed findings against HEAD, re-requests
6
+ review, and exits on convergence. Triggers: '/copilot-review', 'watch
7
+ copilot', 'babysit copilot review', 'keep re-requesting copilot'.
8
+ ---
9
+
10
+ # Copilot Review
11
+
12
+ Delegates Copilot babysitting to a background subagent so the main session stays free. The subagent loops internally and closes itself on convergence.
13
+
14
+ ## Transport check (before any GitHub step)
15
+
16
+ Run `command -v gh`; when it succeeds, run `gh auth status`; once the PR scope is resolved, run `gh api repos/<owner>/<repo> --jq .permissions.push` and take `true` as the pass. When any check fails, run the `pr-loop-cloud-transport` skill first, route every `gh` operation in this skill through its substitution matrix, and carry the same routing into the subagent prompt so the spawned watcher inherits it.
17
+
18
+ ## When this skill applies
19
+
20
+ The user is on a PR branch, wants Copilot (the GitHub Copilot reviewer bot) to keep re-reviewing after each push, and wants findings auto-addressed between ticks — but does not want the main conversation consumed by polling.
21
+
22
+ ## The Process
23
+
24
+ ### Step 0: Opt-out check
25
+
26
+ Before any other work, run:
27
+
28
+ ```bash
29
+ python "$HOME/.claude/_shared/pr-loop/scripts/reviews_disabled.py" --reviewer copilot
30
+ ```
31
+
32
+ Exit 0 — Copilot reviews are disabled: respond with the literal line
33
+ `/copilot-review is disabled via CLAUDE_REVIEWS_DISABLED.` and stop — do not
34
+ spawn the subagent, do not call the Copilot reviewer API, do not run any
35
+ other step of this skill. Exit 1 — continue. Gate semantics live in the
36
+ `reviewer-gates` skill ([../reviewer-gates/SKILL.md](../reviewer-gates/SKILL.md)).
37
+
38
+ ### Step 1: Gather PR context
39
+
40
+ From the current repo:
41
+
42
+ ```bash
43
+ # MCP: pull_request_read(method="get") returns {number, url, head.sha, base.ref, head.ref, isDraft}
44
+ ```
45
+
46
+ Capture `number`, `head.sha`, owner/repo (from `url`), and branch name. Pass these to the subagent so it does not rediscover them.
47
+
48
+ ### Step 2: Spawn the background subagent
49
+
50
+ Invoke the `Agent` tool with:
51
+
52
+ - `subagent_type: "general-purpose"`
53
+ - `run_in_background: true`
54
+ - `description: "Copilot review loop for PR #<N>"`
55
+ - `prompt`: the full instructions in **Step 3 (Subagent prompt template)**, with placeholders filled in from Step 1.
56
+
57
+ Record the returned agent ID. Report to the user in one or two lines:
58
+
59
+ - The subagent is running in the background.
60
+ - It self-terminates on convergence.
61
+ - To stop it early, the user says "stop the copilot loop" and you call `TaskStop <agent_id>`.
62
+ - The main session stays free; completion arrives as a notification.
63
+
64
+ Let the subagent own the cadence. The skill's job in the main session ends once the subagent is spawned and reported.
65
+
66
+ ### Step 3: Subagent prompt template
67
+
68
+ Pass the prompt in
69
+ [`templates/subagent-prompt.md`](templates/subagent-prompt.md) to the subagent
70
+ word for word, filling in the bracketed values ([NUMBER], [OWNER], [REPO],
71
+ [BRANCH], [HEAD_SHA]) from Step 1. It carries the per-tick work, the escalation
72
+ rule (three consecutive no-review ticks), the fix protocol, the stop conditions,
73
+ and the 20-tick safety cap.
74
+
75
+ ### Step 4: Report back to the user
76
+
77
+ After spawning, tell the user in one or two lines: subagent ID, PR URL, that it will notify on convergence or blocker. Nothing else.
78
+
79
+ ## Stopping the subagent
80
+
81
+ - Convergence subagent stops itself.
82
+ - Blocker → subagent reports and stops.
83
+ - User says stop `TaskStop <agent_id>`.
84
+ - User asks what loops are running → `TaskList`.
85
+
86
+ ## Ground rules (for the subagent)
87
+
88
+ - **Append commits.** Each tick adds one new commit on the existing branch with `git commit` and `git push origin [BRANCH]`.
89
+ - **Honor pre-push and pre-commit hooks.** When a hook rejects the change, read its output, fix the underlying issue (the failing test, the missing constant, the broken import), and retry. Solve, do not punt.
90
+ - **Respect the PR's current state.** Whatever draft-vs-ready state the PR has when the loop starts is the state the subagent preserves. The user decides when to flip it.
91
+ - **One fix commit per tick.** Batch all of the current tick's findings into a single commit; the next tick handles the next review round.
92
+ - **Use `copilot-pull-request-reviewer[bot]` with the `[bot]` suffix for the reviewer ID.** That exact spelling is load-bearing — it is the only form the API accepts.
93
+
94
+ ## Examples
95
+
96
+ <example>
97
+ User: `/copilot-review`
98
+ Claude: [reads PR context, spawns background subagent with the Step 3 template, reports "subagent X watching PR #123; will notify on convergence"]
99
+ </example>
100
+
101
+ <example>
102
+ User: "babysit copilot on this PR until it's clean"
103
+ Claude: [same as above]
104
+ </example>
105
+
106
+ <example>
107
+ Subagent tick fires, latest Copilot review is against an older commit.
108
+ Subagent: [re-requests review, schedules next wakeup, returns]
109
+ </example>
110
+
111
+ <example>
112
+ Subagent tick fires, Copilot has 2 unaddressed inline findings on HEAD.
113
+ Subagent: [TDD-fixes both, one commit, pushes, replies inline on both threads, resolves both threads, re-requests review, schedules next wakeup]
114
+ </example>
115
+
116
+ <example>
117
+ Subagent tick fires, latest review is clean against HEAD.
118
+ Subagent: [reports convergence to parent, terminates — no further wakeups]
119
+ </example>
@@ -0,0 +1,49 @@
1
+ # Copilot-review subagent prompt template
2
+
3
+ The background watcher prompt for the `copilot-review` skill. The hub
4
+ ([`../SKILL.md`](../SKILL.md) Step 3) passes the fenced block below to the
5
+ subagent word for word, with the bracketed values ([NUMBER], [OWNER], [REPO],
6
+ [BRANCH], [HEAD_SHA]) filled in from Step 1.
7
+
8
+ ```text
9
+ You are babysitting the GitHub Copilot reviewer on PR **#[NUMBER]** at **[OWNER]/[REPO]** (branch `[BRANCH]`, current HEAD `[HEAD_SHA]`). Your job: keep the loop running until Copilot returns a clean review against the current HEAD, then stop.
10
+
11
+ **Per-tick work** (do this now, then on each wakeup):
12
+
13
+ 1. Resolve current HEAD: `pull_request_read(method="get", pullNumber=[NUMBER], owner="[OWNER]", repo="[REPO]")` and extract `.head.sha`.
14
+ 2. Fetch latest Copilot review via `pull_request_read(method="get_reviews", pullNumber=[NUMBER], owner="[OWNER]", repo="[REPO]")`.
15
+ Capture `commit_id`, `state`, `submitted_at`, `id`.
16
+ 3. Decide the branch:
17
+ - **No review exists:** increment `no_review_count` (see escalation rule below), re-request (step 4), schedule next wakeup, return.
18
+ - **Latest review's `commit_id` != current HEAD:** increment `no_review_count`, re-request (step 4), schedule next wakeup, return.
19
+ - **Latest review's `commit_id` == current HEAD with unresolved inline findings:** reset `no_review_count` to 0, TDD-fix them, push, reply inline on each thread, resolve each addressed thread, re-request (step 4), schedule next wakeup, return.
20
+ - **Latest review's `commit_id` == current HEAD and clean:** report convergence to the parent with a one-sentence summary and terminate. The loop is done; skip the ScheduleWakeup call.
21
+
22
+ **Escalation rule:** `no_review_count` starts at 0, counts consecutive ticks where no Copilot review exists at the current HEAD, and resets to 0 on every push and every review sighted at HEAD. When it reaches 3, Copilot is not delivering reviews — report the stall to the parent with the count and the last request timestamp, then terminate without scheduling another wakeup.
23
+ 4. Re-request Copilot via `request_copilot_review(owner="[OWNER]", repo="[REPO]", pullNumber=[NUMBER])`.
24
+ The reviewer ID **must** be `copilot-pull-request-reviewer[bot]` with the `[bot]` suffix — empirically verified: `Copilot`, `copilot`, and `github-copilot` all return `requested_reviewers: []` with no error, silently no-op.
25
+ 5. Schedule the next wakeup with `ScheduleWakeup`:
26
+ - `delaySeconds: 360`
27
+ - `reason`: one short sentence on what you are waiting for.
28
+ - `prompt`: the literal sentinel `<<autonomous-loop-dynamic>>` so the next firing re-enters these instructions.
29
+
30
+ **Fix protocol** (step 3, third branch):
31
+
32
+ - Read `$HOME/.claude/skills/pr-fix-protocol/SKILL.md` and apply it — it carries the shared fix sequence, the reply-and-resolve unit, and the unresolved-thread sweep.
33
+ - Read each referenced file:line.
34
+ - Write a failing test first when the finding has behavior to test. For pure doc or comment nits that have no behavior, go straight to the fix.
35
+ - Stage the fix and create one new commit on the existing branch: `git add <files> && git commit -m "fix(review): ..."`.
36
+ - Push the new commit: `git push origin [BRANCH]`.
37
+ - Reply inline via `add_reply_to_pull_request_comment(owner="[OWNER]", repo="[REPO]", pullNumber=[NUMBER], body="...", commentId=<comment_id>)`, referencing the new commit SHA; then resolve each addressed thread via `pull_request_review_write(method="resolve_thread", pullNumber=[NUMBER], owner="[OWNER]", repo="[REPO]", threadId="<PRRT id>")`, harvesting the `PRRT_…` id from `pull_request_read(method="get_review_comments", ...)`. Reply first, then resolve — atomic per thread, per the protocol.
38
+
39
+ When a pre-push, pre-commit, or other hook rejects the change, solve it. Read the hook's error message, diagnose the root cause in the code or test, and fix that. Then rerun the commit or push. Hooks exist to catch real problems; treat each rejection as new evidence to act on.
40
+
41
+ **Stop conditions:**
42
+
43
+ - Convergence (clean review against HEAD): report one-sentence summary to parent and terminate.
44
+ - Blocker you have exhausted fix attempts on (API auth failure persists, CI regression whose root cause falls outside this PR, a hook you have investigated and cannot resolve in one commit): report the specific blocker and its diagnosis to the parent, then terminate without scheduling another wakeup.
45
+ - Parent sends `TaskStop`: terminate immediately.
46
+ - `no_review_count` reaches 3 (escalation rule above): report the stall and terminate.
47
+
48
+ **Safety cap:** after 20 ticks without convergence, stop and report. This is the total-tick runaway guard, distinct from the 3-consecutive-no-review escalation; that many rounds means something structural is wrong with the loop.
49
+ ```
@@ -1,15 +1,12 @@
1
1
  # fresh-branch
2
2
 
3
- Creates a new branch from `origin/main` (always fresh-fetched). Triggered by `fresh branch`, `new branch from main`, `/fresh-branch`, or `start fresh`.
3
+ Creates a new branch from fresh-fetched `origin/main` inside an isolated worktree under `Temp/<agent>/<branch-name>`. Does not push, open a PR, or run `checkout -b` in the caller tree.
4
4
 
5
- ## Purpose
6
-
7
- A shared primitive used by other skills and directly by the user. Fetches `origin/main`, suggests 2–4 branch names via `AskUserQuestion` when a topic is available (polling recent branch naming patterns from `git branch -r`), then creates and checks out the branch with `git checkout -b <name> origin/main`.
8
-
9
- Does not push the branch. Does not create a PR. Does not switch an existing branch. Callers that need the new branch name (for example, to open a PR) receive it as a return value.
10
-
11
- ## Key file
5
+ ## Key files
12
6
 
13
7
  | File | Purpose |
14
8
  |---|---|
15
- | `SKILL.md` | Four-phase instructions: fetch `origin/main`, pick branch name (suggest or prompt), create branch, report. Includes gotchas discovered during use. |
9
+ | `SKILL.md` | Phases, checklist, execute-vs-read for the CLI, gotchas |
10
+ | `scripts/create_fresh_branch.py` | Deterministic CLI: fetch base, `git worktree add -b`, JSON stdout |
11
+ | `scripts/test_create_fresh_branch.py` | Behavioral tests with temporary git repos |
12
+ | `scripts/fresh_branch_scripts_constants/` | Constants package (`fresh_branch_cli_constants`) for the CLI |