claude-dev-env 2.0.2 → 2.2.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.
- package/CLAUDE.md +1 -1
- package/hooks/blocking/CLAUDE.md +1 -0
- package/hooks/blocking/code_rules_shared.py +126 -47
- package/hooks/blocking/config/CLAUDE.md +2 -0
- package/hooks/blocking/config/verified_commit_context_constants.py +21 -0
- package/hooks/blocking/config/verified_commit_gate_output_constants.py +14 -0
- package/hooks/blocking/conftest.py +36 -30
- package/hooks/blocking/convergence_gate_blocker.py +76 -8
- package/hooks/blocking/plain_language_blocker.py +8 -0
- package/hooks/blocking/state_description_blocker.py +4 -1
- package/hooks/blocking/test_code_rules_shared.py +120 -20
- package/hooks/blocking/test_convergence_gate_blocker.py +146 -0
- package/hooks/blocking/test_plain_language_blocker.py +15 -0
- package/hooks/blocking/test_state_description_blocker.py +15 -0
- package/hooks/blocking/test_verified_commit_config_bootstrap.py +18 -0
- package/hooks/blocking/test_verified_commit_gate_additional_context.py +134 -0
- package/hooks/blocking/tests/test_verified_commit_gate.py +41 -0
- package/hooks/blocking/verified_commit_config_bootstrap.py +22 -10
- package/hooks/blocking/verified_commit_gate.py +113 -568
- package/hooks/blocking/verified_commit_gate_parts/CLAUDE.md +28 -0
- package/hooks/blocking/verified_commit_gate_parts/__init__.py +1 -0
- package/hooks/blocking/verified_commit_gate_parts/command_tokenization.py +174 -0
- package/hooks/blocking/verified_commit_gate_parts/deny_payload.py +53 -0
- package/hooks/blocking/verified_commit_gate_parts/deny_reason.py +80 -0
- package/hooks/blocking/verified_commit_gate_parts/directory_resolution.py +170 -0
- package/hooks/blocking/verified_commit_gate_parts/gated_invocations.py +205 -0
- package/hooks/blocking/verified_commit_gate_parts/tests/conftest.py +10 -0
- package/hooks/blocking/verified_commit_gate_parts/tests/test_command_tokenization.py +94 -0
- package/hooks/blocking/verified_commit_gate_parts/tests/test_deny_payload.py +17 -0
- package/hooks/blocking/verified_commit_gate_parts/tests/test_deny_reason.py +38 -0
- package/hooks/blocking/verified_commit_gate_parts/tests/test_directory_resolution.py +71 -0
- package/hooks/blocking/verified_commit_gate_parts/tests/test_gated_invocations.py +61 -0
- package/hooks/hooks_constants/CLAUDE.md +4 -1
- package/hooks/hooks_constants/code_rules_path_utils_constants.py +1 -0
- package/hooks/hooks_constants/convergence_gate_blocker_constants.py +36 -0
- package/hooks/hooks_constants/harness_scratchpad_constants.py +10 -9
- package/hooks/hooks_constants/mypy_integration_constants.py +16 -0
- package/hooks/validators/mypy_integration.py +145 -24
- package/hooks/validators/python_antipattern_checks.py +16 -0
- package/hooks/validators/run_all_validators.py +9 -3
- package/hooks/validators/test_mypy_integration.py +154 -0
- package/hooks/validators/test_python_antipattern_checks.py +112 -1
- package/hooks/validators/test_run_all_validators_pretooluse.py +16 -0
- package/package.json +1 -1
- package/rules/CLAUDE.md +1 -0
- package/rules/verified-commit-gate-skip.md +28 -0
- package/skills/_shared/pr-loop/CLAUDE.md +18 -13
- package/skills/_shared/pr-loop/portable-driver.md +150 -0
- package/skills/_shared/pr-loop/scripts/CLAUDE.md +3 -0
- package/skills/_shared/pr-loop/scripts/build_converge_task_list.py +310 -0
- package/skills/_shared/pr-loop/scripts/portable_converge_driver.py +1637 -0
- package/skills/_shared/pr-loop/scripts/select_converge_pacer.py +215 -0
- package/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/CLAUDE.md +3 -0
- package/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/converge_task_list_constants.py +56 -0
- package/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/pacer_constants.py +47 -0
- package/skills/_shared/pr-loop/scripts/skills_pr_loop_constants/portable_driver_constants.py +181 -0
- package/skills/_shared/pr-loop/scripts/test_build_converge_task_list.py +140 -0
- package/skills/_shared/pr-loop/scripts/test_portable_converge_driver.py +1119 -0
- package/skills/_shared/pr-loop/scripts/test_select_converge_pacer.py +207 -0
- package/skills/auditing-claude-config/CLAUDE.md +2 -1
- package/skills/auditing-claude-config/SKILL.md +114 -176
- package/skills/auditing-claude-config/reference/probe-hook.md +74 -0
- package/skills/autoconverge/CLAUDE.md +6 -3
- package/skills/autoconverge/SKILL.md +421 -346
- package/skills/autoconverge/reference/CLAUDE.md +1 -0
- package/skills/autoconverge/reference/convergence.md +5 -5
- package/skills/autoconverge/reference/copilot-findings.md +51 -0
- package/skills/autoconverge/reference/multi-pr.md +33 -2
- package/skills/autoconverge/reference/stop-conditions.md +9 -6
- package/skills/autoconverge/test_portable_pacer_gate.py +54 -0
- package/skills/closeout/SKILL.md +7 -9
- package/skills/copilot-finding-triage/SKILL.md +21 -11
- package/skills/copilot-review/CLAUDE.md +3 -2
- package/skills/copilot-review/SKILL.md +119 -155
- package/skills/copilot-review/templates/subagent-prompt.md +49 -0
- package/skills/fresh-branch/CLAUDE.md +6 -9
- package/skills/fresh-branch/SKILL.md +84 -33
- package/skills/fresh-branch/scripts/create_fresh_branch.py +445 -0
- package/skills/fresh-branch/scripts/fresh_branch_scripts_constants/__init__.py +1 -0
- package/skills/fresh-branch/scripts/fresh_branch_scripts_constants/fresh_branch_cli_constants.py +74 -0
- package/skills/fresh-branch/scripts/test_create_fresh_branch.py +670 -0
- package/skills/pr-converge/CLAUDE.md +4 -3
- package/skills/pr-converge/SKILL.md +469 -422
- package/skills/pr-converge/reference/CLAUDE.md +1 -0
- package/skills/pr-converge/reference/multi-pr-orchestration.md +5 -1
- package/skills/pr-converge/reference/per-tick.md +51 -24
- package/skills/pr-converge/reference/progress-checklist.md +168 -0
- package/skills/pr-converge/test_portable_pacer_gate.py +67 -0
- package/skills/pr-converge/test_step5_host_branch.py +8 -6
- package/skills/pr-converge/workflows/schedule-wakeup-loop.md +5 -3
- package/skills/pr-loop-cloud-transport/SKILL.md +1 -1
- package/skills/privacy-hygiene/SKILL.md +68 -115
- package/skills/privacy-hygiene/reference/sweep-procedure.md +62 -0
- package/skills/session-log/CLAUDE.md +2 -1
- package/skills/session-log/SKILL.md +4 -26
- package/skills/session-log/templates/frontmatter.md +40 -0
- package/skills/skill-builder/CLAUDE.md +8 -7
- package/skills/skill-builder/SKILL.md +26 -11
- package/skills/skill-builder/references/CLAUDE.md +3 -1
- package/skills/skill-builder/references/delegation-map.md +21 -12
- package/skills/skill-builder/references/description-field.md +9 -11
- package/skills/skill-builder/references/deterministic-elements.md +218 -0
- package/skills/skill-builder/references/self-audit-checklist.md +62 -45
- package/skills/skill-builder/references/skill-modularity.md +8 -9
- package/skills/skill-builder/templates/CLAUDE.md +2 -2
- package/skills/skill-builder/templates/gap-analysis.md +15 -0
- package/skills/skill-builder/workflows/CLAUDE.md +5 -5
- package/skills/skill-builder/workflows/improve-skill.md +18 -9
- package/skills/skill-builder/workflows/new-skill.md +23 -15
- 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. |
|
|
@@ -66,11 +66,11 @@ confirmation gates that are expected to return zero.
|
|
|
66
66
|
- **Code-review lens** — a correctness-focused review pass (`code-quality-agent`),
|
|
67
67
|
report-only workflow agent — see runCodeReviewLens in workflow/converge.mjs for its configuration.
|
|
68
68
|
The built-in `/code-review` command is a separate surface outside this
|
|
69
|
-
workflow path.
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
69
|
+
workflow path. On `pacer=workflow`, this lens runs inside `converge.mjs`.
|
|
70
|
+
On `pacer=portable`, the continuous driver uses the pr-converge CODE_REVIEW
|
|
71
|
+
phase through `invoke_code_review.py` instead of `runCodeReviewLens`
|
|
72
|
+
([`../../_shared/pr-loop/portable-driver.md`](../../_shared/pr-loop/portable-driver.md);
|
|
73
|
+
[`../../pr-converge/reference/per-tick.md`](../../pr-converge/reference/per-tick.md)).
|
|
74
74
|
- **Bug-audit lens** — the bug-audit (`code-quality-agent`) applying the
|
|
75
75
|
shared A–P rubric from `_shared/pr-loop/audit-contract.md`, then its
|
|
76
76
|
adversarial second pass, and the doc-parity, test-assertion, and
|
|
@@ -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.
|
|
@@ -42,7 +42,27 @@ each PR its own checkout with `git worktree add`. For each PR the user named:
|
|
|
42
42
|
non-zero exit sets `copilotDisabled: true` on every entry, so each child skips
|
|
43
43
|
the Copilot gate with no agent spawned.
|
|
44
44
|
|
|
45
|
-
## Launch
|
|
45
|
+
## Launch
|
|
46
|
+
|
|
47
|
+
Select the pacer once for the multi-PR run (same helper as single-PR):
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
python "$HOME/.claude/skills/_shared/pr-loop/scripts/select_converge_pacer.py" \
|
|
51
|
+
--skill autoconverge \
|
|
52
|
+
--has-workflow <0|1> \
|
|
53
|
+
--has-schedule-wakeup <0|1>
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### `pacer=portable`
|
|
57
|
+
|
|
58
|
+
Do **not** call `Workflow`. For each PR worktree from pre-flight, run the
|
|
59
|
+
continuous portable driver in
|
|
60
|
+
[`../../_shared/pr-loop/portable-driver.md`](../../_shared/pr-loop/portable-driver.md)
|
|
61
|
+
(serial, or host fan-out when the host can isolate workers). One teardown per
|
|
62
|
+
PR after that PR reaches ready or a named blocker. Shared Copilot quota and
|
|
63
|
+
permission grants from multi-PR pre-flight still apply once.
|
|
64
|
+
|
|
65
|
+
### `pacer=workflow`
|
|
46
66
|
|
|
47
67
|
Call the `Workflow` tool against the fan-out script, passing the absolute path of
|
|
48
68
|
`converge.mjs` and one entry per PR:
|
|
@@ -74,7 +94,18 @@ Each record's `deferredPrs` is that PR's own list of draft hardening PRs, and
|
|
|
74
94
|
`allDeferredPrs` is every record's `deferredPrs` flattened into one list. The
|
|
75
95
|
top-level `converged` is true only when every PR converged.
|
|
76
96
|
|
|
77
|
-
## Multi-PR teardown
|
|
97
|
+
## Multi-PR teardown
|
|
98
|
+
|
|
99
|
+
### `pacer=portable`
|
|
100
|
+
|
|
101
|
+
For each PR worktree, run the single-PR **Teardown → pacer=portable** path in
|
|
102
|
+
[`SKILL.md`](../SKILL.md) (`pr-loop-lifecycle` Close, no Workflow journal
|
|
103
|
+
report). Write one durable handoff per PR with that PR's `--pr-number` and
|
|
104
|
+
resume command `/autoconverge <PR URL>`. Revoke project permissions once per
|
|
105
|
+
repository after every PR's close. Print one summary line per PR as
|
|
106
|
+
`#<prNumber>: <converged | blocked> — rounds <N>, final <finalSha>[, blocker <blocker>]`.
|
|
107
|
+
|
|
108
|
+
### `pacer=workflow` (on workflow completion)
|
|
78
109
|
|
|
79
110
|
Run the single-PR Teardown in [`SKILL.md`](../SKILL.md) once per entry in
|
|
80
111
|
`results`, using that PR's `owner`, `repo`, `prNumber`, and `finalSha`, and its
|
|
@@ -6,14 +6,17 @@ skill still runs teardown (revoke permissions, final report).
|
|
|
6
6
|
|
|
7
7
|
## Blockers (end the run short of ready)
|
|
8
8
|
|
|
9
|
-
- **Budget stop** — the workflow's `budget` API is the
|
|
10
|
-
usage target is set, `converge.mjs` checks
|
|
11
|
-
round and stops at the round boundary when
|
|
12
|
-
lenses + one fix commit + re-verify) does not
|
|
13
|
-
`blocker: "budget"` with the run id; resume with
|
|
9
|
+
- **Budget stop** — on `pacer=workflow`, the workflow's `budget` API is the
|
|
10
|
+
pacing signal: when a usage target is set, `converge.mjs` checks
|
|
11
|
+
`budget.remaining()` before each round and stops at the round boundary when
|
|
12
|
+
one full round (three parallel lenses + one fix commit + re-verify) does not
|
|
13
|
+
fit. The run returns `blocker: "budget"` with the run id; resume with
|
|
14
14
|
`Workflow({scriptPath, resumeFromRunId})` — completed rounds replay from the
|
|
15
15
|
journal. The workflow never starts a round the budget cannot finish: a
|
|
16
|
-
half-run round records nothing resumable and replays dirty.
|
|
16
|
+
half-run round records nothing resumable and replays dirty. On
|
|
17
|
+
`pacer=portable`, stop at a tick boundary when the session cannot cover a
|
|
18
|
+
full clean tick; write handoff and resume with `/autoconverge <PR URL>`
|
|
19
|
+
([`../../_shared/pr-loop/portable-driver.md`](../../_shared/pr-loop/portable-driver.md)).
|
|
17
20
|
- **Iteration cap** — 20 loop iterations pass without a full convergence-check
|
|
18
21
|
pass. The iteration counter increments on every pass through any phase, so a
|
|
19
22
|
convergence-check gate that no round can clear (for example a `mergeable_state`
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"""Contract checks: autoconverge selects a portable pacer when Workflow is absent."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import re
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
|
|
8
|
+
SKILL_ROOT = Path(__file__).resolve().parent
|
|
9
|
+
SKILL_MARKDOWN_PATH = SKILL_ROOT / "SKILL.md"
|
|
10
|
+
MULTI_PR_MARKDOWN_PATH = SKILL_ROOT / "reference" / "multi-pr.md"
|
|
11
|
+
PORTABLE_DRIVER_PATH = (
|
|
12
|
+
SKILL_ROOT.parent / "_shared" / "pr-loop" / "portable-driver.md"
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
SELECT_CONVERGE_PACER_SCRIPT = "select_converge_pacer.py"
|
|
16
|
+
PACER_PORTABLE_TOKEN = "pacer=portable"
|
|
17
|
+
PACER_WORKFLOW_TOKEN = "pacer=workflow"
|
|
18
|
+
ABORT_ONLY_PHRASE = "autoconverge requires the Workflow tool"
|
|
19
|
+
PORTABLE_DRIVER_DOC = "portable-driver.md"
|
|
20
|
+
PORTABLE_DRIVER_LINK_PATTERN = re.compile(
|
|
21
|
+
r"\((?P<relative>(?:\.\./)+_shared/pr-loop/portable-driver\.md)\)"
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def test_skill_selects_pacer_and_forbids_abort_only_workflow() -> None:
|
|
26
|
+
skill_text = SKILL_MARKDOWN_PATH.read_text(encoding="utf-8")
|
|
27
|
+
assert SELECT_CONVERGE_PACER_SCRIPT in skill_text
|
|
28
|
+
assert PACER_PORTABLE_TOKEN in skill_text
|
|
29
|
+
assert PACER_WORKFLOW_TOKEN in skill_text
|
|
30
|
+
assert PORTABLE_DRIVER_DOC in skill_text
|
|
31
|
+
assert ABORT_ONLY_PHRASE not in skill_text
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def test_skill_portable_driver_links_resolve_on_disk() -> None:
|
|
35
|
+
skill_text = SKILL_MARKDOWN_PATH.read_text(encoding="utf-8")
|
|
36
|
+
all_relative_links = PORTABLE_DRIVER_LINK_PATTERN.findall(skill_text)
|
|
37
|
+
assert all_relative_links, "SKILL.md must link portable-driver.md"
|
|
38
|
+
for each_relative_link in all_relative_links:
|
|
39
|
+
resolved_path = (SKILL_MARKDOWN_PATH.parent / each_relative_link).resolve()
|
|
40
|
+
assert resolved_path.is_file(), (
|
|
41
|
+
f"portable-driver link must resolve on disk: "
|
|
42
|
+
f"{each_relative_link} -> {resolved_path}"
|
|
43
|
+
)
|
|
44
|
+
assert resolved_path == PORTABLE_DRIVER_PATH.resolve()
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def test_multi_pr_documents_portable_launch_and_teardown() -> None:
|
|
48
|
+
multi_pr_text = MULTI_PR_MARKDOWN_PATH.read_text(encoding="utf-8")
|
|
49
|
+
assert PACER_PORTABLE_TOKEN in multi_pr_text
|
|
50
|
+
assert "Do **not** call `Workflow`" in multi_pr_text or (
|
|
51
|
+
"Do not call `Workflow`" in multi_pr_text
|
|
52
|
+
)
|
|
53
|
+
assert "pacer=portable" in multi_pr_text
|
|
54
|
+
assert PORTABLE_DRIVER_DOC in multi_pr_text
|
package/skills/closeout/SKILL.md
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: closeout
|
|
3
3
|
description: >-
|
|
4
|
-
Harvests session obstacles into GitHub issues backed by quoted evidence
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
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
|
|
@@ -117,9 +115,21 @@ counts as approval.
|
|
|
117
115
|
|
|
118
116
|
### Step 2 — Hold and wait
|
|
119
117
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
118
|
+
Branch the hold on the caller's pacer (or on whether a durable wake surface is
|
|
119
|
+
present when the caller has not selected a pacer):
|
|
120
|
+
|
|
121
|
+
- **Native pacer** (`pacer=schedule_wakeup`, `pacer=workflow`, or
|
|
122
|
+
`ScheduleWakeup` present): arm `ScheduleWakeup` for a 45-minute deadline.
|
|
123
|
+
Where `ScheduleWakeup` is absent on that native path, use `send_later`.
|
|
124
|
+
- **Portable pacer** (`pacer=portable`, or no durable wake): do not call
|
|
125
|
+
`ScheduleWakeup` or `send_later`. Hold with an in-session deadline poll, or
|
|
126
|
+
write handoff and stop, per
|
|
127
|
+
[`../_shared/pr-loop/portable-driver.md`](../_shared/pr-loop/portable-driver.md).
|
|
128
|
+
Callers may override this step after the ntfy page and apply their own
|
|
129
|
+
portable hold.
|
|
130
|
+
|
|
131
|
+
The clock starts when the page reaches the user, which is the moment the script
|
|
132
|
+
exits zero.
|
|
123
133
|
|
|
124
134
|
- If the user answers, follow their direction.
|
|
125
135
|
- If the deadline passes with no answer, run the caller's normal teardown and
|
|
@@ -143,7 +153,7 @@ its fix re-runs that same check and posts the before/after output on the thread.
|
|
|
143
153
|
evidence note.
|
|
144
154
|
- [ ] The page carries the PR name, the per-finding summary, and the review URL.
|
|
145
155
|
- [ ] `scripts/notify_ntfy.py` exited zero before the 45-minute clock started.
|
|
146
|
-
- [ ] The
|
|
156
|
+
- [ ] The hold is armed from a delivered page (45-minute `ScheduleWakeup` / `send_later` on native pacer; portable in-session poll or handoff on `pacer=portable`).
|
|
147
157
|
- [ ] A failed page kept the gate open rather than approving the round.
|
|
148
158
|
|
|
149
159
|
## Files
|
|
@@ -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
|
|
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),
|
|
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
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
>
|
|
100
|
-
|
|
101
|
-
>
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
>
|
|
105
|
-
|
|
106
|
-
>
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
>
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
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>
|