@juicesharp/rpiv-pi 0.11.5 → 0.11.7
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
CHANGED
|
@@ -135,7 +135,7 @@ Invoke via `/skill:<name>` from inside a Pi Agent session.
|
|
|
135
135
|
|
|
136
136
|
| Skill | Description |
|
|
137
137
|
|---|---|
|
|
138
|
-
| `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 |
|
|
139
139
|
| `commit` | Structured git commits grouped by logical change |
|
|
140
140
|
| `create-handoff` | Context-preserving handoff documents for session transitions |
|
|
141
141
|
| `resume-handoff` | Resume work from a handoff document |
|
|
@@ -157,10 +157,13 @@ Agents are dispatched automatically by skills via the `Agent` tool — you don't
|
|
|
157
157
|
|
|
158
158
|
| Agent | Purpose |
|
|
159
159
|
|---|---|
|
|
160
|
+
| `claim-verifier` | Grounds reconciled code-review findings at cited `file:line`; tags Verified / Weakened / Falsified |
|
|
160
161
|
| `codebase-analyzer` | Analyzes implementation details for specific components |
|
|
161
162
|
| `codebase-locator` | Locates files and components relevant to a task |
|
|
162
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 |
|
|
163
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 |
|
|
164
167
|
| `precedent-locator` | Finds similar past changes in git history |
|
|
165
168
|
| `test-case-locator` | Finds existing test cases and reports coverage stats |
|
|
166
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: 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
|
|
|
@@ -8,7 +8,7 @@ argument-hint: "[scope]"
|
|
|
8
8
|
|
|
9
9
|
Scope: $ARGUMENTS
|
|
10
10
|
|
|
11
|
-
Review changes across **Quality**, **Security**, **Dependencies** lenses with optional advisor adjudication. Valid scopes: `commit` | `staged` | `working` | hash | `A..B` | PR branch. **
|
|
11
|
+
Review changes across **Quality**, **Security**, **Dependencies** lenses with optional advisor adjudication. Valid scopes: `commit` | `staged` | `working` | hash | `A..B` | PR branch. **Empty scope defaults to feature-branch-vs-default-branch first-parent review** (default branch auto-detected; see Step 1).
|
|
12
12
|
|
|
13
13
|
**How it works**:
|
|
14
14
|
- Step 1 — resolve scope, read diff (with `-U30` context), derive flags, build semantic file map
|
|
@@ -22,31 +22,40 @@ Review changes across **Quality**, **Security**, **Dependencies** lenses with op
|
|
|
22
22
|
|
|
23
23
|
**File-orientation contract**: agents reason about *files* as coherent units. Hunks are evidence *within* a file's analysis, never the unit of analysis. The `-U30` patch (Step 1) inlines function-level context so agents rarely need extra `Read` calls.
|
|
24
24
|
|
|
25
|
-
Every Wave-2 agent prompt contains EXACTLY: (a) `Known Context:` followed by the Discovery Map verbatim, and (b) the literal string
|
|
25
|
+
Every Wave-2 agent prompt contains EXACTLY: (a) `Known Context:` followed by the Discovery Map verbatim, and (b) the literal string `.git/code-review-patch.diff` as the patch path. Nothing else from Wave-1 outputs — NOT the raw integration-scanner dump, NOT precedent-locator output, NOT Dependencies/CVE output. See "Wave-2 context isolation" in Step 3 for the failure mode when this is violated. Wave-1 agents that do not consume the Discovery Map (precedents, dependencies, CVE) get `ChangedFiles` / manifest-diff only.
|
|
26
26
|
|
|
27
27
|
## Step 1: Resolve Scope and Assemble the Diff
|
|
28
28
|
|
|
29
|
-
1. **
|
|
30
|
-
- `commit` → `OLDEST=NEWEST=HEAD`
|
|
31
|
-
- `staged` / `working` → no commits; see working-tree branch below
|
|
32
|
-
- Single hash `h` → `OLDEST=NEWEST=h`
|
|
33
|
-
- Range `A..B` → verify A is ancestor of B (`git merge-base --is-ancestor A B`; swap if reversed); `OLDEST=A`, `NEWEST=B`
|
|
34
|
-
- Commit list (`h1,h2,h3` or whitespace-separated) → find endpoints via `git rev-list --topo-order`; `OLDEST` = farthest-from-HEAD, `NEWEST` = nearest. Reject if not on a single linear ancestry (ask user to clarify).
|
|
35
|
-
- PR branch name → `OLDEST=$(git merge-base main HEAD)`, `NEWEST=HEAD` — note: `OLDEST` is already the parent-of-first-PR-commit, so skip the `BASE` computation below and use `BASE=OLDEST` directly.
|
|
29
|
+
1. **Detect default branch**: `DEFAULT_BRANCH=$(git symbolic-ref --quiet --short refs/remotes/origin/HEAD 2>/dev/null | sed 's@^origin/@@')`. Fallback: probe `main` then `master` (`git rev-parse --verify --quiet <name>`); if neither resolves, ask the user which branch is the integration target before proceeding. Use `$DEFAULT_BRANCH` wherever the parser below says `<default>`.
|
|
36
30
|
|
|
37
|
-
2. **
|
|
31
|
+
2. **Interpret the Scope line** (from the header) and identify `OLDEST` + `NEWEST` commits (user-inclusive endpoints). Each branch carries a **strategy tag** used later by Assembly and Step 6:
|
|
32
|
+
- Empty → `OLDEST=$(git merge-base "$DEFAULT_BRANCH" HEAD)`, `NEWEST=HEAD`, strategy=`first-parent` (also skips the `BASE` computation below — use `BASE=OLDEST` directly)
|
|
33
|
+
- `commit` → `OLDEST=NEWEST=HEAD`, strategy=`working-tree`
|
|
34
|
+
- `staged` / `working` → no commits; see working-tree branch below, strategy=`working-tree`
|
|
35
|
+
- Single hash `h` → `OLDEST=NEWEST=h`, strategy=`explicit-range`
|
|
36
|
+
- Range `A..B` → verify A is ancestor of B (`git merge-base --is-ancestor A B`; swap if reversed); `OLDEST=A`, `NEWEST=B`, strategy=`explicit-range`
|
|
37
|
+
- Commit list (`h1,h2,h3` or whitespace-separated) → find endpoints via `git rev-list --topo-order`; `OLDEST` = farthest-from-HEAD, `NEWEST` = nearest. Reject if not on a single linear ancestry (ask user to clarify). Strategy=`first-parent` (ancestry invariant preserves named commits under first-parent traversal).
|
|
38
|
+
- PR branch name → `OLDEST=$(git merge-base "$DEFAULT_BRANCH" HEAD)`, `NEWEST=HEAD`, strategy=`first-parent` — note: `OLDEST` is already the parent-of-first-PR-commit, so skip the `BASE` computation below and use `BASE=OLDEST` directly.
|
|
39
|
+
- Anything unrecognised (prose, branch name that fails to resolve, mixed list) → ask the user to clarify via `ask_user_question`: (A) "review current branch vs `$DEFAULT_BRANCH` (first-parent)", (B) "review uncommitted changes", (C) "restate scope". Do NOT silently guess.
|
|
40
|
+
|
|
41
|
+
2. **Compute the range once**: `BASE=$(git rev-parse "$OLDEST^")`, `TIP=$NEWEST`, `RANGE="$BASE..$TIP"`. This gives a range that INCLUDES `OLDEST`'s own changes (standard `A..B` excludes `A`). Every subsequent git command uses `$RANGE` — do NOT inline a `^` character in templates; orchestrators sometimes drop it. Also set `FP_FLAG="--first-parent"` when strategy=`first-parent`, else `FP_FLAG=""`.
|
|
38
42
|
|
|
39
43
|
3. **Assemble the UNION of changes** (not the net endpoint-diff — so reverted intermediate work stays visible). Save the patch to a tempfile once with generous context; do NOT re-run `git log --patch` to slice windows later:
|
|
40
|
-
- `git log "$RANGE" --name-only --pretty=format: | sort -u` → `ChangedFiles`
|
|
41
|
-
- `git log "$RANGE" --stat --reverse` → per-commit size summary
|
|
42
|
-
- `git log "$RANGE" --patch --reverse --no-merges -U30 > /
|
|
44
|
+
- `git log "$RANGE" $FP_FLAG --name-only --pretty=format: | sort -u` → `ChangedFiles`
|
|
45
|
+
- `git log "$RANGE" $FP_FLAG --stat --reverse` → per-commit size summary
|
|
46
|
+
- `git log "$RANGE" $FP_FLAG --patch --reverse --no-merges -U30 > .git/code-review-patch.diff` → union patches with **30 lines of surrounding context per hunk** (function-level context inline). `$FP_FLAG` is orthogonal to `--no-merges`: first-parent prunes second-parent subtrees from reachability, `--no-merges` drops the merge commit itself from the log.
|
|
43
47
|
- `git log "$RANGE" --reverse --format="%H %s%n%n%b%n---"` → commit-message context
|
|
44
|
-
- **Working-tree branch** (`staged` / `working`, no `$RANGE`): `git diff --cached --name-only` / `git diff --name-only`; `git diff --cached --stat` / `git diff --stat`; `git diff --cached -U30` / `git diff -U30`. Commit-message context is N/A.
|
|
48
|
+
- **Working-tree branch** (`staged` / `working`, no `$RANGE`): `git diff --cached --name-only` / `git diff --name-only`; `git diff --cached --stat` / `git diff --stat`; `git diff --cached -U30` / `git diff -U30`. Commit-message context is N/A. `FP_FLAG` is not applicable.
|
|
45
49
|
- **Patch-size fallback**: `-U30` produces ~2–3× the size of `-U0`. If the resulting patch exceeds ~1MB, drop to `-U10` for this run; never use `-U0` — it defeats the skill's design.
|
|
46
50
|
|
|
47
51
|
3. **Bail-out**: if `ChangedFiles` is empty, print `No changes in scope [scope]. Exiting.` and STOP. Do not write an artifact.
|
|
48
52
|
|
|
49
|
-
4. **Derive flags** (orchestrator-side, used in later steps):
|
|
53
|
+
4. **Derive scope + flags** (orchestrator-side, used in later steps):
|
|
54
|
+
- `InScopeFiles` — used by the Step 6 pre-filter. `ChangedFiles` reflects *tree-reachability* (inflated on branches that back-merged the default branch — each post-merge first-parent commit inherits the merge's tree, so `--name-only` includes every file the merge resolved); `InScopeFiles` reflects *commits' own diffs* and is what the developer actually authored. Derivation:
|
|
55
|
+
- strategy=`first-parent` (empty / PR branch / commit-list inputs) → `InScopeFiles = ⋃ git diff-tree --no-commit-id --name-only -r <h>` over `git log "$RANGE" --first-parent --no-merges --pretty=%H` (each feature commit's own file delta; back-merge sidecars drop out even when the merge is on the first-parent line). For commit-list input, iterate over the user-named hashes instead of the first-parent walk to preserve non-contiguous-list intent.
|
|
56
|
+
- strategy=`explicit-range` → `InScopeFiles = ChangedFiles` (user explicitly asked for range semantics; merges in the range are part of the intent).
|
|
57
|
+
- strategy=`working-tree` → `InScopeFiles = ChangedFiles` (no merge surface).
|
|
58
|
+
- **Invariant**: `InScopeFiles ⊆ ChangedFiles`. On back-merged feature branches, `InScopeFiles ⊊ ChangedFiles` is the primary mechanism by which sidecar findings get dropped at Step 6.
|
|
50
59
|
- `ManifestChanged` = ChangedFiles intersects any dependency manifest or lockfile (e.g. `package.json`/lockfile, `Cargo.toml`/`Cargo.lock`, `go.mod`/`go.sum`, `pyproject.toml`/`requirements*.txt`/`poetry.lock`, `Gemfile*`, `*.csproj`, `pom.xml`/`build.gradle*`, `composer.json`, …) OR a peer/optional/dev-dependency field was touched.
|
|
51
60
|
- `LockstepSelfReview` = repository root contains `scripts/sync-versions.js` AND every `packages/*/package.json` shares the same `version:` AND the diff touches `packages/*/package.json`.
|
|
52
61
|
- `HasGatingPredicate` = diff adds or modifies a **status/enum-comparison predicate** (`Status == X`, `Status is X or Y`, `X.Contains(Status)`, pattern-match on a discriminator) OR introduces a new value into an enum referenced by existing gating predicates. NOT merely the presence of `if (!x) return`.
|
|
@@ -72,7 +81,7 @@ Spawn ALL of the following in parallel at T=0 in a **single message with multipl
|
|
|
72
81
|
|
|
73
82
|
**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
83
|
|
|
75
|
-
**Agent — Peer-Mirror** (only when `len(PeerPairs) > 0`): `subagent_type:
|
|
84
|
+
**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
85
|
```
|
|
77
86
|
Peer-mirror check.
|
|
78
87
|
|
|
@@ -143,9 +152,9 @@ Peer mirrors: [peer-mirror agent output verbatim — Missing/Diverged rows only;
|
|
|
143
152
|
|
|
144
153
|
## Step 3: Dispatch Wave-2 — Quality + Security Lenses
|
|
145
154
|
|
|
146
|
-
Spawn Quality + Security in parallel using the Agent tool. Each receives the `## Discovery Map` block inline as `Known Context` above its task, and a pointer to
|
|
155
|
+
Spawn Quality + Security in parallel using the Agent tool. Each receives the `## Discovery Map` block inline as `Known Context` above its task, and a pointer to `.git/code-review-patch.diff` for the diff itself. Precedents / Dependencies / CVE are already running from Wave-1 — do NOT re-dispatch them here; the prompts below document what those Wave-1 agents received, they are not re-issued.
|
|
147
156
|
|
|
148
|
-
**Wave-2 context isolation (LOAD-BEARING — violations cause silent quality collapse)**: Each Wave-2 agent receives EXACTLY two things, nothing else: (1) the Discovery Map (digested form) and (2) the literal path string
|
|
157
|
+
**Wave-2 context isolation (LOAD-BEARING — violations cause silent quality collapse)**: Each Wave-2 agent receives EXACTLY two things, nothing else: (1) the Discovery Map (digested form) and (2) the literal path string `.git/code-review-patch.diff`.
|
|
149
158
|
|
|
150
159
|
**DO NOT paste into Wave-2 prompts**, under any circumstance, even if the orchestrator has already received them:
|
|
151
160
|
- raw integration-scanner output (the Discovery Map already summarises its auth/ref/wiring findings)
|
|
@@ -160,9 +169,9 @@ Spawn Quality + Security in parallel using the Agent tool. Each receives the `##
|
|
|
160
169
|
|
|
161
170
|
**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
171
|
|
|
163
|
-
**Quality lens** (`
|
|
172
|
+
**Quality lens** (`diff-auditor`) — **file-oriented**:
|
|
164
173
|
```
|
|
165
|
-
Analyse changes file by file. For each file in ChangedFiles, read its diff region in
|
|
174
|
+
Analyse changes file by file. For each file in ChangedFiles, read its diff region in `.git/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
175
|
|
|
167
176
|
**File order strategy**: prioritise by role tag — `[boundary]` files first (security-sensitive), then `[persistence]` (durable-state surfaces), then `[hub]` (blast-radius amplifiers), then `[code]`, then `[config]`, then `[test]` last. Within the same tag, prioritise files with the largest diffs.
|
|
168
177
|
|
|
@@ -187,9 +196,9 @@ Spawn Quality + Security in parallel using the Agent tool. Each receives the `##
|
|
|
187
196
|
**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
197
|
```
|
|
189
198
|
|
|
190
|
-
**Security lens** (`
|
|
199
|
+
**Security lens** (`diff-auditor`) — **file-oriented**:
|
|
191
200
|
```
|
|
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
|
|
201
|
+
Analyse each changed file as a whole, looking for sinks in the classes below. For each file, grep the file's diff region in `.git/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
202
|
|
|
194
203
|
**File order strategy**: `[boundary]` files first (direct source→sink exposure); then `[persistence]` (query injection, unsafe deserialization); then `[code]` (command exec, SSRF, explicit-trust rendering); then `[hub]` / `[config]`; skip `[test]` unless a test helper touches a sink.
|
|
195
204
|
|
|
@@ -244,17 +253,17 @@ Spawn Quality + Security in parallel using the Agent tool. Each receives the `##
|
|
|
244
253
|
|
|
245
254
|
## Step 4: Dispatch Wave-3 — Predicate-Trace + Interaction Sweep + Gap-Finder
|
|
246
255
|
|
|
247
|
-
Once Wave-2 (Quality + Security) completes, dispatch
|
|
256
|
+
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
257
|
|
|
249
258
|
- **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
|
|
259
|
+
- **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
260
|
- 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
261
|
|
|
253
262
|
### Step 4a: Predicate-Trace
|
|
254
263
|
|
|
255
264
|
**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
265
|
|
|
257
|
-
Otherwise spawn ONE `codebase-analyzer` in parallel with 4b
|
|
266
|
+
Otherwise spawn ONE `codebase-analyzer` in parallel with 4b:
|
|
258
267
|
```
|
|
259
268
|
Coherence rows (Quality — Predicate-set coherence): [paste verbatim]
|
|
260
269
|
Gating predicates in diff: [`file:line` list]
|
|
@@ -268,13 +277,13 @@ Otherwise spawn ONE `codebase-analyzer` in parallel with 4b and 4c:
|
|
|
268
277
|
Evidence only. Citation contract applies.
|
|
269
278
|
```
|
|
270
279
|
|
|
271
|
-
Do NOT wait — 4b (Interaction Sweep)
|
|
280
|
+
Do NOT wait — 4b (Interaction Sweep) dispatches in the same message as 4a; 4c runs inline in the orchestrator.
|
|
272
281
|
|
|
273
282
|
### Step 4b: Interaction Sweep
|
|
274
283
|
|
|
275
284
|
**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
285
|
|
|
277
|
-
Otherwise spawn ONE `codebase-analyzer` in parallel with 4a
|
|
286
|
+
Otherwise spawn ONE `codebase-analyzer` in parallel with 4a:
|
|
278
287
|
```
|
|
279
288
|
Quality Evidence: [verbatim]
|
|
280
289
|
Security Evidence: [verbatim]
|
|
@@ -299,36 +308,21 @@ Otherwise spawn ONE `codebase-analyzer` in parallel with 4a and 4c:
|
|
|
299
308
|
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
309
|
```
|
|
301
310
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
### Step 4c: Gap-Finder
|
|
305
|
-
|
|
306
|
-
**Gate**: SKIP this sub-step (do not dispatch 4c) when `len(ChangedFiles) < 2`. Tiny diffs cannot structurally have coverage gaps.
|
|
311
|
+
### Step 4c: Gap-Finder (orchestrator-side coverage arithmetic)
|
|
307
312
|
|
|
308
|
-
|
|
309
|
-
```
|
|
310
|
-
All lens findings so far:
|
|
311
|
-
Quality Evidence: [verbatim]
|
|
312
|
-
Security Evidence: [verbatim | "not applicable"]
|
|
313
|
+
**Gate**: SKIP when `len(ChangedFiles) < 2`. Tiny diffs cannot structurally have coverage gaps.
|
|
313
314
|
|
|
314
|
-
|
|
315
|
-
Discovery Map: [verbatim]
|
|
315
|
+
No agent dispatch. Compute inline while 4a / 4b run:
|
|
316
316
|
|
|
317
|
-
|
|
317
|
+
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.
|
|
318
|
+
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.
|
|
319
|
+
3. **Emit gap findings** — walk uncovered in-scope files in role-tag priority `[boundary]` → `[persistence]` → `[hub]` → `[code]`. For each, open its diff region in `.git/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
320
|
|
|
319
|
-
|
|
321
|
+
`G<ordinal> — file:line — \`<verbatim line>\` — [role-tag] — <risk class in 3-6 words>`
|
|
320
322
|
|
|
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)
|
|
323
|
+
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
324
|
|
|
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.
|
|
325
|
+
**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
326
|
|
|
333
327
|
## Step 5: Reconcile Findings
|
|
334
328
|
|
|
@@ -371,9 +365,9 @@ Otherwise spawn ONE `codebase-analyzer` in parallel with 4a and 4b. The prompt i
|
|
|
371
365
|
|
|
372
366
|
## Step 6: Verify Findings
|
|
373
367
|
|
|
374
|
-
Before writing the artifact, spawn ONE `
|
|
368
|
+
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
369
|
|
|
376
|
-
**Dispatch** after Step 5's reconciled severity map is final, before Step 7 writes anything:
|
|
370
|
+
**Dispatch** after Step 5's reconciled severity map is final, before Step 7 writes anything. First apply the **InScopeFiles pre-filter**: drop any finding whose cited `file` ∉ `InScopeFiles` (orchestrator-side set arithmetic, matches Step 4c's idiom). On `first-parent` strategies `InScopeFiles ⊊ ChangedFiles` is expected — this is where back-merge sidecar findings get dropped. Record the dropped count in `## Reconciliation Notes` so the omission is auditable. Then dispatch the filtered map:
|
|
377
371
|
|
|
378
372
|
```
|
|
379
373
|
Verify each finding below against the actual repository state. You have Read access to the whole tree.
|
|
@@ -401,7 +395,9 @@ Before writing the artifact, spawn ONE `codebase-analyzer` whose sole job is to
|
|
|
401
395
|
Citation contract applies to every justification. No recommendations. No new findings.
|
|
402
396
|
```
|
|
403
397
|
|
|
404
|
-
**
|
|
398
|
+
**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.
|
|
399
|
+
|
|
400
|
+
**Apply the tags** (on the corrected tag):
|
|
405
401
|
- **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
402
|
- **Weakened** findings — demote one severity tier (🔴→🟡, 🟡→🔵, 🔵→💭). Rewrite the finding's evidence line to reflect the narrower claim.
|
|
407
403
|
- **Verified** findings — carry through unchanged to Step 7.
|
|
@@ -471,7 +467,7 @@ Ask follow-ups.
|
|
|
471
467
|
- **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
468
|
- **Load-bearing ordering**:
|
|
473
469
|
- 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)
|
|
470
|
+
- 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
471
|
- 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
472
|
- **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
473
|
- **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 +475,19 @@ Ask follow-ups.
|
|
|
479
475
|
- ALWAYS probe advisor availability before calling it (strip-when-unconfigured at `packages/rpiv-advisor/advisor.ts:463-472`).
|
|
480
476
|
- NEVER call `advisor()` from a sub-agent (branch invisible to advisor).
|
|
481
477
|
- NEVER parse advisor prose — paste verbatim as a blockquote at the top of `## Recommendation`.
|
|
482
|
-
- ALWAYS wait for 4a / 4b
|
|
478
|
+
- 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
479
|
- 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
480
|
- PRESERVE severity emoji/naming and frontmatter keys verbatim — `thoughts-locator` / `thoughts-analyzer` grep these.
|
|
485
|
-
-
|
|
481
|
+
- 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`.
|
|
482
|
+
- **Scope strategy is load-bearing at both ends**: Step 1 sets `strategy` and `FP_FLAG`; Step 6 pre-filters the reconciled severity map against `InScopeFiles` before `claim-verifier` dispatch. `--first-parent` is orthogonal to `--no-merges` / `-U30` — additive, not a replacement. Agent contracts (`claim-verifier.md:11-30` in particular) stay scope-blind by design; orchestrator owns scope.
|
|
486
483
|
- **Agent roles**:
|
|
487
484
|
- `integration-scanner` (Wave-1) — inbound/outbound refs, auth-boundary crossings.
|
|
488
485
|
- `precedent-locator` (Wave-1) — git history + thoughts/.
|
|
489
486
|
- `codebase-analyzer` ×1 (Wave-1, `ManifestChanged`) — dependencies parse.
|
|
490
487
|
- `web-search-researcher` (Wave-1, `ManifestChanged`) — CVE/advisory lookups with LINKS.
|
|
491
|
-
- `
|
|
492
|
-
- `
|
|
488
|
+
- `peer-comparator` ×1 (Wave-1, gated on `len(PeerPairs) > 0`) — peer-mirror check; tags Mirrored/Missing/Diverged/Intentionally-absent.
|
|
489
|
+
- `diff-auditor` ×2 (Wave-2) — Quality, Security.
|
|
493
490
|
- `codebase-analyzer` ×1 (Step 4a, gated) — predicate-trace.
|
|
494
491
|
- `codebase-analyzer` ×1 (Step 4b, gated) — interaction sweep.
|
|
495
|
-
-
|
|
496
|
-
- `
|
|
492
|
+
- *(Step 4c, gated)* — gap-finder runs inline in the orchestrator (set arithmetic over coverage map; no agent).
|
|
493
|
+
- `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).
|
|
@@ -8,6 +8,8 @@ branch: [Branch]
|
|
|
8
8
|
commit: [Short hash]
|
|
9
9
|
review_type: [commit | pr | staged | working]
|
|
10
10
|
scope: "[What was reviewed]"
|
|
11
|
+
scope_strategy: [first-parent | explicit-range | working-tree]
|
|
12
|
+
in_scope_files_count: [N]
|
|
11
13
|
status: [approved | needs_changes | requesting_changes]
|
|
12
14
|
severity: { critical: [C], important: [I], suggestion: [S] }
|
|
13
15
|
verification: { verified: [V], weakened: [W], falsified: [F] }
|