@clipboard-health/ai-rules 2.33.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clipboard-health/ai-rules",
3
- "version": "2.33.0",
3
+ "version": "2.34.0",
4
4
  "description": "Pre-built AI agent rules for consistent coding standards.",
5
5
  "keywords": [
6
6
  "ai",
@@ -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.14.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.
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.14.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.
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.14.0</code></sub>`
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.14.0</code></sub>` so grep catches them individually.
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.14.0</code></sub>'
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)"
@@ -1,21 +1,22 @@
1
1
  ---
2
2
  name: cb-review
3
- description: Code review of the current branch or a PR β€” single-pass by default, parallel reviewer agents that debate at high effort, plus a spec-compliance lens when the originating ticket or PRD is available; findings posted as anchored PR comments. Use when the user asks to review a diff, branch, or PR, or runs /cb-review [pr-number-or-url] [--effort low|high].
4
- argument-hint: "[pr-number-or-url] [--effort low|high]"
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
5
  ---
6
6
 
7
7
  # CB Review
8
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. Two engines share everything except how the rubric is applied:
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
10
 
11
- - **low** β€” single pass by you (the main agent), no subagents. Default.
12
- - **high** β€” parallel reviewer agents, one debate round, moderator filter. For large or high-stakes diffs.
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
13
 
14
14
  ## Invocation
15
15
 
16
16
  - `/cb-review` β€” review the current branch (resolves the open PR for the branch if any, otherwise diffs against the default branch).
17
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
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).
19
20
 
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.
21
22
 
@@ -49,7 +50,7 @@ Determine **mode**:
49
50
  - PR exists and authors differ β†’ **reviewer mode**.
50
51
  - No PR β†’ **author mode**.
51
52
 
52
- **Persistence:** low effort holds everything in-context. High effort persists for subagents: diff β†’ `/tmp/cb-review-diff.patch`, context β†’ `/tmp/cb-review-context.md`, changed files β†’ `/tmp/cb-review-files.txt`, metadata (PR number/url/base/author, viewer, head SHA, owner/repo, mode, `context_ref`, dispatched agent set) β†’ `/tmp/cb-review-meta.json`.
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`.
53
54
 
54
55
  ## Freshness preflight (mandatory before reading code)
55
56
 
@@ -111,9 +112,7 @@ When `context_ref = worktree (stale, user accepted risk)`:
111
112
 
112
113
  ## Cross-repo evidence policy
113
114
 
114
- 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. **Never silently read external repos and never claim a downstream impact you have not verified** β€” speculating that "the FE will break" without reading the consumer is a top source of false-positive findings. Cap any cross-repo finding at **MAJOR** until verified.
115
-
116
- 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 access-request template, and what "verify" means for contract/schema vs API-response changes.
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.
117
116
 
118
117
  ## Diff classification (pick which lenses apply)
119
118
 
@@ -132,7 +131,7 @@ The rubric β€” severity ladder, `failure_mode` contract, do-not-raise list, NIT
132
131
 
133
132
  ### Low effort
134
133
 
135
- Read the full rubric, then walk the diff once, applying the active lenses yourself. You're looking for _the smallest number of high-signal findings_, not exhaustive coverage. **No subagents** β€” if a finding needs deeper independent investigation than you can do confidently in-line, surface it as a flagged finding rather than guess.
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.
136
135
 
137
136
  ### High effort
138
137
 
@@ -140,15 +139,14 @@ Follow [references/multi-agent.md](references/multi-agent.md): dispatch one revi
140
139
 
141
140
  ## Filter (before synthesis)
142
141
 
143
- Low effort: apply to your own candidates. High effort: the moderator filter in multi-agent.md extends this list β€” apply that version.
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.
144
143
 
145
144
  1. **Drop findings with empty or hypothetical `failure_mode`.** "A future caller might…", "in case someone…" β†’ drop.
146
- 2. **Self-audit for slop.** For every finding, ask: does it match a slop pattern (asks-for-defensive-guard on an already-narrowed value β€” but only if an _enforced_ check narrows it, not merely a declared type or cast; hypothetical future caller; restating-obvious comment request; abstract refactor with no concrete cost-of-keeping; observability without named failure mode; test for trivially-verifiable code; defends against a state the product cannot produce)? If yes and you can't write a concrete, product-specific cost in one sentence β€” drop it.
147
- 3. **Cross-repo audit.** Does the failure_mode reference a downstream actor or a contract/schema/public-artifact boundary? If you didn't actually read the external code, route through the cross-repo evidence policy (verify, ask for access, or downgrade to a labeled "speculative" MINOR).
148
- 4. **Drop do-not-raise items** that slipped through.
149
- 5. **Apply the NIT gate.** NITs that don't meet it β†’ drop. Kept NITs stay internal, hidden by default.
150
- 6. **Merge near-duplicates** under one finding (note which lens(es) surfaced it).
151
- 7. **Apply hard caps.** 6 actionable, 8 NITs retained; rest summarized as "N additional items omitted; ask for the full list."
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."
152
150
 
153
151
  Track dropped items in Withdrawn (one-liner each) so the user can see what was filtered.
154
152
 
@@ -182,6 +180,12 @@ Do **not** print by default. Print only: _"N nit(s) available (M from convention
182
180
 
183
181
  Terse one-liners of items dropped by the filter. Transparency only.
184
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
+
185
189
  ## User gate 1 β€” select items
186
190
 
187
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.
@@ -194,6 +198,8 @@ Option-label format: `<id> - <short title> (<SEVERITY>)`. The `description` is t
194
198
 
195
199
  ## Branch on mode
196
200
 
201
+ Gate 2 is mandatory in both modes β€” never auto-apply fixes and never auto-post reviews.
202
+
197
203
  ### Author mode
198
204
 
199
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.
@@ -223,16 +229,3 @@ Skip the plan step β€” you are not implementing someone else's code.
223
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.
224
230
 
225
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).
226
-
227
- ## Rules
228
-
229
- - The rubric file is binding for both engines: empty `failure_mode` β†’ drop, NIT not meeting the gate β†’ drop, do-not-raise items β†’ drop, caps applied (6 actionable, 8 nits).
230
- - Issue independent `gh`/`git` commands in parallel (PR view, diff, files, viewer).
231
- - Freshness preflight is mandatory before reading code. Read repo context via `git show "<context_ref>:<path>"`, not the worktree filesystem, unless `context_ref = worktree (stale, user accepted risk)`.
232
- - Never run state-modifying git commands on the user's behalf (`checkout`, `stash`, `reset`, `clean`, `pull` with merge). Warn and ask. `git fetch` is allowed.
233
- - Cross-repo evidence: **never raise a "consumer will break" finding without reading the consumer.** Cap at MAJOR until verified; user `skip` β†’ drop or keep as MINOR with a visible "speculative β€” assumes `<X>`" prefix.
234
- - Conditional lenses (Security/Database/Frontend/Spec) run only when classification matches.
235
- - Hide nits by default. Print only when the user selects the NIT toggle in gate 1.
236
- - Reviews are always `event: COMMENT`. Never approve or request changes on the user's behalf.
237
- - Both user gates are mandatory. Do not auto-apply recommendations and do not auto-post reviews.
238
- - If the diff is empty, stop with a one-line message β€” do not invent findings.
@@ -1,6 +1,6 @@
1
1
  # High-effort engine β€” parallel reviewers, one debate round, moderator filter
2
2
 
3
- Read this only when effort is `high`. Referenced from `SKILL.md`. The rubric in `review-rubric.md` is binding for every agent.
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
4
 
5
5
  ## Roster
6
6
 
@@ -17,17 +17,17 @@ One reviewer agent per active lens. **Refer to agents by name in everything the
17
17
  | H | AntiSlop | Β§AntiSlop | Always |
18
18
  | S | Spec | Β§Spec | Spec source found |
19
19
 
20
- Record the dispatched set in `/tmp/cb-review-meta.json` so Round 2 knows the full agent list.
20
+ Record the dispatched set in `$RUN_DIR/meta.json` so Round 2 knows the full agent list.
21
21
 
22
22
  ## Dispatch mechanics
23
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 and tell the user why.
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
25
 
26
- Keep large content on disk (`/tmp/cb-review-*`) so Round 2 prompts stay compact.
26
+ Keep large content on disk (`$RUN_DIR/*`, from SKILL.md Β§Scope Persistence) so Round 2 prompts stay compact.
27
27
 
28
28
  Every agent prompt includes:
29
29
 
30
- - The file paths from Scope (`/tmp/cb-review-diff.patch`, `-context.md`, `-files.txt`).
30
+ - The file paths from Scope (`$RUN_DIR/diff.patch`, `$RUN_DIR/context.md`, `$RUN_DIR/files.txt`).
31
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
32
  - The two contracts below, verbatim (substitute `<context_ref>` from the freshness preflight):
33
33
 
@@ -53,15 +53,7 @@ Dispatch the same agent set, in parallel. Each agent receives **all Round 1 outp
53
53
 
54
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
55
 
56
- **AntiSlop plays an expanded Round 2 role**: beyond defending or withdrawing its own findings, it audits every other agent's finding for the slop patterns it scans code for, and marks matches `disagree` with a one-line `slop:` label in `reasoning`:
57
-
58
- - "Add a null check / try-catch / validation" on a value already typed, validated upstream, or guaranteed by a preceding call β†’ `slop: asks for defensive guard on already-narrowed value`.
59
- - "What if a future caller / someone later…" with no current realistic input β†’ `slop: hypothetical future caller β€” no current path`.
60
- - Comment/JSDoc requests where name + signature already convey intent β†’ `slop: restating-the-obvious comment request`.
61
- - Refactor suggestions whose failure_mode is shape-of-the-code β†’ `slop: refactor with no concrete cost-of-keeping`.
62
- - "Add a log/metric" without the specific failure it would debug β†’ `slop: observability without named failure mode`.
63
- - Test demands on type-evident or already-exercised code β†’ `slop: test for trivially-verifiable code`.
64
- - Worries about states the product cannot produce β†’ `slop: defends against a state the product cannot produce`.
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`.
65
57
 
66
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.
67
59
 
@@ -2,12 +2,6 @@
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.
@@ -1,6 +1,6 @@
1
1
  # Review rubric (binding for both engines)
2
2
 
3
- Low effort: the main agent reads this whole file and walks every active lens. High effort: each reviewer agent reads **Admission** plus its own lens section. Referenced from `SKILL.md`.
3
+ Low effort: the single reviewer subagent reads this whole file and walks every active lens. High effort: each reviewer agent reads **Admission** plus its own lens section. Referenced from `SKILL.md`.
4
4
 
5
5
  ## Admission
6
6
 
@@ -19,13 +19,16 @@ Litmus test before keeping any candidate: _"What is the concrete, current, produ
19
19
 
20
20
  ### Do-not-raise list
21
21
 
22
- - Speculative defensiveness at trusted internal boundaries (only where the boundary's guarantee is actually _enforced_ β€” a declared or cast type is not enforcement; see AntiSlop).
23
- - Restating the obvious ("consider a comment explaining what this does").
24
- - Hypothetical future-caller scenarios with no current caller.
22
+ Drop candidates that match. The tagged items double as the slop taxonomy for the Filter (SKILL.md) and for AntiSlop's Round 2 audit of other agents' findings (multi-agent.md), which cites the tags verbatim.
23
+
24
+ - `slop: asks for defensive guard on already-narrowed value` β€” speculative defensiveness at a boundary whose guarantee is actually _enforced_; a declared or cast type is not enforcement (see AntiSlop).
25
+ - `slop: hypothetical future caller β€” no current path` β€” future-caller scenarios with no current caller.
26
+ - `slop: restating-the-obvious comment request` β€” comment/JSDoc requests where name + signature already convey intent.
27
+ - `slop: refactor with no concrete cost-of-keeping` β€” abstract SOLID-style "consider extracting…" with no concrete failure mode.
28
+ - `slop: observability without named failure mode` β€” "add a log/metric" without the specific failure it would debug.
29
+ - `slop: test for trivially-verifiable code` β€” test demands on type-evident or already-exercised code.
30
+ - `slop: defends against a state the product cannot produce`.
25
31
  - Style/formatting a linter or formatter covers.
26
- - Test-coverage demands on trivially-verifiable code.
27
- - "Add observability" without naming a concrete failure mode it would help debug.
28
- - Abstract SOLID-style "consider extracting…" without a concrete failure mode.
29
32
  - Aesthetic naming preferences β€” only raise names that mislead about behavior.
30
33
 
31
34
  ### Caps
@@ -54,6 +57,8 @@ For each change name a realistic input or condition that would expose a bug. If
54
57
  - **Asymmetric handling across sibling call sites is a likely bug, not a style nit.** When the diff guards, validates, converts, or error-wraps a value in one place but consumes the same value or shape bare elsewhere, exactly one side is usually right. Compare the call sites against each other instead of reviewing each in isolation, and resolve the inconsistency: guard missing where it's absent β†’ bug; guard unnecessary everywhere β†’ slop to remove.
55
58
  - Edge cases, error paths, observability of real failure modes.
56
59
  - Tests cover real risk, not lines.
60
+ - A diff that changes runtime behavior with zero test delta is raisable when the repo's documented rules mandate tests (cite the rule) β€” "the new behavior ships unverified" is a concrete failure_mode, not a hypothetical.
61
+ - Hard-coded environment-specific identifiers (pool/account IDs, environment URLs) in code, scripts, or docs meant for reuse.
57
62
  - Concurrency, performance at real scale, data integrity.
58
63
  - Backward compatibility, on-call implications, degraded-mode behavior.
59
64
  - Async/await ordering matches actual data dependencies.
@@ -63,6 +68,7 @@ For each change name a realistic input or condition that would expose a bug. If
63
68
  - Schema/query changed β†’ indexes for new patterns, N+1, cascade semantics, type fit (deep dive under Database).
64
69
  - Telemetry covers business/product value, not only engineering surface metrics.
65
70
  - Contract/backward-compat for any consumer-visible response shape change. **If you suspect a consumer break, the finding is cross-repo β€” follow the cross-repo evidence policy before raising it.**
71
+ - Before raising a version/back-compat break on a published package, read its `package.json` at `${context_ref}` β€” 0.x caret semantics or a days-old package can refute the failure_mode.
66
72
 
67
73
  ## Minimalism (always)
68
74
 
@@ -71,6 +77,8 @@ The smallest diff that ships the intent is the best diff.
71
77
  - Unneeded abstractions, speculative generality, dead branches.
72
78
  - Redundant validation, defensive code at trusted internal boundaries.
73
79
  - Comments that restate code; new files/utilities that duplicate existing ones.
80
+ - Near-duplicate tests or assertions within the diff; conditions or variables another hunk of the same diff makes unnecessary.
81
+ - New docs or guidance lines that restate an adjacent existing line.
74
82
  - Tests that exercise the framework, not behavior.
75
83
  - Flags/config knobs without a concrete caller.
76
84
  - Duplicated error handlers in the same scope.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: cb-ship
3
- description: Ship changes. Simplify the diff, commit, push, and open or update a PR. Use when the user says 'ship it', 'commit and push', or wants a PR created or updated.
3
+ description: Ship changes. Simplify the diff, commit, review, push, and open or update a PR. Use when the user says 'ship it', 'commit and push', or wants a PR created or updated.
4
4
  argument-hint: "[--draft]"
5
5
  ---
6
6
 
@@ -17,16 +17,18 @@ Resolve bundled "./references" paths relative to SKILL.md.
17
17
  1. Create a new branch if on the default branch (e.g., `feat/add-user-validation`, `fix/null-check-in-parser`).
18
18
  2. Use ./references/simplify.md on the full PR diff: `git diff $(git merge-base HEAD origin/HEAD)..HEAD` and any uncommitted changes.
19
19
  3. Inspect `git status --short`, identify intended files, ask if ambiguous, then git add them. If uncommitted changes, create a conventional commit with `git commit --no-gpg-sign`.
20
- 4. Push changes to origin.
21
- 5. Create or update the PR using ./references/pr-template.md:
20
+ 4. Invoke the `cb-review` skill with `--effort low --report` and triage each returned finding yourself: if it's real and in scope, apply it, rerun the repo's relevant checks, and commit; otherwise dismiss it with a one-line reason for the output. Skip this step when the session already ran cb-review over these same changes.
21
+ 5. Push changes to origin.
22
+ 6. Create or update the PR using ./references/pr-template.md:
22
23
  a. If the host exposes a session ID (e.g., CODEX_THREAD_ID, CLAUDE_CODE_SESSION_ID), include the resume command in the PR body in backticks: ``Agent session: `codex resume <id>` `` or ``Agent session: `claude --resume <id>` ``. Preserve existing `Agent session:` lines, append only.
23
24
  b. If a PR exists, update the title and body if the new changes aren't reflected.
24
25
  c. Otherwise, create one with `gh pr create`; make it a draft if the user passed `--draft`.
25
- 6. Output:
26
+ 7. Output:
26
27
 
27
28
  ```plaintext
28
29
  - Directory: [Absolute path]
29
30
  - Branch: [Branch name]
30
- - Session: [Resume command from 5a] (omit if none)
31
+ - Review: [N findings β€” M applied, K dismissed with a one-line reason each] (omit if step 4 skipped or found nothing)
32
+ - Session: [Resume command from 6a] (omit if none)
31
33
  - PR: [Complete url] (e.g., `https://github.com/clipboardhealth/core-utils/pull/123`)
32
34
  ```
@@ -17,5 +17,5 @@ Concisely explain the user intent from session history and the meaningful behavi
17
17
 
18
18
  Optional, don't fabricate: ticket links, rollout plan, residual risk, or specific areas for reviewers to focus.
19
19
 
20
- <sub>πŸ€– <code>cb-ship:created v1 core@3.14.0</code></sub>
20
+ <sub>πŸ€– <code>cb-ship:created v1 core@3.15.0</code></sub>
21
21
  ```
@@ -22,6 +22,7 @@ Unless instructed otherwise:
22
22
  The plan or request is the source of truth for scope:
23
23
 
24
24
  - Make exactly the changes requested, no extra refactors or cleanup.
25
+ - Target ≀ ~500 changed lines per PR: if the work will clearly exceed that, stop and propose a split into separately shippable slices before implementing.
25
26
  - On any drift from the plan (e.g. referenced files or utilities missing, an assumption invalid, a constraint missed) stop and report. Do not silently rewrite the approach.
26
27
  - Do not modify the plan file itself unless asked.
27
28