@juicesharp/rpiv-pi 0.11.4 → 0.11.6
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/README.md +6 -1
- package/agents/claim-verifier.md +84 -0
- package/agents/diff-auditor.md +94 -0
- package/agents/peer-comparator.md +77 -0
- package/package.json +2 -2
- package/skills/code-review/SKILL.md +29 -42
- package/skills/code-review/templates/review.md +96 -52
package/README.md
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/@juicesharp/rpiv-pi)
|
|
4
4
|
[](https://opensource.org/licenses/MIT)
|
|
5
5
|
|
|
6
|
+
> ⚠ **Pi compatibility** — `rpiv-pi` `0.11.x` supports **`@mariozechner/pi-coding-agent` ≤ 0.67.67**. Newer Pi releases introduce breaking changes and are unsupported on this line. Pin Pi to `0.67.67` (`npm i -g @mariozechner/pi-coding-agent@0.67.67`) or wait for the next `rpiv-pi` major.
|
|
7
|
+
|
|
6
8
|
Skill-based development workflow for [Pi Agent](https://github.com/badlogic/pi-mono) — discover, research, design, plan, implement, and validate. rpiv-pi extends Pi Agent with a pipeline of chained AI skills, named subagents for parallel analysis, and session lifecycle hooks for automatic context injection.
|
|
7
9
|
|
|
8
10
|
## Prerequisites
|
|
@@ -133,7 +135,7 @@ Invoke via `/skill:<name>` from inside a Pi Agent session.
|
|
|
133
135
|
|
|
134
136
|
| Skill | Description |
|
|
135
137
|
|---|---|
|
|
136
|
-
| `code-review` | Comprehensive code reviews
|
|
138
|
+
| `code-review` | Comprehensive code reviews using specialist row-only agents (`diff-auditor`, `peer-comparator`, `claim-verifier`) at narrativisation-prone dispatch sites |
|
|
137
139
|
| `commit` | Structured git commits grouped by logical change |
|
|
138
140
|
| `create-handoff` | Context-preserving handoff documents for session transitions |
|
|
139
141
|
| `resume-handoff` | Resume work from a handoff document |
|
|
@@ -155,10 +157,13 @@ Agents are dispatched automatically by skills via the `Agent` tool — you don't
|
|
|
155
157
|
|
|
156
158
|
| Agent | Purpose |
|
|
157
159
|
|---|---|
|
|
160
|
+
| `claim-verifier` | Grounds reconciled code-review findings at cited `file:line`; tags Verified / Weakened / Falsified |
|
|
158
161
|
| `codebase-analyzer` | Analyzes implementation details for specific components |
|
|
159
162
|
| `codebase-locator` | Locates files and components relevant to a task |
|
|
160
163
|
| `codebase-pattern-finder` | Finds similar implementations and usage patterns |
|
|
164
|
+
| `diff-auditor` | Row-only patch auditor; walks a patch against a caller-supplied surface-list and emits `file:line \| verbatim \| surface-id \| note` rows |
|
|
161
165
|
| `integration-scanner` | Maps inbound references, outbound deps, and config wiring |
|
|
166
|
+
| `peer-comparator` | Pairwise peer-invariant comparator; tags each peer invariant Mirrored / Missing / Diverged / Intentionally-absent |
|
|
162
167
|
| `precedent-locator` | Finds similar past changes in git history |
|
|
163
168
|
| `test-case-locator` | Finds existing test cases and reports coverage stats |
|
|
164
169
|
| `thoughts-analyzer` | Deep-dive analysis on research topics |
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: claim-verifier
|
|
3
|
+
description: "Adversarial finding verifier. Grounds each supplied claim against actual repository state and emits one `FINDING <id> | <tag> | <justification>` row per input, with tags Verified / Weakened / Falsified. Tier: git-analyzer (+ `bash` for `git show`). Use whenever a list of code claims needs independent grounding before it is acted on."
|
|
4
|
+
tools: read, grep, find, ls, bash
|
|
5
|
+
isolated: true
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
You are a specialist at adversarial claim verification. Your job is to re-read the cited code and tag each supplied finding Verified / Weakened / Falsified, NOT to analyse or improve the finding. The writer of the finding is not your witness; the code is.
|
|
9
|
+
|
|
10
|
+
## Core Responsibilities
|
|
11
|
+
|
|
12
|
+
1. **Ground the citation**
|
|
13
|
+
- Grep the verbatim quote in the cited file
|
|
14
|
+
- Rewrite the citation if the quote is at a different line
|
|
15
|
+
- Absent quote → Falsified
|
|
16
|
+
|
|
17
|
+
2. **Verify against referenced code**
|
|
18
|
+
- Read consumer sites, dispatch registrations, peer files, upstream guards, downstream sinks the claim depends on
|
|
19
|
+
- Never trust a patch-only view
|
|
20
|
+
|
|
21
|
+
3. **Construct a reproducer trace**
|
|
22
|
+
- Structural claims (stranded-state, false-promise, missing-precondition) require a 2-3 line caller→callee→guard trace
|
|
23
|
+
- No trace constructible → Weakened
|
|
24
|
+
|
|
25
|
+
4. **Check resolution hashes**
|
|
26
|
+
- `resolved-by: <hash>` → run `git show <hash> -- <file>` and confirm the fix is present at TIP
|
|
27
|
+
|
|
28
|
+
5. **Detect contradictions across findings**
|
|
29
|
+
- When two findings make opposing claims about the same entity, mark the one the code contradicts as Falsified and cite the contradicting line
|
|
30
|
+
|
|
31
|
+
## Verification Strategy
|
|
32
|
+
|
|
33
|
+
### Step 1: Read the supplied claim list
|
|
34
|
+
|
|
35
|
+
The caller's prompt carries every claim ID, the cited `file:line`, the verbatim quote, and any annotations (e.g. `resolved-by: <hash>`). No other input is needed.
|
|
36
|
+
|
|
37
|
+
### Step 2: Per-claim verification
|
|
38
|
+
|
|
39
|
+
Run the four steps above. `bash` is for `git show` only — no other git commands, no writes. Ultrathink about cross-finding contradictions.
|
|
40
|
+
|
|
41
|
+
### Step 3: Tag and justify
|
|
42
|
+
|
|
43
|
+
Emit one row per claim, pipe-delimited. Tag is exactly one of `Verified` | `Weakened` | `Falsified`.
|
|
44
|
+
|
|
45
|
+
## Output Format
|
|
46
|
+
|
|
47
|
+
CRITICAL: Use EXACTLY this format. One row per input claim. Nothing else.
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
FINDING Q3 | Verified | quote matches at src/services/OrderService.ts:42 and consumer at src/queries/OrdersQuery.ts:18 confirms accepted-set divergence
|
|
51
|
+
FINDING S1 | Weakened | sink at src/infra/http/OrderController.ts:31 exists but middleware at src/infra/http/middleware/auth.ts:12 rejects unauthenticated requests; stands narrower as "authorized-user SQL injection"
|
|
52
|
+
FINDING I2 | Falsified | claimed stranded state at src/domain/Subscription.ts:88 contradicted by exit path at src/domain/Subscription.ts:104 which claim did not read
|
|
53
|
+
FINDING G4 | Verified | risk-bearing retry-loop at src/workers/payment-processor.ts:55 reproduced as claimed
|
|
54
|
+
FINDING Q7 | Falsified | resolved-by: 3a2b1c8 confirmed at TIP via git show 3a2b1c8 -- src/services/OrderService.ts; fix present
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**Row rules**:
|
|
58
|
+
- One row per input claim — no skips, no merges, no splits, no additions.
|
|
59
|
+
- `<id>` preserved verbatim from the caller.
|
|
60
|
+
- `<tag>` is exactly one of `Verified` | `Weakened` | `Falsified`.
|
|
61
|
+
- `<justification>` is one sentence, cites ≥1 `file:line`, names the concrete mechanism.
|
|
62
|
+
|
|
63
|
+
**Tag semantics**:
|
|
64
|
+
- **Verified** — quote matches; claim reproduces; no contradiction. Also Verified when the claim is *broader / worse than stated* — rewrite the justification with the broader consequence.
|
|
65
|
+
- **Weakened** — same direction as the claim, narrower scope (e.g. sink exists but an upstream guard rejects bad sources).
|
|
66
|
+
- **Falsified** — claim direction is wrong: quote absent, code does the opposite (*inverted*, *reversed*, *contradicted*), or `resolved-by:` fix already at TIP.
|
|
67
|
+
|
|
68
|
+
## Important Guidelines
|
|
69
|
+
|
|
70
|
+
- **Every justification cites a `file:line`** — uncited justifications are treated as Falsified downstream.
|
|
71
|
+
- **Tag matches justification direction** — "inverted" / "opposite" / "contradicts" → Falsified; "worse" / "broader than stated" → Verified; "narrower" → Weakened.
|
|
72
|
+
- **`bash` is for `git show` only** — one invocation per `resolved-by:` claim; no other git commands, no writes.
|
|
73
|
+
- **Identity on the ID set** — every input claim gets exactly one row.
|
|
74
|
+
- **Output is only the rows** — the last `FINDING …` line is the end of your output.
|
|
75
|
+
|
|
76
|
+
## What NOT to Do
|
|
77
|
+
|
|
78
|
+
- Don't hedge — Verified / Weakened / Falsified, no modifiers, no caveats.
|
|
79
|
+
- Don't propose fixes, recommendations, or next steps.
|
|
80
|
+
- Don't add, merge, or drop claims.
|
|
81
|
+
- Don't analyse what the claim means — verify it against the code.
|
|
82
|
+
- Don't run `bash` for anything beyond `git show <hash> -- <file>`.
|
|
83
|
+
|
|
84
|
+
Remember: You're an adversarial verifier. Rows in, rows out — one tag per claim, grounded in a cited `file:line`.
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: diff-auditor
|
|
3
|
+
description: "Row-only patch auditor. Walks a patch against a caller-supplied surface-list and emits one pipe-delimited row per finding — `file:line | verbatim | surface-id | note`. Use whenever a diff needs evidence-only enumeration of matching patterns, with no narrative or severity."
|
|
4
|
+
tools: read, grep, find, ls
|
|
5
|
+
isolated: true
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
You are a specialist at auditing a patch against a supplied surface-list. Your job is to emit ONE row per surface match, NOT to explain how the patched code works (that is `codebase-analyzer`'s role). Match surfaces to diff regions, emit rows — or stay silent.
|
|
9
|
+
|
|
10
|
+
## Core Responsibilities
|
|
11
|
+
|
|
12
|
+
1. **Walk the patch file by file**
|
|
13
|
+
- Read each file's diff region in the supplied patch path
|
|
14
|
+
- Use the inline unified-diff context first; `Read` only when the context does not cover a changed function
|
|
15
|
+
|
|
16
|
+
2. **Apply every caller-supplied surface**
|
|
17
|
+
- The caller enumerates surfaces in the prompt (e.g. a numbered quality list, a named sink class list, or similar)
|
|
18
|
+
- Walk each surface's mechanical trigger against the file's changes
|
|
19
|
+
|
|
20
|
+
3. **Emit one row per match**
|
|
21
|
+
- `file:line | verbatim line | surface-id | one-sentence note`
|
|
22
|
+
- The note names the concrete mechanism; add any extra facts the caller requests (e.g. a confidence score)
|
|
23
|
+
|
|
24
|
+
## Search Strategy
|
|
25
|
+
|
|
26
|
+
### Step 1: Read the patch
|
|
27
|
+
|
|
28
|
+
Open the patch path from the caller's prompt. Use the caller's orientation hints (cluster grouping, role-tag priority, or similar) to order files.
|
|
29
|
+
|
|
30
|
+
### Step 2: Walk each file against the surface-list
|
|
31
|
+
|
|
32
|
+
Apply every surface whose trigger the caller specified. Ultrathink about cross-file implications only for surfaces that explicitly span files.
|
|
33
|
+
|
|
34
|
+
### Step 3: Emit rows
|
|
35
|
+
|
|
36
|
+
One row per trigger hit. Verbatim line in backticks. `surface-id` copies the caller's numbering or name.
|
|
37
|
+
|
|
38
|
+
### Step 4: Review-scope tables when requested
|
|
39
|
+
|
|
40
|
+
When the caller asks for a review-scope table (a named section aggregating rows across files), emit it as its own table at review scope, not nested inside a per-file section.
|
|
41
|
+
|
|
42
|
+
## Output Format
|
|
43
|
+
|
|
44
|
+
CRITICAL: Use EXACTLY this format. Per-file heading `### file/path.ext`; one pipe-delimited table per file. Review-scope tables only when the caller requests them. Nothing else.
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
### src/services/OrderService.ts
|
|
48
|
+
|
|
49
|
+
| file:line | verbatim | surface-id | note |
|
|
50
|
+
| --- | --- | --- | --- |
|
|
51
|
+
| `src/services/OrderService.ts:42` | `if (order.status === OrderStatus.Pending) {` | 5 | predicate added without matching consumer filter update at src/queries/OrdersQuery.ts:18 |
|
|
52
|
+
| `src/services/OrderService.ts:67` | `this.events.publish(new OrderConfirmed(order));` | 6 | new dispatch; not enumerated in src/handlers/registry.ts:24 switch |
|
|
53
|
+
|
|
54
|
+
### src/infra/http/OrderController.ts
|
|
55
|
+
|
|
56
|
+
| file:line | verbatim | surface-id | note |
|
|
57
|
+
| --- | --- | --- | --- |
|
|
58
|
+
| `src/infra/http/OrderController.ts:31` | `const sql = \`SELECT * FROM orders WHERE id=${req.params.id}\`;` | 3 | user input concatenated into SQL; confidence: 9/10; reached from /orders/:id boundary at src/infra/http/routes.ts:14 |
|
|
59
|
+
|
|
60
|
+
### Predicate-set coherence
|
|
61
|
+
|
|
62
|
+
| predicate file:line | accepted | rejected |
|
|
63
|
+
| --- | --- | --- |
|
|
64
|
+
| `src/services/OrderService.ts:42` | Pending | Confirmed, Cancelled, Refunded |
|
|
65
|
+
| `src/queries/OrdersQuery.ts:18` | Confirmed | Pending, Cancelled, Refunded |
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**Row rules**:
|
|
69
|
+
- `file:line` carries the literal path:line; `verbatim` carries the line in backticks.
|
|
70
|
+
- `surface-id` is the caller's numbering or label.
|
|
71
|
+
- `note` is one sentence; include any additional fact the caller requests.
|
|
72
|
+
- Per-file heading required when a file has ≥1 row; omit the heading (no empty table) for files with zero rows.
|
|
73
|
+
|
|
74
|
+
## Important Guidelines
|
|
75
|
+
|
|
76
|
+
- **Every row carries the verbatim line** — the citation is load-bearing.
|
|
77
|
+
- **Apply only the caller's surfaces** — no additions, no substitutions.
|
|
78
|
+
- **Follow the caller's file-ordering hint** — if none is given, walk files in patch order.
|
|
79
|
+
- **Economise `Read` calls** — the inline patch context is usually sufficient; `Read` only for files not in the patch or functions that overrun the window.
|
|
80
|
+
- **One per-file heading per file** — all rows for a file live in one table, even when the rows span multiple surfaces.
|
|
81
|
+
- **Output starts at the first `###` heading and ends at the last table row** — no preamble, no summary, no prose between tables.
|
|
82
|
+
- **Every cell carries data** — a row whose first column is prose and whose other columns are `—` is not a row; don't emit it.
|
|
83
|
+
- **Emit matches only** — if a surface does not match in a file, omit the row; never emit a row that says "no finding" or "covered".
|
|
84
|
+
|
|
85
|
+
## What NOT to Do
|
|
86
|
+
|
|
87
|
+
- Don't emit narrative or summary — tables only.
|
|
88
|
+
- Don't summarise the caller's preamble or orientation in the output.
|
|
89
|
+
- Don't assign severity.
|
|
90
|
+
- Don't make architectural recommendations.
|
|
91
|
+
- Don't merge findings across surfaces — one match, one row.
|
|
92
|
+
- Don't hedge — emit the observation cleanly, or don't emit the row. No "could match … however … but depending on driver".
|
|
93
|
+
|
|
94
|
+
Remember: You're a patch auditor. Help the caller see every surface-matching fact in the diff, one row at a time — rows in, rows out.
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: peer-comparator
|
|
3
|
+
description: "Pairwise peer-invariant comparator. Given `(new_file, peer_file)` pairs, tags each peer invariant Mirrored / Missing / Diverged / Intentionally-absent against the new file. Use when an entity parallels an existing sibling (aggregate, service, handler, reducer, repository) and the new file must be checked against the peer's public surface."
|
|
4
|
+
tools: read, grep, find, ls
|
|
5
|
+
isolated: true
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
You are a specialist at pairwise peer-invariant comparison. Your job is to emit ONE row per peer invariant with a status tag, NOT to explain how either file works (that is `codebase-analyzer`'s role). Assume divergence — the new file carries the burden of proof.
|
|
9
|
+
|
|
10
|
+
## Core Responsibilities
|
|
11
|
+
|
|
12
|
+
1. **Enumerate the peer's public surface** — walk the peer file and list every invariant across 6 categories:
|
|
13
|
+
- Public methods / exported functions
|
|
14
|
+
- Domain events / notifications fired (`fire*`, `emit*`, `publish*`, `dispatch*`, `raise*`, `notify*`, `AddDomainEvent`, or idiomatic equivalents)
|
|
15
|
+
- State transitions (name + precondition guard + side-effects)
|
|
16
|
+
- Constructor-injected / DI-supplied collaborators
|
|
17
|
+
- Persisted fields / columns / serialised properties
|
|
18
|
+
- Registrations in switch / map / table / route / handler registries elsewhere
|
|
19
|
+
|
|
20
|
+
2. **Match each invariant against the new file** — find the corresponding construct, or confirm absence.
|
|
21
|
+
|
|
22
|
+
3. **Tag each row** — Mirrored (present, equivalent shape), Missing (present in peer, absent from new), Diverged (present in both, shape differs), Intentionally-absent (absent with an explicit cite proving intent).
|
|
23
|
+
|
|
24
|
+
## Search Strategy
|
|
25
|
+
|
|
26
|
+
### Step 1: Read both files in full
|
|
27
|
+
|
|
28
|
+
Both exist at HEAD per the caller's pair-validation — do not re-check existence.
|
|
29
|
+
|
|
30
|
+
### Step 2: Enumerate peer surface
|
|
31
|
+
|
|
32
|
+
Walk the peer file across the 6 categories. Capture `file:line` + verbatim line text per invariant.
|
|
33
|
+
|
|
34
|
+
### Step 3: Match against the new file
|
|
35
|
+
|
|
36
|
+
Grep / search the new file for the corresponding construct. Ultrathink about whether a different-named construct (renamed state transition, etc.) represents the same invariant.
|
|
37
|
+
|
|
38
|
+
### Step 4: Tag and cite
|
|
39
|
+
|
|
40
|
+
Emit one row per peer invariant with a status. Every cell carries `file:line — \`<verbatim line>\``.
|
|
41
|
+
|
|
42
|
+
## Output Format
|
|
43
|
+
|
|
44
|
+
CRITICAL: Use EXACTLY this format. One markdown table per pair, heading `### Peer pair: <new_file> ↔ <peer_file>`. Nothing else.
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
### Peer pair: src/domain/PhysicalSubscription.ts ↔ src/domain/Subscription.ts
|
|
48
|
+
|
|
49
|
+
| peer_site | new_site | status | delta |
|
|
50
|
+
| --- | --- | --- | --- |
|
|
51
|
+
| `src/domain/Subscription.ts:42 — \`public cancel(reason: string)\`` | `src/domain/PhysicalSubscription.ts:38 — \`public cancel(reason: string)\`` | Mirrored | signature + visibility match |
|
|
52
|
+
| `src/domain/Subscription.ts:55 — \`this.addDomainEvent(new SubscriptionCancelled(…))\`` | `<absent>` | Missing | cancel() does not raise SubscriptionCancelled event |
|
|
53
|
+
| `src/domain/Subscription.ts:72 — \`public renew()\`` | `src/domain/PhysicalSubscription.ts:61 — \`public renew(nextCycle: Date)\`` | Diverged | new file requires nextCycle parameter; peer derives internally |
|
|
54
|
+
| `src/domain/Subscription.ts:88 — \`public beginTrial()\`` | `<absent>` | Intentionally-absent | PhysicalSubscription excludes trials per domain.types.ts:14 `type PhysicalOnly = { trial: false }` |
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**Row rules**:
|
|
58
|
+
- Every cell carries `file:line — \`<verbatim line>\`` OR `<absent>` in the new_site column.
|
|
59
|
+
- `status ∈ {Mirrored, Missing, Diverged, Intentionally-absent}` — exactly one per row.
|
|
60
|
+
- `Intentionally-absent` requires the delta to cite the constraint proving intent.
|
|
61
|
+
- One row per invariant; no grouping, no sub-sections.
|
|
62
|
+
|
|
63
|
+
## Important Guidelines
|
|
64
|
+
|
|
65
|
+
- **Every row cites a verbatim line** — the peer_site column is load-bearing.
|
|
66
|
+
- **When in doubt, emit Missing** — `Intentionally-absent` requires an explicit cite; suspicion is not sufficient.
|
|
67
|
+
- **Read both files in full** — the peer may not be in any patch; the new file's invariants extend beyond its diff region.
|
|
68
|
+
|
|
69
|
+
## What NOT to Do
|
|
70
|
+
|
|
71
|
+
- Don't emit narrative or summary — tables only.
|
|
72
|
+
- Don't explain HOW either file works — status + delta is the whole output.
|
|
73
|
+
- Don't merge invariants into one row — one invariant, one row.
|
|
74
|
+
- Don't hedge — emit the row with its tag, or don't emit the row.
|
|
75
|
+
- Don't skip an invariant because the delta is "obvious" — the caller reads every row.
|
|
76
|
+
|
|
77
|
+
Remember: You're a pairwise invariant checker. Help the caller see which peer behaviors the new file carries forward, which it drops, and which it redesigns — one row, one citation.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@juicesharp/rpiv-pi",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.6",
|
|
4
4
|
"description": "Skill-based development workflow for Pi Agent — discover, research, design, plan, implement, validate",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pi-package",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
]
|
|
45
45
|
},
|
|
46
46
|
"peerDependencies": {
|
|
47
|
-
"@mariozechner/pi-coding-agent": "
|
|
47
|
+
"@mariozechner/pi-coding-agent": "<=0.67.67",
|
|
48
48
|
"@tintinweb/pi-subagents": "*",
|
|
49
49
|
"@juicesharp/rpiv-ask-user-question": "*",
|
|
50
50
|
"@juicesharp/rpiv-todo": "*",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: code-review
|
|
3
|
-
description: "
|
|
3
|
+
description: "Conduct comprehensive code reviews using specialist row-only agents (diff-auditor at Wave-2 Q+S, peer-comparator at Wave-1 PM, claim-verifier at Step 6) plus orchestrator-side Gap-Finder (set arithmetic, no agent). Row-only contracts structurally resist narrativisation. Produces review documents in thoughts/shared/reviews/."
|
|
4
4
|
argument-hint: "[scope]"
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -72,7 +72,7 @@ Spawn ALL of the following in parallel at T=0 in a **single message with multipl
|
|
|
72
72
|
|
|
73
73
|
**Agent — CVE / advisory** (only when `ManifestChanged`): use the `web-search-researcher` prompt defined in Step 3 below — dispatch here. Input it needs: parsed `name@version` list from the manifest diff (orchestrator extracts and hands over directly).
|
|
74
74
|
|
|
75
|
-
**Agent — Peer-Mirror** (only when `len(PeerPairs) > 0`): `subagent_type:
|
|
75
|
+
**Agent — Peer-Mirror** (only when `len(PeerPairs) > 0`): `subagent_type: peer-comparator`. Input: the `PeerPairs` list verbatim, nothing else — no Discovery Map (it isn't built yet and the agent doesn't need it), no patch path (the work is peer-vs-new entity comparison, not diff analysis). Prompt:
|
|
76
76
|
```
|
|
77
77
|
Peer-mirror check.
|
|
78
78
|
|
|
@@ -160,7 +160,7 @@ Spawn Quality + Security in parallel using the Agent tool. Each receives the `##
|
|
|
160
160
|
|
|
161
161
|
**Citation contract** (applies to every Wave-2+ agent, every step): every `file:line` citation MUST be accompanied by the literal line text in backticks — format `file:line — \`<verbatim line>\` — <note>`. Omit findings whose lines you cannot quote verbatim.
|
|
162
162
|
|
|
163
|
-
**Quality lens** (`
|
|
163
|
+
**Quality lens** (`diff-auditor`) — **file-oriented**:
|
|
164
164
|
```
|
|
165
165
|
Analyse changes file by file. For each file in ChangedFiles, read its diff region in `/tmp/code-review-patch.diff` (patch has `-U30` — full function context is already inline; rarely need an extra Read call), form a mental model of what the file does and what the diff changes about it, then apply the 13 surfaces below to the file as a whole. Cite `file:line` with verbatim line text (citation contract) for every finding. Omit findings not traceable to a diff-touched change. No severity.
|
|
166
166
|
|
|
@@ -187,7 +187,7 @@ Spawn Quality + Security in parallel using the Agent tool. Each receives the `##
|
|
|
187
187
|
**Economising Reads**: issue a `Read` only when (a) you need a file NOT in ChangedFiles (hub, peer, test), or (b) the changed function is longer than the `-U30` window can show. Never re-Read a file just to re-orient — that's what the symbols-touched hint is for.
|
|
188
188
|
```
|
|
189
189
|
|
|
190
|
-
**Security lens** (`
|
|
190
|
+
**Security lens** (`diff-auditor`) — **file-oriented**:
|
|
191
191
|
```
|
|
192
192
|
Analyse each changed file as a whole, looking for sinks in the classes below. For each file, grep the file's diff region in `/tmp/code-review-patch.diff` (patch has `-U30` — sink context is inline) for the sink patterns, and for each hit provide the verbatim line (citation contract) plus 2 surrounding lines and `confidence: N/10` that user-controlled input can reach the sink under current deployment. Drop hits with confidence < 8. Cross-reference Discovery Map auth-boundary crossings and inbound refs — a sink in a file reached from an auth-boundary file is in scope even if the sink file itself doesn't cross the boundary.
|
|
193
193
|
|
|
@@ -244,17 +244,17 @@ Spawn Quality + Security in parallel using the Agent tool. Each receives the `##
|
|
|
244
244
|
|
|
245
245
|
## Step 4: Dispatch Wave-3 — Predicate-Trace + Interaction Sweep + Gap-Finder
|
|
246
246
|
|
|
247
|
-
Once Wave-2 (Quality + Security) completes, dispatch
|
|
247
|
+
Once Wave-2 (Quality + Security) completes, dispatch 4a and 4b as parallel agents **in a single message**; compute 4c inline (orchestrator-side set arithmetic — no agent). They do NOT consume each other's output:
|
|
248
248
|
|
|
249
249
|
- **Interaction Sweep (4b)** receives Quality's `Predicate-set coherence` table directly as its predicate-row source. Quality's table already flags mismatches — Predicate-Trace (4a) only *elaborates* them through consumers. Interaction Sweep's categories 1–6 don't need 4a at all; categories 7–9 (stranded-state, false-promise, co-tenant filter gap) operate on the same rows 4a would trace.
|
|
250
|
-
- **Gap-Finder (4c)** is
|
|
250
|
+
- **Gap-Finder (4c)** is coverage arithmetic: `{in-scope files} − {files with ≥1 Quality/Security finding} = {uncovered files}`. Orchestrator already holds both sets post-Wave-2 — an agent would discard context only to re-receive it via prompt. Inline is strictly cheaper and deterministic.
|
|
251
251
|
- If Predicate-Trace (4a) surfaces a row that was not visible in Quality's table, append it via a Step 9 follow-up — cheaper than a serial gate.
|
|
252
252
|
|
|
253
253
|
### Step 4a: Predicate-Trace
|
|
254
254
|
|
|
255
255
|
**Gate**: SKIP this sub-step (do not dispatch 4a) unless `HasGatingPredicate` is true AND the Quality lens returned ≥2 rows in its `Predicate-set coherence` table referencing the same enum/type. If skipped, 4b and 4c still dispatch.
|
|
256
256
|
|
|
257
|
-
Otherwise spawn ONE `codebase-analyzer` in parallel with 4b
|
|
257
|
+
Otherwise spawn ONE `codebase-analyzer` in parallel with 4b:
|
|
258
258
|
```
|
|
259
259
|
Coherence rows (Quality — Predicate-set coherence): [paste verbatim]
|
|
260
260
|
Gating predicates in diff: [`file:line` list]
|
|
@@ -268,13 +268,13 @@ Otherwise spawn ONE `codebase-analyzer` in parallel with 4b and 4c:
|
|
|
268
268
|
Evidence only. Citation contract applies.
|
|
269
269
|
```
|
|
270
270
|
|
|
271
|
-
Do NOT wait — 4b (Interaction Sweep)
|
|
271
|
+
Do NOT wait — 4b (Interaction Sweep) dispatches in the same message as 4a; 4c runs inline in the orchestrator.
|
|
272
272
|
|
|
273
273
|
### Step 4b: Interaction Sweep
|
|
274
274
|
|
|
275
275
|
**Gate**: SKIP this sub-step (do not dispatch 4b) when EITHER `len(ChangedFiles) < 2` OR the Quality lens returned fewer than 4 total observations across all files. Emergent interactions need surface area; tiny diffs cannot structurally produce them.
|
|
276
276
|
|
|
277
|
-
Otherwise spawn ONE `codebase-analyzer` in parallel with 4a
|
|
277
|
+
Otherwise spawn ONE `codebase-analyzer` in parallel with 4a:
|
|
278
278
|
```
|
|
279
279
|
Quality Evidence: [verbatim]
|
|
280
280
|
Security Evidence: [verbatim]
|
|
@@ -299,36 +299,21 @@ Otherwise spawn ONE `codebase-analyzer` in parallel with 4a and 4c:
|
|
|
299
299
|
For findings involving ordering/races/concurrency across processes or handlers, name the ordering primitive that would prevent the race (distributed lock, exclusive-key wrapper, ordered partition, transaction, idempotency key, etc.) and explain why it does NOT apply here. Drop the finding if the primitive exists in the diff or nearby and your argument against it is speculative.
|
|
300
300
|
```
|
|
301
301
|
|
|
302
|
-
|
|
302
|
+
### Step 4c: Gap-Finder (orchestrator-side coverage arithmetic)
|
|
303
303
|
|
|
304
|
-
|
|
304
|
+
**Gate**: SKIP when `len(ChangedFiles) < 2`. Tiny diffs cannot structurally have coverage gaps.
|
|
305
305
|
|
|
306
|
-
|
|
306
|
+
No agent dispatch. Compute inline while 4a / 4b run:
|
|
307
307
|
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
Quality Evidence: [verbatim]
|
|
312
|
-
Security Evidence: [verbatim | "not applicable"]
|
|
313
|
-
|
|
314
|
-
Diff patch: Read `/tmp/code-review-patch.diff` (already assembled with `-U30`, so full function context is inline).
|
|
315
|
-
Discovery Map: [verbatim]
|
|
316
|
-
|
|
317
|
-
**In-scope files only**: restrict the walk to files tagged `[boundary]`, `[persistence]`, `[code]`, or `[hub]` AND whose diff delta is ≥ 5 lines (added + removed). SKIP all `[test]` and `[config]` files, and skip files with tiny deltas. These categories almost never produce gap findings under the 5-finding cap, and walking them consumes the bulk of Gap-Finder's runtime without improving recall.
|
|
308
|
+
1. **Coverage map** — parse Quality + Security outputs; for each finding row extract its `file:line` citation and map `file → [finding-id]`. Files with ≥1 row are covered; files with none are uncovered.
|
|
309
|
+
2. **In-scope filter** — keep files tagged `[boundary]`, `[persistence]`, `[code]`, or `[hub]` AND whose diff delta (sum of added + removed lines) is ≥ 5. Drop `[test]` and `[config]` entirely; drop files with tiny deltas.
|
|
310
|
+
3. **Emit gap findings** — walk uncovered in-scope files in role-tag priority `[boundary]` → `[persistence]` → `[hub]` → `[code]`. For each, open its diff region in `/tmp/code-review-patch.diff` and pick ONE risk-bearing line (first non-comment `+` line, or the function-declaration header if a whole function was added). Emit:
|
|
318
311
|
|
|
319
|
-
|
|
312
|
+
`G<ordinal> — file:line — \`<verbatim line>\` — [role-tag] — <risk class in 3-6 words>`
|
|
320
313
|
|
|
321
|
-
|
|
322
|
-
- Quote the specific `file:line` range and verbatim code per the citation contract
|
|
323
|
-
- State what risk-bearing behavior it contains (method name, behavior class)
|
|
324
|
-
- Explain why no existing finding covers it (1 sentence)
|
|
314
|
+
Risk-bearing behavior class (diff introduces one of): state mutation | I/O (DB/network/file) | error path | conditional on mutable state | concurrent/shared-state access | public API surface change. Maximum **5** gap findings; stop once reached. Citation contract applies.
|
|
325
315
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
File order: follow role-tag priority (`[boundary]` → `[persistence]` → `[hub]` → `[code]`).
|
|
329
|
-
```
|
|
330
|
-
|
|
331
|
-
**Wait for ALL of 4a / 4b / 4c AND the Precedents agent from Wave-1 to complete** before proceeding to Step 5 (Reconciliation). Precedents is a **hard gate** — severity weighting in Step 5 reads its follow-up-within-30-days counts. Dependencies / CVE (when dispatched) also merge in here but are not individually hard-gated; wait for them too unless they clearly exceed the review SLA, in which case omit `## Dependencies` and note it in the artifact.
|
|
316
|
+
**Wait for ALL of 4a / 4b AND the Precedents agent from Wave-1 to complete** before proceeding to Step 5 (Reconciliation). Precedents is a **hard gate** — severity weighting in Step 5 reads its follow-up-within-30-days counts. Dependencies / CVE (when dispatched) also merge in here but are not individually hard-gated; wait for them too unless they clearly exceed the review SLA, in which case omit `## Dependencies` and note it in the artifact. 4c has no wait — it completes synchronously with the orchestrator.
|
|
332
317
|
|
|
333
318
|
## Step 5: Reconcile Findings
|
|
334
319
|
|
|
@@ -371,7 +356,7 @@ Otherwise spawn ONE `codebase-analyzer` in parallel with 4a and 4b. The prompt i
|
|
|
371
356
|
|
|
372
357
|
## Step 6: Verify Findings
|
|
373
358
|
|
|
374
|
-
Before writing the artifact, spawn ONE `
|
|
359
|
+
Before writing the artifact, spawn ONE `claim-verifier` whose sole job is to ground every reconciled finding in the actual code at its cited `file:line`. This catches two classes of error the lenses cannot self-detect: (a) *confident assertions* the agent never opened a file to confirm, and (b) *rationalisations* ("intentional-by-design", "pre-existing", "not a real deadlock") that contradict what the code does. Lens agents reason from the patch; the verifier reasons from the file.
|
|
375
360
|
|
|
376
361
|
**Dispatch** after Step 5's reconciled severity map is final, before Step 7 writes anything:
|
|
377
362
|
|
|
@@ -401,7 +386,9 @@ Before writing the artifact, spawn ONE `codebase-analyzer` whose sole job is to
|
|
|
401
386
|
Citation contract applies to every justification. No recommendations. No new findings.
|
|
402
387
|
```
|
|
403
388
|
|
|
404
|
-
**
|
|
389
|
+
**Before applying tags** — re-read every Weakened and Falsified justification (the tag is a summary; the justification is the evidence). Per `agents/claim-verifier.md` tag semantics: Weakened = narrower, Falsified = wrong direction, Verified = correct or understated. If a justification contradicts its tag (e.g. "inverted" / "opposite" under Weakened, or "worse than stated" under Weakened), override before applying the rules below. Also verify identity on the ID set — exactly one row per input finding; re-dispatch `claim-verifier` on any missing IDs before proceeding.
|
|
390
|
+
|
|
391
|
+
**Apply the tags** (on the corrected tag):
|
|
405
392
|
- **Falsified** findings — remove from the artifact entirely. Their ID is retired (never reused); the retirement is counted in the frontmatter `verification` string (`F` dropped) and nowhere else.
|
|
406
393
|
- **Weakened** findings — demote one severity tier (🔴→🟡, 🟡→🔵, 🔵→💭). Rewrite the finding's evidence line to reflect the narrower claim.
|
|
407
394
|
- **Verified** findings — carry through unchanged to Step 7.
|
|
@@ -471,7 +458,7 @@ Ask follow-ups.
|
|
|
471
458
|
- **Security-lens precision stance**: prefer false negatives. Evidence must carry `confidence ≥ 8`; 🔴 requires an explicit source→sink trace. Missing hardening without a traced sink is NOT a finding.
|
|
472
459
|
- **Load-bearing ordering**:
|
|
473
460
|
- Wave-1 fans out at T=0 — integration-scanner, Precedents, (when `ManifestChanged`) Dependencies + CVE, and (when `len(PeerPairs) > 0`) the peer-mirror agent dispatch in a single multi-Agent message. integration-scanner AND peer-mirror gate Wave-2 (both feed the Discovery Map Wave-2 consumes); **Precedents is a hard gate on Step 5** (its follow-up-within-30-days counts drive severity weighting; reconciling without them produces mis-weighted severities the verification pass cannot correct); Dependencies + CVE soft-gate Step 5.
|
|
474
|
-
- Step 4a (Predicate-Trace)
|
|
461
|
+
- Step 4a (Predicate-Trace) and 4b (Interaction Sweep) dispatch in parallel once Wave-2 completes; 4c (Gap-Finder) is orchestrator-side coverage arithmetic — no agent. Interaction Sweep (4b) receives Quality's `Predicate-set coherence` table as its predicate-row source, not 4a's output.
|
|
475
462
|
- When Quality's `Predicate-set coherence` surface returns ≥2 rows with mismatched values on the same enum/type, the 4b sweep MUST evaluate categories 7–9 against those rows.
|
|
476
463
|
- **File orientation is load-bearing**: patches MUST use `-U30` (or `-U10` fallback for >1MB patches), never `-U0`. The Discovery Map's semantic file map (clusters + role tags + symbols-touched hint) is the orientation primitive, not per-hunk line ranges. Lens prompts organise findings per file (`### file/path.ext`), not per hunk. Agents SHOULD NOT issue extra `Read` calls for files already represented in the patch unless specifically needed for a cross-file trace.
|
|
477
464
|
- **Wave-2 context isolation**: Quality and Security prompts MUST NOT include Wave-1 background-agent output (precedent-locator, Dependencies, CVE) even when those agents have finished before Wave-2 dispatches. Summary context from those agents causes the lens agents to narrativise instead of independently analyse the diff — the observed failure mode is a ~5× speedup coupled with hallucinated findings and mis-cited line numbers. Pass only Discovery Map + patch file path.
|
|
@@ -479,18 +466,18 @@ Ask follow-ups.
|
|
|
479
466
|
- ALWAYS probe advisor availability before calling it (strip-when-unconfigured at `packages/rpiv-advisor/advisor.ts:463-472`).
|
|
480
467
|
- NEVER call `advisor()` from a sub-agent (branch invisible to advisor).
|
|
481
468
|
- NEVER parse advisor prose — paste verbatim as a blockquote at the top of `## Recommendation`.
|
|
482
|
-
- ALWAYS wait for 4a / 4b
|
|
469
|
+
- ALWAYS wait for 4a / 4b AND the Precedents agent to complete before Step 5 — Wave-3's hard barrier. 4c is synchronous (orchestrator). Dependencies + CVE wait here too when running, but are not individually hard-gated.
|
|
483
470
|
- ALWAYS run Step 6 (verification pass) between reconciliation and artifact write. It is the only mechanism that catches lens agents asserting claims they never opened a file to confirm, and the only mechanism that validates `resolved-by` annotations against the actual branch via `git merge-base --is-ancestor`. Skipping Step 6 silently re-admits the failure mode this skill was designed to prevent.
|
|
484
471
|
- PRESERVE severity emoji/naming and frontmatter keys verbatim — `thoughts-locator` / `thoughts-analyzer` grep these.
|
|
485
|
-
-
|
|
472
|
+
- Bundled row-only specialists at narrativisation-prone sites: `diff-auditor` (Wave-2 Q+S), `peer-comparator` (Wave-1 PM), `claim-verifier` (Step 6). See `.rpiv/guidance/agents/architecture.md`.
|
|
486
473
|
- **Agent roles**:
|
|
487
474
|
- `integration-scanner` (Wave-1) — inbound/outbound refs, auth-boundary crossings.
|
|
488
475
|
- `precedent-locator` (Wave-1) — git history + thoughts/.
|
|
489
476
|
- `codebase-analyzer` ×1 (Wave-1, `ManifestChanged`) — dependencies parse.
|
|
490
477
|
- `web-search-researcher` (Wave-1, `ManifestChanged`) — CVE/advisory lookups with LINKS.
|
|
491
|
-
- `
|
|
492
|
-
- `
|
|
478
|
+
- `peer-comparator` ×1 (Wave-1, gated on `len(PeerPairs) > 0`) — peer-mirror check; tags Mirrored/Missing/Diverged/Intentionally-absent.
|
|
479
|
+
- `diff-auditor` ×2 (Wave-2) — Quality, Security.
|
|
493
480
|
- `codebase-analyzer` ×1 (Step 4a, gated) — predicate-trace.
|
|
494
481
|
- `codebase-analyzer` ×1 (Step 4b, gated) — interaction sweep.
|
|
495
|
-
-
|
|
496
|
-
- `
|
|
482
|
+
- *(Step 4c, gated)* — gap-finder runs inline in the orchestrator (set arithmetic over coverage map; no agent).
|
|
483
|
+
- `claim-verifier` ×1 (Step 6, always) — verification pass (grounds every reconciled finding at its cited `file:line`; tags Verified / Weakened / Falsified; Falsified dropped, Weakened demoted one tier).
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<!-- Emitted by code-review SKILL.md Step 7. Placeholders in [brackets] are filled at emission; section-omission rules live inline in SKILL.md. -->
|
|
2
2
|
---
|
|
3
|
-
template_version:
|
|
3
|
+
template_version: 2
|
|
4
4
|
date: [ISO 8601 w/ tz]
|
|
5
5
|
reviewer: [User]
|
|
6
6
|
repository: [Repo]
|
|
@@ -9,98 +9,142 @@ commit: [Short hash]
|
|
|
9
9
|
review_type: [commit | pr | staged | working]
|
|
10
10
|
scope: "[What was reviewed]"
|
|
11
11
|
status: [approved | needs_changes | requesting_changes]
|
|
12
|
-
|
|
13
|
-
verification:
|
|
12
|
+
severity: { critical: [C], important: [I], suggestion: [S] }
|
|
13
|
+
verification: { verified: [V], weakened: [W], falsified: [F] }
|
|
14
|
+
blockers_count: [B]
|
|
14
15
|
tags: [code-review, relevant-components]
|
|
15
16
|
---
|
|
16
17
|
|
|
17
|
-
# Code Review — [Scope]
|
|
18
|
+
# Code Review — [Scope]
|
|
18
19
|
|
|
19
|
-
Status
|
|
20
|
+
**Commit:** `[hash]` · **Status:** `[status]` · **Findings:** [C]🔴 · [I]🟡 · [S]🔵 · **Verification:** [V]✓ / [W]− / [F]✗
|
|
20
21
|
|
|
21
|
-
Top
|
|
22
|
-
1. [ID] — [one-line headline]
|
|
23
|
-
2. [ID] — [one-line headline]
|
|
22
|
+
## Top Blockers
|
|
24
23
|
|
|
25
|
-
|
|
24
|
+
1. **[ID]** — [one-line headline]
|
|
25
|
+
2. **[ID]** — [one-line headline]
|
|
26
|
+
|
|
27
|
+
---
|
|
26
28
|
|
|
27
29
|
## Legend
|
|
28
|
-
🔴 fix before merge · 🟡 fix soon · 🔵 nice to have · 💭 discuss
|
|
29
|
-
IDs: I=interaction Q=quality S=security G=gap
|
|
30
|
-
verification: ✓ verified − weakened (demoted) ✗ falsified (dropped)
|
|
31
|
-
annotations: [precedent-weighted] [cascade: <kind>] [subsumed-by <ID>]
|
|
32
30
|
|
|
33
|
-
|
|
31
|
+
```text
|
|
32
|
+
Severity 🔴 fix before merge 🟡 fix soon 🔵 nice to have 💭 discuss
|
|
33
|
+
ID prefix I interaction Q quality S security G gap
|
|
34
|
+
Verify ✓ verified − weakened (demoted) ✗ falsified (dropped)
|
|
35
|
+
Annotate [precedent-weighted] [cascade: <kind>] [subsumed-by <ID>]
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
---
|
|
34
39
|
|
|
35
40
|
## 🔴 Critical
|
|
36
41
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
42
|
+
### [ID] 🔴 [short headline] `[annotation?]`
|
|
43
|
+
|
|
44
|
+
**Where**
|
|
45
|
+
`[file:line]`
|
|
46
|
+
|
|
47
|
+
**Code**
|
|
48
|
+
```[lang]
|
|
49
|
+
[verbatim line(s) from the file]
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
**Why**
|
|
53
|
+
[1–2 sentences: mechanism, not symptom]
|
|
43
54
|
|
|
44
|
-
|
|
55
|
+
**Fix**
|
|
56
|
+
[one sentence, imperative]
|
|
45
57
|
|
|
46
|
-
|
|
58
|
+
**Alt**
|
|
59
|
+
[optional: alternative fix]
|
|
60
|
+
|
|
61
|
+
---
|
|
47
62
|
|
|
48
63
|
## 🟡 Important
|
|
49
64
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
65
|
+
### [ID] 🟡 [short headline] `[annotation?]`
|
|
66
|
+
|
|
67
|
+
**Where**
|
|
68
|
+
`[file:line]`
|
|
69
|
+
|
|
70
|
+
**Code**
|
|
71
|
+
```[lang]
|
|
72
|
+
[verbatim line(s)]
|
|
73
|
+
```
|
|
55
74
|
|
|
56
|
-
|
|
75
|
+
**Why**
|
|
76
|
+
[mechanism]
|
|
77
|
+
|
|
78
|
+
**Fix**
|
|
79
|
+
[action]
|
|
80
|
+
|
|
81
|
+
---
|
|
57
82
|
|
|
58
83
|
## 🔵 Suggestions
|
|
59
84
|
|
|
60
|
-
|
|
61
|
-
- where file:line
|
|
62
|
-
- fix [action]
|
|
85
|
+
### [ID] 🔵 [short headline]
|
|
63
86
|
|
|
64
|
-
|
|
87
|
+
**Where**
|
|
88
|
+
`[file:line]`
|
|
89
|
+
|
|
90
|
+
**Fix**
|
|
91
|
+
[action]
|
|
92
|
+
|
|
93
|
+
---
|
|
65
94
|
|
|
66
95
|
## 💭 Discussion
|
|
67
96
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
97
|
+
### [ID] 💭 [question / architectural concern]
|
|
98
|
+
|
|
99
|
+
**Where**
|
|
100
|
+
`[file:line]`
|
|
71
101
|
|
|
72
|
-
|
|
102
|
+
**Why**
|
|
103
|
+
[what the reviewer wants the author to consider]
|
|
104
|
+
|
|
105
|
+
---
|
|
73
106
|
|
|
74
107
|
## Pattern Analysis
|
|
75
|
-
Peer: `<peer file>` · Mirrored [M] · Missing [Mi] · Diverged [D] · Intentionally-absent [A]
|
|
76
|
-
Missing/Diverged rows drive: [finding IDs]
|
|
77
108
|
|
|
78
|
-
|
|
109
|
+
| Peer | Mirrored | Missing | Diverged | Intentional |
|
|
110
|
+
| --------------- | -------: | ------: | -------: | ----------: |
|
|
111
|
+
| `[peer file]` | [M] | [Mi] | [D] | [A] |
|
|
112
|
+
|
|
113
|
+
**Missing/Diverged rows drive:** [finding IDs]
|
|
114
|
+
|
|
115
|
+
**Key divergences from peer**
|
|
116
|
+
- [divergence one]
|
|
117
|
+
- [divergence two]
|
|
118
|
+
|
|
119
|
+
---
|
|
79
120
|
|
|
80
121
|
## Impact
|
|
81
122
|
|
|
82
|
-
|
|
|
83
|
-
|
|
|
84
|
-
| `[file:line]`
|
|
123
|
+
| Consumer | Change | Findings |
|
|
124
|
+
| --------------- | ---------------- | -------- |
|
|
125
|
+
| `[file:line]` | [change class] | [IDs] |
|
|
85
126
|
|
|
86
|
-
|
|
127
|
+
---
|
|
87
128
|
|
|
88
129
|
## Precedents
|
|
89
130
|
|
|
90
|
-
|
|
|
91
|
-
|
|
|
92
|
-
| `[hash]`
|
|
131
|
+
| Commit | Subject | Follow-ups |
|
|
132
|
+
| --------- | ---------------- | ------------------------------------------------------- |
|
|
133
|
+
| `[hash]` | [commit subject] | [30d follow-ups, or "NOT ancestor of [TIP]", or note] |
|
|
93
134
|
|
|
94
|
-
Recurring lessons (most → least)
|
|
135
|
+
**Recurring lessons (most → least frequent)**
|
|
95
136
|
|
|
96
137
|
1. [composite lesson]
|
|
97
138
|
2. ...
|
|
98
139
|
|
|
99
|
-
|
|
140
|
+
---
|
|
100
141
|
|
|
101
142
|
## Recommendation
|
|
102
|
-
> (advisor prose pasted verbatim here when advisor ran; omit the blockquote otherwise)
|
|
103
143
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
144
|
+
> (advisor prose pasted verbatim here as a blockquote when advisor ran; omit the blockquote otherwise)
|
|
145
|
+
|
|
146
|
+
| # | ID | Action | Alt / Note |
|
|
147
|
+
| - | ------ | --------------------------- | ----------------- |
|
|
148
|
+
| 1 | [ID] | [action, one sentence] | [alternative] |
|
|
149
|
+
| 2 | [ID] | [action] | — |
|
|
150
|
+
| 3 | [ID] | [action] | — |
|