@clipboard-health/ai-rules 2.25.0 → 2.26.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/rules/common/coreLibraries.md +0 -1
- package/skills/babysit-pr/SKILL.md +4 -4
- package/skills/babysit-pr/scripts/_sentinel.sh +1 -1
- package/skills/commit-push-pr/SKILL.md +2 -2
- package/skills/in-depth-review/SKILL.md +491 -0
- package/skills/in-depth-review/references/cross-repo-evidence.md +37 -0
- package/skills/in-depth-review/references/posting-pr-review.md +105 -0
- package/skills/simple-review/SKILL.md +472 -0
- package/skills/simple-review/references/cross-repo-evidence.md +64 -0
- package/skills/simple-review/references/posting-pr-review.md +100 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Cross-repo evidence policy
|
|
2
|
+
|
|
3
|
+
Read this before raising or finalizing any cross-repo finding. Referenced from `SKILL.md`.
|
|
4
|
+
|
|
5
|
+
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 — most commonly a producer, consumer, or downstream parser of something the diff changes. **Never silently read external repos** — they may be stale or you may have no checkout at all. Equally, **never claim a downstream impact you have not verified.** Speculating that "the FE will break" or "a consumer will choke on this" without reading the consumer is a top source of false-positive findings.
|
|
6
|
+
|
|
7
|
+
## When this policy fires
|
|
8
|
+
|
|
9
|
+
Treat a finding as cross-repo _before_ raising it whenever any of these apply:
|
|
10
|
+
|
|
11
|
+
1. The diff touches a **contract/schema package** (anything in `packages/contract-*`, `packages/*-contract*`, ts-rest contracts, JSON Schema files, OpenAPI specs, Protobuf, Avro, etc.) — consumers of these packages live in other repos by design.
|
|
12
|
+
2. The diff alters a **deployed-artifact boundary**: HTTP response shape, queue message shape, public SDK signature, exported library type, env-var contract, DB-record shape read by other services.
|
|
13
|
+
3. The failure mode you wrote references a downstream actor by role rather than name: _"the FE will…", "the mobile app will…", "consumers will…", "a rolling deploy will break for…"_ — you cannot verify any of those claims from inside the diff's repo alone.
|
|
14
|
+
4. The finding is a "backward-compatibility" or "rolling-deploy" concern about a producer change.
|
|
15
|
+
5. The finding's argument is "this diverges from how other consumers do X" — and "other consumers" are not in this repo.
|
|
16
|
+
|
|
17
|
+
If any of (1)–(5) is true, the finding is cross-repo. Move on to **Verify or downgrade** below before keeping it in your candidate list.
|
|
18
|
+
|
|
19
|
+
## Verify or downgrade (binding)
|
|
20
|
+
|
|
21
|
+
For each cross-repo finding:
|
|
22
|
+
|
|
23
|
+
1. **Identify the specific consumer/producer file(s)** you would need to read to confirm the claim. Be concrete: _"facility app's `useGetInvoiceBalances` hook to see whether it imports the contract schema and whether `.parse()` is strict."_ If you cannot name a specific artifact, the finding is speculative — drop it.
|
|
24
|
+
2. **Search likely locations you already have access to** before asking the user. Sibling repos under the same parent directory, monorepo workspaces, vendored copies. Use targeted `grep`/`git grep` — do not recursively scan the whole filesystem.
|
|
25
|
+
3. **If found locally**, run the **same freshness preflight** on that external repo (branch, dirty state, behind/ahead). Read context via `git show "${external_context_ref}:<path>"`, never via worktree filesystem. Note "verified against: `<repo>@<short-sha>`" in the finding.
|
|
26
|
+
4. **If not found locally**, ask the user for access using the template below. Do not raise the finding until the user has responded.
|
|
27
|
+
5. **If the user picks `skip`**, you have two choices:
|
|
28
|
+
- **Drop the finding entirely** if the speculative version doesn't pass the litmus test ("concrete, current, product-visible cost").
|
|
29
|
+
- **Keep as MINOR with explicit "speculative" prefix in the title** — only when the worst-case is genuinely concerning AND you can name the _assumption_ the finding rests on (e.g., _"assuming the FE imports this schema and parses strictly, then…"_). Make the assumption visible so the PR author can confirm or refute it.
|
|
30
|
+
|
|
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
|
+
|
|
33
|
+
## Access-request template
|
|
34
|
+
|
|
35
|
+
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.
|
|
36
|
+
|
|
37
|
+
> One finding depends on code outside `<primary-repo>`. Before I raise it, I need to verify:
|
|
38
|
+
>
|
|
39
|
+
> **Finding:** `<short title>`
|
|
40
|
+
> **Claim:** `<what the finding asserts about the consumer/producer>`
|
|
41
|
+
> **What I need to read:** `<repo>/<path>` — to check `<specific question, e.g. "whether it imports GetFooResponseSchema and calls .strict() on it">`.
|
|
42
|
+
>
|
|
43
|
+
> Options:
|
|
44
|
+
>
|
|
45
|
+
> - **Local path** — give me an absolute path to a checkout (I'll run freshness preflight and read via `git show`).
|
|
46
|
+
> - **`gh:<owner>/<repo>`** — I'll fetch via `gh api repos/<owner>/<repo>/contents/<path>?ref=main`.
|
|
47
|
+
> - **`skip`** — I'll either drop the finding or keep it as MINOR with a "speculative — assumes `<assumption>`" prefix; you can confirm/refute.
|
|
48
|
+
> - **`skip all`** — apply `skip` to every remaining cross-repo finding.
|
|
49
|
+
|
|
50
|
+
## What "verify" means in practice
|
|
51
|
+
|
|
52
|
+
For a contract/schema change, the questions you must answer before claiming consumer impact are concrete:
|
|
53
|
+
|
|
54
|
+
- Does the consumer **import the contract schema directly**, or define its own local schema? (Local schema = your contract change has zero direct effect on the consumer's parser.)
|
|
55
|
+
- If it imports, does it call `.strict()`, `.passthrough()`, or rely on the default (strip unknowns)? Required fields missing → parse failure; extra fields → silently stripped under default.
|
|
56
|
+
- Is the consumer pinned to a published version of the package, or symlinked/workspace-resolved? Pinned → upgrade is explicit and the consumer team controls timing.
|
|
57
|
+
- Is the field actually read at runtime, or just typed? Type-only references don't fail at runtime even when the schema diverges.
|
|
58
|
+
|
|
59
|
+
For an API response change (without consumer-side schema):
|
|
60
|
+
|
|
61
|
+
- Does the consumer JSON-parse and read specific keys, or pass the body through opaquely (e.g. to a logger, to storage)?
|
|
62
|
+
- Does any layer in between (BFF, gateway) apply its own validation?
|
|
63
|
+
|
|
64
|
+
Answer these from real code, not from priors about "how FEs usually work." When you can't answer, you do not have a finding — you have a hypothesis.
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Posting an anchored PR review (both modes)
|
|
2
|
+
|
|
3
|
+
Read this once the user approves items to post. Referenced from `SKILL.md`.
|
|
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
|
+
## API call and payload
|
|
12
|
+
|
|
13
|
+
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
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# /tmp/simple-review-payload.json contains: {event, commit_id, body, comments: [...]}
|
|
17
|
+
gh api -X POST "repos/<owner>/<repo>/pulls/<N>/reviews" --input /tmp/simple-review-payload.json
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Payload shape:
|
|
21
|
+
|
|
22
|
+
```json
|
|
23
|
+
{
|
|
24
|
+
"event": "COMMENT",
|
|
25
|
+
"commit_id": "<head_sha>",
|
|
26
|
+
"body": "<summary>",
|
|
27
|
+
"comments": [
|
|
28
|
+
{ "path": "src/foo.ts", "line": 42, "side": "RIGHT", "body": "..." },
|
|
29
|
+
{
|
|
30
|
+
"path": "src/bar.ts",
|
|
31
|
+
"start_line": 10,
|
|
32
|
+
"line": 14,
|
|
33
|
+
"start_side": "RIGHT",
|
|
34
|
+
"side": "RIGHT",
|
|
35
|
+
"body": "..."
|
|
36
|
+
}
|
|
37
|
+
]
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Rules:
|
|
42
|
+
|
|
43
|
+
- `event` is **always `COMMENT`** — never `APPROVE` or `REQUEST_CHANGES`. Approval is a human decision.
|
|
44
|
+
- Multi-line ranges: `start_line`, `line`, `start_side: "RIGHT"`, `side: "RIGHT"`.
|
|
45
|
+
- No clean anchor → pick the first changed line of the most relevant file; if literally nothing anchorable, fold into the review `body` as a labeled "general note" and flag in the post-confirmation summary.
|
|
46
|
+
- `commit_id` from `pr.headRefOid`.
|
|
47
|
+
- Build JSON with literal newlines (use `jq -n --arg body "$BODY" '...'` or a small `python -c`/heredoc), not `\n` escapes.
|
|
48
|
+
|
|
49
|
+
## Review body (top-level)
|
|
50
|
+
|
|
51
|
+
Three blocks, in order:
|
|
52
|
+
|
|
53
|
+
**1. Attribution line.** Exactly:
|
|
54
|
+
|
|
55
|
+
> _These comments were generated by @\<viewer-login\> using Claude Code._
|
|
56
|
+
|
|
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 Simple Review skill by name; it's a local skill the PR author can't see or use.
|
|
58
|
+
|
|
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.
|
|
60
|
+
|
|
61
|
+
**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
|
+
|
|
63
|
+
````markdown
|
|
64
|
+
**Apply all comments at once** — paste this into Claude Code on a checkout of this branch:
|
|
65
|
+
|
|
66
|
+
```
|
|
67
|
+
Fetch the most recent review by @<viewer-login> on PR <PR_URL>. 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
|
+
```
|
|
69
|
+
````
|
|
70
|
+
|
|
71
|
+
## Each comment body
|
|
72
|
+
|
|
73
|
+
**Budget:** ≤60 words of prose total + the code block. Hard caps below are binding — if a section won't fit, the finding is probably two findings; split or drop one.
|
|
74
|
+
|
|
75
|
+
````markdown
|
|
76
|
+
**[SEVERITY] Title** <!-- ≤8 words -->
|
|
77
|
+
|
|
78
|
+
<Point — 1 sentence, ≤25 words. References to other code use GitHub permalinks pinned to head_sha, not bare `file:lines`. The line(s) the comment is anchored to do not need to be relinked.>
|
|
79
|
+
|
|
80
|
+
**Why it matters:** <failure_mode — 1 sentence, ≤20 words. **Drop this line entirely** when it would only rephrase the Point.>
|
|
81
|
+
|
|
82
|
+
**Suggested fix:**
|
|
83
|
+
|
|
84
|
+
```suggestion
|
|
85
|
+
<suggested_fix.after — replaces the anchored line(s); GitHub renders the diff vs. the anchored line(s) AND an "Apply suggestion" button>
|
|
86
|
+
```
|
|
87
|
+
````
|
|
88
|
+
|
|
89
|
+
Rules:
|
|
90
|
+
|
|
91
|
+
- **No bulleted lists in the comment body.** Bullets fragment reasoning; either the prose fits in one sentence or it doesn't belong on the PR.
|
|
92
|
+
- **No prose preamble on the suggested fix.** The code block speaks for itself. Don't write "Suggested fix — route Rate the same way as Pay" before the block; just show the block.
|
|
93
|
+
- **No trailing addenda.** "If feature X isn't shipped yet…", "Note that this also affects…", "While you're here…" — these belong in the in-chat synthesis, not on the posted comment. The reviewee can ask follow-ups on the thread.
|
|
94
|
+
- **Optional Example/context fenced block is opt-out by default.** Include a non-suggestion code block only when prose-plus-`suggestion` is genuinely ambiguous (e.g. you're flagging a pattern violation and the offending pattern is not in the anchored lines). Default: skip.
|
|
95
|
+
- **Include a `suggestion` block whenever it makes the fix concrete.** Skip when the issue is purely structural or when prose alone says everything.
|
|
96
|
+
- **`suggestion` block stands alone on the PR.** GitHub already renders the diff vs. anchored line(s). Do **NOT** include a `// Before` fenced block in PR comments — it duplicates what GitHub shows. This is different from the in-chat **Actionable** section, which DOES render `// Before` + `// After` pairs so the user can review before approving the post.
|
|
97
|
+
- **When to skip the `suggestion` block:** structural fix with no drop-in (use prose + a target-shape fenced block), OR `suggested_fix.after` is empty (pure deletion — write "_Delete the anchored line(s)._" instead), OR `suggested_fix.before` is empty (pure addition — `suggestion` block still works; prefix `after` with `// Add after line <N>`).
|
|
98
|
+
- **Permalinks for in-prose line references.** Build as `https://github.com/<owner>/<repo>/blob/<head_sha>/<path>#L<start>-L<end>` (single line: `#L<n>`). Always pin to `head_sha`. Use Markdown link syntax with a meaningful label.
|
|
99
|
+
|
|
100
|
+
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).
|