@clipboard-health/ai-rules 2.32.0 → 2.34.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/package.json +1 -1
- package/skills/cb-babysit/SKILL.md +6 -6
- package/skills/cb-babysit/scripts/_sentinel.sh +1 -1
- package/skills/cb-babysit/scripts/commitAndPush.sh +4 -2
- package/skills/cb-review/SKILL.md +231 -0
- package/skills/{simple-review → cb-review}/references/cross-repo-evidence.md +14 -1
- package/skills/cb-review/references/multi-agent.md +68 -0
- package/skills/{simple-review → cb-review}/references/posting-pr-review.md +5 -11
- package/skills/cb-review/references/review-rubric.md +194 -0
- package/skills/cb-ship/SKILL.md +7 -5
- package/skills/cb-ship/references/pr-template.md +1 -1
- package/skills/cb-work/SKILL.md +1 -0
- package/skills/in-depth-review/SKILL.md +0 -491
- package/skills/in-depth-review/references/cross-repo-evidence.md +0 -37
- package/skills/in-depth-review/references/posting-pr-review.md +0 -105
- package/skills/simple-review/SKILL.md +0 -474
package/package.json
CHANGED
|
@@ -19,9 +19,9 @@ Resolve bundled "./scripts" paths relative to SKILL.md.
|
|
|
19
19
|
|
|
20
20
|
The skill uses two sentinels with visible footer lines.
|
|
21
21
|
|
|
22
|
-
**Addressed sentinel**: `<sub>🤖 <code>cb-babysit:addressed v1 core@3.
|
|
22
|
+
**Addressed sentinel**: `<sub>🤖 <code>cb-babysit:addressed v1 core@3.15.0</code></sub>`. Appended on its own line at the end of every reply the skill posts so re-runs know which threads and review-body comments are already handled. Dedupe also recognizes the legacy `babysit-pr:addressed v1` prefix from before this skill was renamed.
|
|
23
23
|
|
|
24
|
-
**Follow-up sentinel**: `<sub>🤖 <code>cb-babysit:followup v1 core@3.
|
|
24
|
+
**Follow-up sentinel**: `<sub>🤖 <code>cb-babysit:followup v1 core@3.15.0</code></sub>`. Attached to replies that defer an out-of-scope comment as a tracked follow-up. The sentinel is additive: the post-reply scripts still append the `addressed` sentinel at the end.
|
|
25
25
|
|
|
26
26
|
**Sentinel recency rules.** The script emits a per-thread `activityState` with three values. Step 6a owns the handling rules for each state.
|
|
27
27
|
|
|
@@ -67,10 +67,10 @@ If `mergeable == "CONFLICTING"` (or `mergeStateStatus == "DIRTY"`), merge the ba
|
|
|
67
67
|
```bash
|
|
68
68
|
BASE=$(gh pr view --json baseRefName --jq .baseRefName)
|
|
69
69
|
git fetch origin "$BASE"
|
|
70
|
-
git merge --no-edit "origin/$BASE"
|
|
70
|
+
git merge --no-edit --no-gpg-sign "origin/$BASE"
|
|
71
71
|
```
|
|
72
72
|
|
|
73
|
-
Resolve directly only for lockfile/generated regenerations, additive non-overlapping edits, or trivial textual conflicts in PR-touched files. `git merge --abort` for anything semantic, ambiguous, or outside the PR's intentional surface, and skip to step 10 to exit **stuck** with a diagnosis. After a clean resolution, commit the merge and `git push origin HEAD`.
|
|
73
|
+
Resolve directly only for lockfile/generated regenerations, additive non-overlapping edits, or trivial textual conflicts in PR-touched files. `git merge --abort` for anything semantic, ambiguous, or outside the PR's intentional surface, and skip to step 10 to exit **stuck** with a diagnosis. After a clean resolution, commit the merge with `git commit --no-gpg-sign` and `git push origin HEAD`.
|
|
74
74
|
|
|
75
75
|
### 3. Wait for CI
|
|
76
76
|
|
|
@@ -247,7 +247,7 @@ Body templates (the script appends the `addressed` sentinel if missing):
|
|
|
247
247
|
- **Agree**: `Addressed in <commit-url>. <one-line what-changed>.`
|
|
248
248
|
- **Disagree**: `Leaving current behavior. <reasoning>.`
|
|
249
249
|
- **Already fixed**: `Already handled by <commit-url-or-file:line>. <brief pointer>.`
|
|
250
|
-
- **Defer**: `Out of scope for this PR; this looks like follow-up work rather than something introduced or required by this change. <one-line rationale or pointer if useful>.\n\n<sub>🤖 <code>cb-babysit:followup v1 core@3.
|
|
250
|
+
- **Defer**: `Out of scope for this PR; this looks like follow-up work rather than something introduced or required by this change. <one-line rationale or pointer if useful>.\n\n<sub>🤖 <code>cb-babysit:followup v1 core@3.15.0</code></sub>`
|
|
251
251
|
|
|
252
252
|
For Defer replies, include the follow-up sentinel on its own line as shown. The script will append the `addressed` sentinel after it on its own line, so the final body ends with the follow-up sentinel followed by a blank line followed by the `addressed` sentinel. `grep cb-babysit:followup` finds the deferral and `grep cb-babysit:addressed` still marks the thread handled for dedupe.
|
|
253
253
|
|
|
@@ -263,7 +263,7 @@ The PR-level summary should:
|
|
|
263
263
|
|
|
264
264
|
- Group by source. Use `## Review-body findings` for step-7 work and `## Conversation-tab comments` for step-6b work. Omit a section if its list is empty.
|
|
265
265
|
- Inside each section, group verdicts under **Agree / Disagree / Already fixed / Deferred (out of scope)** subheadings. Omit a subheading if its list is empty.
|
|
266
|
-
- Under **Deferred (out of scope)**, list each deferred item as a bullet, followed on its own line by `<sub>🤖 <code>cb-babysit:followup v1 core@3.
|
|
266
|
+
- Under **Deferred (out of scope)**, list each deferred item as a bullet, followed on its own line by `<sub>🤖 <code>cb-babysit:followup v1 core@3.15.0</code></sub>` so grep catches them individually.
|
|
267
267
|
- Include the commit URL for fixes.
|
|
268
268
|
- End with a fenced fingerprint block listing every current fingerprint (addressed and deferred) one per line. Include both `reviewBodyComments[].fingerprint` (whole-body, one per automated review) and `activeIssueComments[].fingerprint` (per Conversation-tab comment). Future runs dedupe by matching these against `priorBabysitSentinels`.
|
|
269
269
|
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
SENTINEL_PREFIX='cb-babysit:addressed v1 '
|
|
12
12
|
LEGACY_SENTINEL_PREFIX='babysit-pr:addressed v1 '
|
|
13
|
-
SENTINEL='<sub>🤖 <code>cb-babysit:addressed v1 core@3.
|
|
13
|
+
SENTINEL='<sub>🤖 <code>cb-babysit:addressed v1 core@3.15.0</code></sub>'
|
|
14
14
|
|
|
15
15
|
# Bot author allowlist (JSON array literal). Used by unresolvedPrComments.sh
|
|
16
16
|
# as a fallback when GraphQL's `author.__typename == "Bot"` misses a GitHub
|
|
@@ -9,7 +9,9 @@
|
|
|
9
9
|
#
|
|
10
10
|
# Does NOT use `git add -A` — the caller MUST name every file to stage, so the
|
|
11
11
|
# skill never sweeps up unrelated uncommitted work. Does NOT skip hooks
|
|
12
|
-
# (no --no-verify); a hook failure surfaces as a non-zero exit.
|
|
12
|
+
# (no --no-verify); a hook failure surfaces as a non-zero exit. Commits with
|
|
13
|
+
# --no-gpg-sign (cb-ship's convention) — agent runs can't service a signing
|
|
14
|
+
# prompt, and a missing signer otherwise fails the commit after hooks pass.
|
|
13
15
|
#
|
|
14
16
|
# Exit 0 on success. Exit 1 on runtime errors. Exit 2 on usage errors.
|
|
15
17
|
#
|
|
@@ -51,7 +53,7 @@ if git diff --cached --quiet; then
|
|
|
51
53
|
exit 1
|
|
52
54
|
fi
|
|
53
55
|
|
|
54
|
-
git commit -m "$MSG"
|
|
56
|
+
git commit --no-gpg-sign -m "$MSG"
|
|
55
57
|
git push
|
|
56
58
|
|
|
57
59
|
SHA="$(git rev-parse HEAD)"
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cb-review
|
|
3
|
+
description: Code review of a diff, branch, or PR, with findings posted as anchored PR comments. Use when the user asks to review a diff, branch, or PR, asks to check a change against its ticket/spec/PRD, or runs /cb-review [pr-number-or-url] [--effort low|high] [--report].
|
|
4
|
+
argument-hint: "[pr-number-or-url] [--effort low|high] [--report]"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# CB Review
|
|
8
|
+
|
|
9
|
+
Review a diff against one rubric, filter to the few findings worth raising, gate with the user, optionally post as anchored PR comments. `--report` replaces the gates with a findings report for an agent caller. Two engines share everything except how the rubric is applied:
|
|
10
|
+
|
|
11
|
+
- **low** — one reviewer subagent, single pass. Default.
|
|
12
|
+
- **high** — parallel reviewer subagents, one debate round, moderator filter. For large or high-stakes diffs.
|
|
13
|
+
|
|
14
|
+
## Invocation
|
|
15
|
+
|
|
16
|
+
- `/cb-review` — review the current branch (resolves the open PR for the branch if any, otherwise diffs against the default branch).
|
|
17
|
+
- `/cb-review <pr-number-or-url>` — review that PR without checking it out; forces reviewer mode. Accepts a bare number (current repo) or full GitHub URL (identifies owner/repo).
|
|
18
|
+
- `--effort low|high` — pick the engine explicitly. Phrases also select: "quick"/"fast" → low; "deep"/"thorough"/"multi-perspective" → high.
|
|
19
|
+
- `--report` — non-interactive: stop after Synthesize and return the findings to the caller. No user gates, no posting, no implementing. For agent callers (e.g. cb-ship's review step).
|
|
20
|
+
|
|
21
|
+
**Effort auto-select** (no flag, no phrase): `high` when the diff exceeds 20 changed files or 600 changed lines, else `low`. Before reviewing, print one line — `Effort: <low|high> (<N> files, <M> lines; override with --effort <other>)` — so the user can interrupt.
|
|
22
|
+
|
|
23
|
+
## Scope
|
|
24
|
+
|
|
25
|
+
### Path A — PR-argument fast path (argument provided)
|
|
26
|
+
|
|
27
|
+
- Parse the argument: bare integer → `gh repo view --json nameWithOwner --jq .nameWithOwner`; URL → extract `<owner>/<repo>` and `<N>`.
|
|
28
|
+
- Do **not** check out the PR branch.
|
|
29
|
+
- Mode is **locked to reviewer**.
|
|
30
|
+
|
|
31
|
+
Gather in parallel:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
gh pr view <N> --repo <owner>/<repo> --json number,url,title,body,baseRefName,author,headRefOid,files
|
|
35
|
+
gh pr diff <N> --repo <owner>/<repo>
|
|
36
|
+
gh api user --jq .login
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
If `pr.author.login == viewer.login`, still proceed in reviewer mode but flag this in Summary so the user can switch to a current-branch run on their checkout if they meant to implement.
|
|
40
|
+
|
|
41
|
+
### Path B — current-branch path (no argument)
|
|
42
|
+
|
|
43
|
+
- Open PR for current branch → review that PR. Base = `baseRefName`, diff = `git diff $base...HEAD`. Context = PR title + body.
|
|
44
|
+
- No PR → diff vs default branch (`main`, fall back to `master`). Context = `git log --format='%h %s%n%n%b' $base..HEAD`.
|
|
45
|
+
- **Never** review uncommitted working-tree changes. Empty diff → stop and report.
|
|
46
|
+
|
|
47
|
+
Determine **mode**:
|
|
48
|
+
|
|
49
|
+
- PR exists and `pr.author.login == viewer.login` → **author mode**.
|
|
50
|
+
- PR exists and authors differ → **reviewer mode**.
|
|
51
|
+
- No PR → **author mode**.
|
|
52
|
+
|
|
53
|
+
**Persistence:** both efforts persist for subagents into a fresh per-run directory — `RUN_DIR=$(mktemp -d "${TMPDIR:-/tmp}/cb-review.XXXXXX")` — so concurrent sessions never clobber each other: diff → `$RUN_DIR/diff.patch`, context → `$RUN_DIR/context.md`, changed files → `$RUN_DIR/files.txt`, metadata (PR number/url/base/author, viewer, head SHA, owner/repo, mode, `context_ref`) → `$RUN_DIR/meta.json`.
|
|
54
|
+
|
|
55
|
+
## Freshness preflight (mandatory before reading code)
|
|
56
|
+
|
|
57
|
+
Stale local state produces false-positive findings. Before reviewing, verify the ref you'll read for context is current.
|
|
58
|
+
|
|
59
|
+
Run on the **primary repo** (the one containing the diff):
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
git fetch origin "$base" --quiet
|
|
63
|
+
git rev-parse --abbrev-ref HEAD
|
|
64
|
+
git status --porcelain
|
|
65
|
+
git rev-list --left-right --count "HEAD...origin/${base}"
|
|
66
|
+
git log -1 --format='%h %ci' "origin/${base}"
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Decide `context_ref`:
|
|
70
|
+
|
|
71
|
+
- **Path A (reviewer):** `context_ref = origin/${base}`. The worktree may be used only when `HEAD == origin/${base}` AND clean AND fetch succeeded.
|
|
72
|
+
- **Path B (author):** `context_ref = origin/${base}`. The local feature branch IS the diff; pre-PR context comes from `origin/${base}`.
|
|
73
|
+
|
|
74
|
+
Stop and ask the user when:
|
|
75
|
+
|
|
76
|
+
1. `git fetch` failed (offline, auth).
|
|
77
|
+
2. Path B: working tree is dirty AND dirty paths overlap the diff's changed-file list or anything you'll need to read.
|
|
78
|
+
3. Path B: `HEAD` is behind `origin/${base}` (any non-zero "behind") — findings may target code the base has already changed.
|
|
79
|
+
|
|
80
|
+
Warn template (substitute verified state):
|
|
81
|
+
|
|
82
|
+
> Freshness check for `<owner>/<repo>` at `<worktree-path>`:
|
|
83
|
+
>
|
|
84
|
+
> - on branch `<HEAD-branch>`
|
|
85
|
+
> - `<N>` ahead, `<M>` behind `origin/<base>` (last: `<short-sha> <iso-date>`)
|
|
86
|
+
> - working tree: `<clean | dirty: N file(s)>`
|
|
87
|
+
>
|
|
88
|
+
> Reading from this worktree may surface findings based on stale state.
|
|
89
|
+
> Reply: `proceed` (use worktree, accept the risk), `use-origin` (read context via `git show origin/<base>:<path>` — recommended), or `stop`.
|
|
90
|
+
|
|
91
|
+
**Never** run `git checkout`, `stash`, `reset`, or other state-modifying git on the user's behalf. The skill warns and asks; the user resolves local state. `git fetch` is allowed (read-only).
|
|
92
|
+
|
|
93
|
+
On Path A, local branch state never blocks the review — all reads go through origin refs, no checkout needed. When `HEAD` differs from `origin/${base}` or the tree is dirty, fetch the PR head to a local ref:
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
git fetch origin "pull/<N>/head:refs/remotes/origin/pr-<N>" --quiet
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Then read PR-head content via `git show origin/pr-<N>:<path>` and base context via `git show origin/<base>:<path>`. No checkout needed.
|
|
100
|
+
|
|
101
|
+
### Reading code
|
|
102
|
+
|
|
103
|
+
When `context_ref = origin/<base>` (or `origin/pr-<N>` for PR head):
|
|
104
|
+
|
|
105
|
+
- Read via `git show "${context_ref}:<path>"` (whole files) or `git grep -n <pattern> "${context_ref}" -- <paths>` (search).
|
|
106
|
+
- Avoid reading the worktree filesystem for tracked content — it may be stale.
|
|
107
|
+
- Worktree reads are OK only for files brand-new in the diff (untracked at `context_ref`); note "verified against: worktree" in the finding.
|
|
108
|
+
|
|
109
|
+
When `context_ref = worktree (stale, user accepted risk)`:
|
|
110
|
+
|
|
111
|
+
- Worktree reads are OK but every CRITICAL/MAJOR finding is downgraded to MINOR unless evidence is internal to the diff itself. Tag each finding with "verified against: worktree-stale".
|
|
112
|
+
|
|
113
|
+
## Cross-repo evidence policy
|
|
114
|
+
|
|
115
|
+
A finding's evidence is "cross-repo" when its load-bearing claim depends on code in any repo other than the one containing the diff. Read [references/cross-repo-evidence.md](references/cross-repo-evidence.md) before raising or finalizing any cross-repo finding — it has when the policy fires, the verify-or-downgrade procedure, the severity cap, the access-request template, and what "verify" means for contract/schema vs API-response changes.
|
|
116
|
+
|
|
117
|
+
## Diff classification (pick which lenses apply)
|
|
118
|
+
|
|
119
|
+
Walk the changed-file list. Activate lenses that match:
|
|
120
|
+
|
|
121
|
+
- **Security** triggers on: `routes/`, `controllers/`, `middleware*/`, files matching `auth*`/`*permission*`/`*acl*`/`*token*`/`*session*`, response serializers, OpenAPI/contract definitions, new API endpoint files.
|
|
122
|
+
- **Database** triggers on: `migrations/`, `*.sql`, files matching `schema*`, Mongoose/Prisma model files (`models/`, `*.model.ts`, `*.schema.ts`), repository/DAL files, query builders.
|
|
123
|
+
- **Frontend** triggers on: `*.tsx`, `*.jsx`, `*.css`, `*.scss`, `pages/`, `components/`, `hooks/`, or anything importing from `react`, `@tanstack/react-query`, or a design-system package.
|
|
124
|
+
- **Spec** triggers when a spec source exists. Look in order: (1) issue/ticket references in the PR body or commit messages (`#123`, `Closes #45`, Linear/Jira keys) — fetch via `gh` or the tracker; (2) a path the user passed as an argument; (3) a plan/PRD file under `docs/`, `specs/`, or `.scratch/` matching the branch or feature name. Nothing found → skip the lens and note "no spec available" in Summary.
|
|
125
|
+
|
|
126
|
+
Always-on lenses: **Engineering**, **Minimalism**, **Conventions**, **AntiSlop**.
|
|
127
|
+
|
|
128
|
+
## Review
|
|
129
|
+
|
|
130
|
+
The rubric — severity ladder, `failure_mode` contract, do-not-raise list, NIT gate, caps, `suggested_fix` schema, and every lens checklist — lives in [references/review-rubric.md](references/review-rubric.md). It is binding for both engines.
|
|
131
|
+
|
|
132
|
+
### Low effort
|
|
133
|
+
|
|
134
|
+
Dispatch **one** reviewer subagent — fresh eyes on the diff, and the bulk content stays out of your context. Its prompt carries the persisted file paths, the absolute path to references/review-rubric.md with the instruction to read it in full, the active lens list, and the two contracts from multi-agent.md §Dispatch mechanics (context-read, cross-repo evidence) with `<context_ref>` substituted and the moderator/Round-2 sentence replaced by: emit `evidence_required` findings capped at MAJOR; the dispatching agent resolves them in the Filter's cross-repo audit. Finding ids use an `R` prefix in place of roster letters. The subagent walks the diff, applying every active lens — the walk is done only when every hunk has been read under each active lens. Exhaustive reading, selective output: it returns _the smallest number of high-signal findings_ in the Round 1 output shape (multi-agent.md §Round 1), flagging anything that needs deeper investigation than it can do confidently rather than guessing. If the host cannot run subagents, do that same single pass yourself inline.
|
|
135
|
+
|
|
136
|
+
### High effort
|
|
137
|
+
|
|
138
|
+
Follow [references/multi-agent.md](references/multi-agent.md): dispatch one reviewer agent per active lens in parallel (each reads only its own rubric section), run one debate round, then moderator-filter. Return here for Synthesize.
|
|
139
|
+
|
|
140
|
+
## Filter (before synthesis)
|
|
141
|
+
|
|
142
|
+
Low effort: apply to the reviewer subagent's candidates. High effort: the moderator filter in multi-agent.md extends this list — apply that version.
|
|
143
|
+
|
|
144
|
+
1. **Drop findings with empty or hypothetical `failure_mode`.** "A future caller might…", "in case someone…" → drop.
|
|
145
|
+
2. **Drop do-not-raise matches.** For every finding, ask: does it match a do-not-raise item (rubric §Admission)? If it matches a `slop:` tag and you can't write a concrete, product-specific cost in one sentence — drop it.
|
|
146
|
+
3. **Cross-repo audit.** Does the failure_mode reference a downstream actor or a contract/schema/public-artifact boundary you didn't actually read? Route through the cross-repo evidence policy.
|
|
147
|
+
4. **Apply the NIT gate.** NITs that don't meet it → drop. Kept NITs stay internal, hidden by default.
|
|
148
|
+
5. **Merge near-duplicates** under one finding (note which lens(es) surfaced it).
|
|
149
|
+
6. **Apply hard caps.** 6 actionable, 8 NITs retained; rest summarized as "N additional items omitted; ask for the full list."
|
|
150
|
+
|
|
151
|
+
Track dropped items in Withdrawn (one-liner each) so the user can see what was filtered.
|
|
152
|
+
|
|
153
|
+
## Synthesize
|
|
154
|
+
|
|
155
|
+
### Summary
|
|
156
|
+
|
|
157
|
+
One short paragraph: what the change does and your overall recommendation (ship / ship with changes / do not ship). When the Spec lens ran, add one line with its verdict — requirements met, missing, or diverging — kept separate so a standards-clean diff can't mask a spec miss (and vice versa). When it was skipped, add "no spec available". Do not state the mode, engine, lenses applied, or convention sources consulted — that metadata is noise.
|
|
158
|
+
|
|
159
|
+
### Actionable
|
|
160
|
+
|
|
161
|
+
Up to 6 items. Format each:
|
|
162
|
+
|
|
163
|
+
- **[SEVERITY] Title** — `file:lines`
|
|
164
|
+
- **Point:** one sentence. Spec findings quote the spec line they're grounded in.
|
|
165
|
+
- **Why it matters:** the `failure_mode`.
|
|
166
|
+
- **Suggested fix (before → after):** two stacked fenced code blocks — first `// Before` (current code), then `// After` (replacement). Same language tag for both. For a pure deletion, show only `Before` and write "_Delete these lines._" For a pure addition, show only `After` prefixed with `// Add after line <N>`. Omit when structural; explain in prose.
|
|
167
|
+
- **Lens(es):** which lens(es) surfaced this (high effort: which agents raised/agreed, by name).
|
|
168
|
+
|
|
169
|
+
Order by severity (CRITICAL → MAJOR → MINOR), then by file. Number items 1..N — these ids drive the gates.
|
|
170
|
+
|
|
171
|
+
### Disagreements (high effort only)
|
|
172
|
+
|
|
173
|
+
Items where agents substantively disagreed and did not converge. One sentence per side, attributed by agent name, then the moderator's call with a one-line reason.
|
|
174
|
+
|
|
175
|
+
### Nits
|
|
176
|
+
|
|
177
|
+
Do **not** print by default. Print only: _"N nit(s) available (M from convention audit)."_ Surface a "show the N NIT(s) first" option in gate 1. If N is 0, omit this section.
|
|
178
|
+
|
|
179
|
+
### Withdrawn
|
|
180
|
+
|
|
181
|
+
Terse one-liners of items dropped by the filter. Transparency only.
|
|
182
|
+
|
|
183
|
+
## Report mode (--report)
|
|
184
|
+
|
|
185
|
+
Stop after Synthesize: print the Summary, the Actionable list, and the retained NITs as one-liners (the caller is an agent — the hide-nits default is for humans), then end. No user gates, no posting, no implementing; the caller triages every finding itself and owns any fixes.
|
|
186
|
+
|
|
187
|
+
Earlier interactive checkpoints resolve to their safe defaults instead of prompting: the freshness preflight's stop-and-ask resolves as `use-origin` (fetch failure → return an error to the caller instead of findings), and cross-repo access requests resolve as `skip all` (downgrade per the cross-repo policy).
|
|
188
|
+
|
|
189
|
+
## User gate 1 — select items
|
|
190
|
+
|
|
191
|
+
Ask via the host's structured picker (`AskUserQuestion` in Claude Code; hosts without one: a numbered text prompt with the same options). Render each actionable finding as an option, plus a trailing "Show the N NIT(s) first" option when N > 0. Set `multiSelect: true`. Do not proceed until the user answers.
|
|
192
|
+
|
|
193
|
+
Option-label format: `<id> - <short title> (<SEVERITY>)`. The `description` is the one-sentence failure_mode, not the fix.
|
|
194
|
+
|
|
195
|
+
- **Zero findings selected** → end with a one-line "no findings selected — nothing to do".
|
|
196
|
+
- **Only "Show the N NIT(s) first"** → print the NITs (one-liners with `file:lines` and `[CONVENTION]`/`[SPEC]` tags), then re-ask this gate.
|
|
197
|
+
- **Findings selected** → proceed to gate 2 (print NITs first if the toggle was also checked).
|
|
198
|
+
|
|
199
|
+
## Branch on mode
|
|
200
|
+
|
|
201
|
+
Gate 2 is mandatory in both modes — never auto-apply fixes and never auto-post reviews.
|
|
202
|
+
|
|
203
|
+
### Author mode
|
|
204
|
+
|
|
205
|
+
**Plan.** For the selected ids only, produce an ordered implementation plan: steps, files touched per step, tests to add/update, verification commands. Do **not** edit files yet.
|
|
206
|
+
|
|
207
|
+
**User gate 2 (author)** — structured picker, `multiSelect: false`, options:
|
|
208
|
+
|
|
209
|
+
- `Implement locally` — apply the plan against the checkout.
|
|
210
|
+
- `Post as review` — post anchored comments on your own PR, then stop.
|
|
211
|
+
- `Both` — post the review first, then execute the plan.
|
|
212
|
+
- `Edit the plan` — revise, re-ask this gate.
|
|
213
|
+
- `Cancel` — stop.
|
|
214
|
+
|
|
215
|
+
**Execute.** Track each step with the host's task tracker. Apply the plan, run verification, report results. If a step surfaces a new substantive issue not in the selected items, stop and ask before expanding scope.
|
|
216
|
+
|
|
217
|
+
### Reviewer mode
|
|
218
|
+
|
|
219
|
+
Skip the plan step — you are not implementing someone else's code.
|
|
220
|
+
|
|
221
|
+
**User gate 2 (reviewer)** — structured picker, `multiSelect: false`, options:
|
|
222
|
+
|
|
223
|
+
- `Post` — submit a single COMMENT review with the selected anchored comments.
|
|
224
|
+
- `Edit` — ask which to drop or refine, then re-ask.
|
|
225
|
+
- `Cancel` — stop.
|
|
226
|
+
|
|
227
|
+
## Posting an anchored PR review (both modes)
|
|
228
|
+
|
|
229
|
+
When the user approves items to post, submit a **single** review via the GitHub Reviews API (`event: COMMENT` — never `APPROVE`/`REQUEST_CHANGES`), with every selected item as an inline comment anchored to its diff line. Never use loose issue comments.
|
|
230
|
+
|
|
231
|
+
Follow [references/posting-pr-review.md](references/posting-pr-review.md) exactly — it has the `gh api` call, the payload shape, the three-block review body, and the per-comment body budget and format. After posting, print the review `html_url` and a one-line summary of how many comments were posted (and fallback general-notes count if any).
|
|
@@ -30,6 +30,19 @@ For each cross-repo finding:
|
|
|
30
30
|
|
|
31
31
|
Severity cap on any cross-repo finding is **MAJOR** until verified. Anything verified as actual breakage can be raised to its true severity.
|
|
32
32
|
|
|
33
|
+
## High effort — subagent and moderator flow
|
|
34
|
+
|
|
35
|
+
Reviewer agents must **not** do the verification themselves. An agent whose finding is cross-repo emits it with:
|
|
36
|
+
|
|
37
|
+
```json
|
|
38
|
+
"evidence_required": {
|
|
39
|
+
"repos": ["cbh-admin-frontend", "payment-service"],
|
|
40
|
+
"what_to_verify": "concrete grep / file path / question the moderator should answer to confirm or kill the finding"
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
…and caps severity at MAJOR. After Round 1 the moderator (main agent) collects every `evidence_required` block, runs **Verify or downgrade** above for each (including the user access-request when needed), then re-dispatches only the affected agents with the verified evidence (or its absence) inlined so they can finalize severity in Round 2. Findings whose evidence the user `skip`s are kept but capped per step 5.
|
|
45
|
+
|
|
33
46
|
## Access-request template
|
|
34
47
|
|
|
35
48
|
When asking the user for access to external repos, name the specific file and the specific question. Do not ask vaguely for "access to repo X" — ask for the evidence that would change your mind.
|
|
@@ -43,7 +56,7 @@ When asking the user for access to external repos, name the specific file and th
|
|
|
43
56
|
> Options:
|
|
44
57
|
>
|
|
45
58
|
> - **Local path** — give me an absolute path to a checkout (I'll run freshness preflight and read via `git show`).
|
|
46
|
-
> - **`gh:<owner>/<repo
|
|
59
|
+
> - **`gh:<owner>/<repo>[@<ref>]`** — I'll fetch via `gh api repos/<owner>/<repo>/contents/<path>?ref=<ref>`, defaulting `<ref>` to the repo's default branch.
|
|
47
60
|
> - **`skip`** — I'll either drop the finding or keep it as MINOR with a "speculative — assumes `<assumption>`" prefix; you can confirm/refute.
|
|
48
61
|
> - **`skip all`** — apply `skip` to every remaining cross-repo finding.
|
|
49
62
|
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# High-effort engine — parallel reviewers, one debate round, moderator filter
|
|
2
|
+
|
|
3
|
+
Read this when effort is `high`; low effort borrows only the two dispatch contracts (§Dispatch mechanics) and the Round 1 output shape. Referenced from `SKILL.md`. The rubric in `review-rubric.md` is binding for every agent.
|
|
4
|
+
|
|
5
|
+
## Roster
|
|
6
|
+
|
|
7
|
+
One reviewer agent per active lens. **Refer to agents by name in everything the user sees**; the letter is only a compact prefix for internal finding IDs (`B1`, `C3`, …).
|
|
8
|
+
|
|
9
|
+
| Letter | Name | Rubric section | When it runs |
|
|
10
|
+
| ------ | ----------- | -------------- | ---------------------- |
|
|
11
|
+
| B | Engineering | §Engineering | Always |
|
|
12
|
+
| C | Minimalist | §Minimalism | Always |
|
|
13
|
+
| D | Conventions | §Conventions | Always |
|
|
14
|
+
| E | Security | §Security | Classification trigger |
|
|
15
|
+
| F | Database | §Database | Classification trigger |
|
|
16
|
+
| G | Frontend | §Frontend | Classification trigger |
|
|
17
|
+
| H | AntiSlop | §AntiSlop | Always |
|
|
18
|
+
| S | Spec | §Spec | Spec source found |
|
|
19
|
+
|
|
20
|
+
Record the dispatched set in `$RUN_DIR/meta.json` so Round 2 knows the full agent list.
|
|
21
|
+
|
|
22
|
+
## Dispatch mechanics
|
|
23
|
+
|
|
24
|
+
Use the host's parallel subagent mechanism (in Claude Code: the `Agent` tool with `subagent_type: general-purpose`, all calls in a single message so they run truly in parallel). Use fresh agents for every round. If one agent fails or returns malformed output, re-dispatch **that agent only** — do not restart the round. If the host cannot run subagents, high effort's independence guarantee is unattainable — fall back to the low-effort engine (which then runs its single pass inline) and tell the user why.
|
|
25
|
+
|
|
26
|
+
Keep large content on disk (`$RUN_DIR/*`, from SKILL.md §Scope Persistence) so Round 2 prompts stay compact.
|
|
27
|
+
|
|
28
|
+
Every agent prompt includes:
|
|
29
|
+
|
|
30
|
+
- The file paths from Scope (`$RUN_DIR/diff.patch`, `$RUN_DIR/context.md`, `$RUN_DIR/files.txt`).
|
|
31
|
+
- An instruction to read `review-rubric.md` **§Admission** plus the agent's own lens section (give the absolute path to this skill's `references/review-rubric.md`), and — for Spec — the spec source content or how to fetch it.
|
|
32
|
+
- The two contracts below, verbatim (substitute `<context_ref>` from the freshness preflight):
|
|
33
|
+
|
|
34
|
+
> **Context-read contract.** The verified-fresh ref for repo context is `<context_ref>`. For any file that is part of the primary repo's tracked content (i.e. _not_ a brand-new file in this PR's diff), use `git show "<context_ref>:<path>"` or `git grep -n <pattern> "<context_ref>" -- <paths>` rather than reading the worktree. If you read from the worktree because the file is new in the diff or untracked at `<context_ref>`, say so in the finding's `point`.
|
|
35
|
+
>
|
|
36
|
+
> **Cross-repo evidence contract.** If a finding's load-bearing evidence is in any repo other than this one, do NOT silently read another local checkout — those checkouts may be stale or on unrelated branches. Instead, emit the finding with an `evidence_required` field naming the repo(s) and the specific verification question, and cap your severity at MAJOR. The moderator will ask the user for verified access before Round 2 and re-dispatch you if needed.
|
|
37
|
+
|
|
38
|
+
## Round 1 — parallel independent reviews
|
|
39
|
+
|
|
40
|
+
Agents must not see each other's output in this round. Each agent emits at most 8 findings, prioritized — not exhaustive.
|
|
41
|
+
|
|
42
|
+
Required output per finding: `id` (letter-prefixed: `B1`, `C3`, `S1`, …), `severity`, `file:lines`, `title` (one sentence), `point` (one short paragraph), `failure_mode` (one sentence), optional `suggested_fix` (schema in rubric §Admission), and optional `evidence_required` (`{ repos: string[], what_to_verify: string }` — required whenever the finding depends on cross-repo state).
|
|
43
|
+
|
|
44
|
+
After Round 1, collect every `evidence_required` block and resolve it with the user per `cross-repo-evidence.md` **before** Round 2.
|
|
45
|
+
|
|
46
|
+
## Round 2 — debate (last round; hard cap: 2)
|
|
47
|
+
|
|
48
|
+
Dispatch the same agent set, in parallel. Each agent receives **all Round 1 outputs** and must:
|
|
49
|
+
|
|
50
|
+
- Re-examine their own findings and **withdraw** any that don't survive scrutiny.
|
|
51
|
+
- For each other agent's finding: mark `agree`, `disagree` (with reasoning), or `refine` (propose a tighter version).
|
|
52
|
+
- Flag items where disagreement is substantive and unlikely to resolve.
|
|
53
|
+
|
|
54
|
+
Output per item: `id`, `original_author` (agent **name**, not letter), `verdict` (keep | withdraw | agree | disagree | refine), `final_severity`, `final_title`, `final_failure_mode`, `reasoning`, `suggested_fix`, and rebuttals `[{from, stance, reasoning}]` (`from` is also a name).
|
|
55
|
+
|
|
56
|
+
**AntiSlop plays an expanded Round 2 role**: beyond defending or withdrawing its own findings, it audits every other agent's finding against the tagged do-not-raise items (rubric §Admission) and marks matches `disagree` with the item's `slop:` tag in `reasoning`.
|
|
57
|
+
|
|
58
|
+
When an agent sees a slop tag on its own finding, it either rebuts with a concrete, product-specific `final_failure_mode` or withdraws — not both stand on the original framing. Even when AntiSlop's own Round 1 findings are sparse because the diff is clean, it must not under-spend on this audit — stopping slop _suggestions_ from polluting the review is often the bigger lever.
|
|
59
|
+
|
|
60
|
+
Residual disagreement goes to the Disagreements section of the synthesis.
|
|
61
|
+
|
|
62
|
+
## Moderator filter (main agent — after Round 2, before synthesis)
|
|
63
|
+
|
|
64
|
+
Apply the shared Filter list from `SKILL.md`, with these additions in order:
|
|
65
|
+
|
|
66
|
+
1. **Apply AntiSlop slop tags.** For every finding AntiSlop tagged `slop:`, check the original author's Round 2 rebuttal. No concrete, product-specific `final_failure_mode` addressing the specific tag → **drop the finding**. AntiSlop's audit is not a unilateral veto, but the burden of proof shifts to the author once tagged. Record drops in Withdrawn with the slop label (e.g. `B4 — dropped: AntiSlop tagged "slop: asks for defensive guard on already-narrowed value", Engineering did not rebut`).
|
|
67
|
+
2. **Merge near-duplicates across agents** into one item, preserving all attributions in `Raised by:`.
|
|
68
|
+
3. Renumber the survivors 1..N for the user-facing Actionable list and gates; keep agent names in `Raised by` / `agreed by`.
|
|
@@ -2,19 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
Read this once the user approves items to post. Referenced from `SKILL.md`.
|
|
4
4
|
|
|
5
|
-
## Contents
|
|
6
|
-
|
|
7
|
-
- API call and payload shape
|
|
8
|
-
- Review body (top-level): attribution line, summary, apply-all prompt
|
|
9
|
-
- Each comment body: budget, template, formatting rules
|
|
10
|
-
|
|
11
5
|
## API call and payload
|
|
12
6
|
|
|
13
7
|
Post via the GitHub Reviews API as a **single** review with all selected actionable items as inline review comments anchored to specific diff lines. **Never** loose issue comments.
|
|
14
8
|
|
|
15
9
|
```bash
|
|
16
|
-
# /tmp/
|
|
17
|
-
gh api -X POST "repos/<owner>/<repo>/pulls/<N>/reviews" --input /tmp/
|
|
10
|
+
# /tmp/cb-review-payload.json contains: {event, commit_id, body, comments: [...]}
|
|
11
|
+
gh api -X POST "repos/<owner>/<repo>/pulls/<N>/reviews" --input /tmp/cb-review-payload.json
|
|
18
12
|
```
|
|
19
13
|
|
|
20
14
|
Payload shape:
|
|
@@ -54,9 +48,9 @@ Three blocks, in order:
|
|
|
54
48
|
|
|
55
49
|
> _These comments were generated by @\<viewer-login\> using Claude Code._
|
|
56
50
|
|
|
57
|
-
Italicized. Substitute `<viewer-login>` from `gh api user --jq .login`. Non-negotiable — collaborators must be able to tell at a glance the review is AI-assisted. Do **not** mention the
|
|
51
|
+
Italicized. Substitute `<viewer-login>` from `gh api user --jq .login`. Non-negotiable — collaborators must be able to tell at a glance the review is AI-assisted. Do **not** mention the CB Review skill by name; it's a local skill the PR author can't see or use.
|
|
58
52
|
|
|
59
|
-
**2. Summary.** Same paragraph from the in-chat synthesis: what the change does and your recommendation. Do not include mode, lenses applied, or convention sources consulted — that's noise.
|
|
53
|
+
**2. Summary.** Same paragraph from the in-chat synthesis: what the change does and your recommendation (including the Spec verdict line when that lens ran). Do not include mode, engine, lenses applied, or convention sources consulted — that's noise.
|
|
60
54
|
|
|
61
55
|
**3. "Apply all comments at once" prompt.** A fenced block with a self-contained Claude Code prompt the PR author can paste into a Claude Code session on a checkout of this branch:
|
|
62
56
|
|
|
@@ -64,7 +58,7 @@ Italicized. Substitute `<viewer-login>` from `gh api user --jq .login`. Non-nego
|
|
|
64
58
|
**Apply all comments at once** — paste this into Claude Code on a checkout of this branch:
|
|
65
59
|
|
|
66
60
|
```
|
|
67
|
-
Fetch the
|
|
61
|
+
Fetch the review by @<viewer-login> on PR <PR_URL> that contains this exact prompt. For every inline comment in that review, address the issue: when the comment includes a `suggestion` block, apply it verbatim; otherwise implement an equivalent fix that satisfies the comment's "Why it matters" rationale. After resolving each thread, post a reply on that thread with a one-line summary of what you changed. When all comments are handled, run the project's tests, commit the changes with a message that references the review, and report back any threads you could not resolve and why.
|
|
68
62
|
```
|
|
69
63
|
````
|
|
70
64
|
|