specpipe 1.0.1 → 1.0.2
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 +111 -311
- package/package.json +2 -1
- package/src/cli.js +16 -6
- package/src/commands/diff.js +1 -1
- package/src/commands/init-agents.js +40 -20
- package/src/commands/init-global.js +88 -33
- package/src/commands/init-interactive.js +71 -0
- package/src/commands/init.js +61 -22
- package/src/commands/remove.js +159 -49
- package/src/commands/upgrade.js +21 -56
- package/src/lib/agent-guards.js +34 -78
- package/src/lib/agent-install.js +38 -25
- package/src/lib/agents.js +53 -11
- package/src/lib/claude-global.js +50 -77
- package/src/lib/hooks.js +203 -0
- package/src/lib/installer.js +73 -61
- package/src/lib/reconcile.js +13 -8
- package/templates/{.claude/hooks → hooks}/file-guard.js +26 -21
- package/templates/hooks/specpipe-read-guard.sh +94 -21
- package/templates/hooks/specpipe-shell-guard.sh +121 -29
- package/templates/rules/specpipe-rules.md +77 -0
- package/templates/skills/sp-build/SKILL.md +101 -1
- package/templates/skills/sp-build-behavior-matrix/SKILL.md +876 -0
- package/templates/skills/sp-challenge/SKILL.md +34 -0
- package/templates/skills/sp-challenge-behavior-matrix/SKILL.md +289 -0
- package/templates/skills/sp-explore/SKILL.md +132 -0
- package/templates/skills/sp-explore-behavior-matrix/SKILL.md +862 -0
- package/templates/skills/sp-fix/SKILL.md +73 -1
- package/templates/skills/sp-fix-behavior-matrix/SKILL.md +338 -0
- package/templates/skills/sp-investigate/SKILL.md +70 -0
- package/templates/skills/sp-investigate-behavior-matrix/SKILL.md +718 -0
- package/templates/skills/sp-plan/SKILL.md +90 -0
- package/templates/skills/sp-plan-behavior-matrix/SKILL.md +1037 -0
- package/templates/skills/sp-review/SKILL.md +29 -3
- package/templates/skills/sp-review-behavior-matrix/SKILL.md +294 -0
- package/templates/.claude/CLAUDE.md +0 -79
- package/templates/.claude/hooks/path-guard.sh +0 -118
- package/templates/.claude/hooks/self-review.sh +0 -27
- package/templates/.claude/hooks/sensitive-guard.sh +0 -227
- package/templates/.claude/settings.json +0 -68
- package/templates/docs/WORKFLOW.md +0 -325
- package/templates/docs/specs/.gitkeep +0 -0
- package/templates/rules/specpipe-guards.md +0 -40
- package/templates/scripts/test-hooks.sh +0 -66
- /package/templates/{.claude/hooks → hooks}/comment-guard.js +0 -0
- /package/templates/{.claude/hooks → hooks}/glob-guard.js +0 -0
|
@@ -33,9 +33,11 @@ Before Phase 0:
|
|
|
33
33
|
git log --oneline "$BASE"...HEAD
|
|
34
34
|
```
|
|
35
35
|
2. Check for spec in `docs/specs/<feature>/<feature>.md` — review against INTENT.
|
|
36
|
-
3.
|
|
37
|
-
4.
|
|
38
|
-
5.
|
|
36
|
+
3. If the spec contains `## Behavior Matrix`, treat each `BM.AS-NNN.<surface>` row as review intent. Keep the matrix open while reading the diff.
|
|
37
|
+
4. Use the invariant registry README/schema as base knowledge; README examples are not runtime entries. Then read project-local invariant entries if present: `docs/invariants/INV-*.md`. If none exist, continue and note "No invariant registry found" internally.
|
|
38
|
+
5. Read the diff: `git diff "$BASE"...HEAD`
|
|
39
|
+
6. **Expand blast radius.** **If GA available (per Phase 0a):** run `ga_impact(diff=<full diff>)` (or `changed_files=[...]`) to get impacted files, affected tests, affected routes/configs, and a 4-dim risk score in one call — this is the flagship review tool, prefer it over any chain of grep + manual reading. Cross-check with `ga_architecture` for module/layer membership (auth, payment, core) and `ga_risk(changed_files=[...])` for a refactor-safety gate. **If GA unavailable:** grep for each changed function/type name across the rest of the tree to find affected files; identify sensitive paths (`auth/`, `payment/`, `core/`) by directory.
|
|
40
|
+
7. **What already exists:** List any code/flows that already partially solve the problem in this diff. Flag if the diff rebuilds something that already exists.
|
|
39
41
|
|
|
40
42
|
If `$ARGUMENTS` provided → scope to those files only.
|
|
41
43
|
If diff > 500 lines → review file-by-file, prioritize by smart focus below.
|
|
@@ -55,6 +57,8 @@ Auto-detect primary focus from diff content:
|
|
|
55
57
|
| Test files only | Test quality (skip security deep-dive) |
|
|
56
58
|
| Docs/comments only | Accuracy only (minimal review) |
|
|
57
59
|
| Payment, billing, transaction | Correctness + idempotency |
|
|
60
|
+
| Spec has `## Behavior Matrix`, or diff contains state/status/role/viewer/surface/read-model/feed/calendar/email/list/detail/worklist/dashboard | Lifecycle + parity + cascade |
|
|
61
|
+
| Diff touches code named in invariant logs | Regression invariants for that component |
|
|
58
62
|
|
|
59
63
|
Spend 60% of analysis on the primary focus. Cover all categories, but proportionally.
|
|
60
64
|
|
|
@@ -95,6 +99,28 @@ Spend 60% of analysis on the primary focus. Cover all categories, but proportion
|
|
|
95
99
|
- Test referencing an AS-NNN that no longer exists in the spec → "Test references removed AS-NNN"
|
|
96
100
|
Keep this lightweight — match on AS-NNN identifiers and story name substrings, not semantic analysis.
|
|
97
101
|
|
|
102
|
+
### Behavior Matrix & Invariants (High)
|
|
103
|
+
|
|
104
|
+
Use this section when the spec has `## Behavior Matrix`, `## Sibling Surface Map`, or project-local invariant logs match the diff.
|
|
105
|
+
|
|
106
|
+
- **Cell-to-diff trace:** For each changed state transition, viewer rule, read surface, notification, queue, dashboard count, feed, calendar, or API projection, identify the corresponding `BM.AS-NNN.<surface>` row. If code changes behavior for a matrix cell but tests do not reference that AS ID or `BM.AS-NNN`, flag High.
|
|
107
|
+
- **Surface parity:** If the diff updates one read surface for a state/viewer change, check matrix siblings for list/detail/worklist/dashboard/feed/API/email/calendar parity. Flag missing sibling updates unless the matrix marks them `N/A` with a concrete reason.
|
|
108
|
+
- **Sibling candidate disposition:** If the spec has `## Sibling Surface Map`, every high/medium candidate must be `cover`, `GAP-NNN`, or `ignore(reason)`. Flag missing dispositions. If the diff changes a confirmed sibling surface but omits sibling tests/updates for the other confirmed surfaces, flag High unless a GAP/N/A covers it.
|
|
109
|
+
- **Discovery drift:** If the diff introduces or modifies an entry-point whose name/evidence matches the operation (`create_from_*`, `*_from_*`, `send_*invite*`, `*_outcome*`, `reschedule*`, `book_next*`, etc.) but it is absent from the Sibling Surface Map and invariant registry, flag "Invariant candidate missing" as Medium/High depending on risk.
|
|
110
|
+
- **Suspicious N/A/GAP:** If changed code exercises a matrix row marked `N/A` or `GAP`, flag the spec/code mismatch. `GAP` is not a test obligation, but it is a review concern when the diff implements or depends on that behavior.
|
|
111
|
+
- **Viewer-relative behavior:** Confirm visibility, labels, allowed actions, recipients, and queue membership are derived from `state/status × viewer/role`, not only from owner/assignee shortcuts.
|
|
112
|
+
- **Cascade propagation:** State transitions must update derived queues, counts, feeds, read models, notifications, calendars, and APIs named by the matrix. Flag partial propagation and stale read-path risks.
|
|
113
|
+
- **Delete/orphan/incomplete/out-of-order:** For lifecycle changes, check delete/cancel/reschedule/reassign paths for orphaned rows, stale external events, incomplete rollback, and out-of-order async delivery.
|
|
114
|
+
- **Timing/source parity:** When matrix rows imply sync/async/external-down timing, confirm tests assert the correct timing tier and user-visible source of truth.
|
|
115
|
+
- **No-vacuous boundary tests:** If a test covers `BM.AS-NNN.<surface>` but mocks the exact boundary that surface depends on (API projection, calendar provider, email provider, read-model query, queue feed), flag it. Mock outside the boundary, not the behavior being claimed.
|
|
116
|
+
- **Invariant registry check:** For each project-local `docs/invariants/INV-*.md` entry whose `component_keys`, `sibling_set`, `shared_anchor`, or keywords match the diff, verify code and tests preserve it. Status handling:
|
|
117
|
+
- `enforced` → hard review gate: if the diff touches one sibling/component in the invariant but does not update or run the `test_ref` / equivalent regression, flag High.
|
|
118
|
+
- `confirmed` → High risk advisory: flag missing sibling updates/tests unless the spec intentionally changes the invariant.
|
|
119
|
+
- `candidate` → Medium/High depending on evidence: flag as "Invariant candidate needs confirmation" if the diff repeats the class.
|
|
120
|
+
- `retired` → ignore unless the diff revives the retired component.
|
|
121
|
+
A repeated class such as carry-forward, viewer-relative labels, invite-on-reschedule, orphan cleanup, or stale dashboard count is High unless intentionally changed in the spec.
|
|
122
|
+
- **Review fix direction:** Suggested fixes should usually update the spec/test/code triangle: add or correct the matrix cell, add a `BM.AS-NNN` regression test, then fix code. Do not suggest "add generic coverage" when a precise cell is available.
|
|
123
|
+
|
|
98
124
|
### Code Quality (Medium)
|
|
99
125
|
- Dead code: removed functions still imported elsewhere?
|
|
100
126
|
- Obvious duplication: copy-pasted blocks that should be shared?
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: |
|
|
3
|
+
Pre-merge code review — security, correctness, spec alignment. Reviews diff
|
|
4
|
+
against the base branch with smart focus by blast radius.
|
|
5
|
+
Use when asked to "review this PR", "review code", "review trước khi merge",
|
|
6
|
+
"kiểm tra code", "check my diff", "pre-merge review", or "review my changes".
|
|
7
|
+
Proactively suggest before /sp-commit or when the user is about to merge,
|
|
8
|
+
especially after /sp-build produces a non-trivial diff.
|
|
9
|
+
Catches: SQL safety issues, security gaps, spec drift, regressions in
|
|
10
|
+
modified-not-added lines, and changes to sensitive layers (auth, payment, core).
|
|
11
|
+
allowed-tools: Read, Bash, Glob, Grep, AskUserQuestion, mcp__graphatlas__*
|
|
12
|
+
---
|
|
13
|
+
Pre-merge code review — security, correctness, spec alignment.
|
|
14
|
+
|
|
15
|
+
## Phase 0a — Graphatlas probe (run once, silently)
|
|
16
|
+
|
|
17
|
+
Before Phase 0:
|
|
18
|
+
|
|
19
|
+
1. Call `mcp__graphatlas__ga_architecture` with `max_modules: 1`.
|
|
20
|
+
2. Interpret:
|
|
21
|
+
- Returns `modules` → **GA available.** Use `ga_impact`, `ga_risk`, `ga_architecture` for blast-radius and layer checks below. Manual grep is fallback.
|
|
22
|
+
- Error `STALE_INDEX` → call `mcp__graphatlas__ga_reindex` (mode `"full"`), retry once, then treat as available. (Reviewing the diff against a stale index gives wrong impact — reindex matters here.)
|
|
23
|
+
- Tool not found / connection error / any other failure → **GA unavailable.** Skip `ga_*` steps and review the diff manually. Do not re-probe.
|
|
24
|
+
3. Carry the outcome through Phase 0 - 4.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Phase 0: Understand Intent
|
|
29
|
+
|
|
30
|
+
1. Read commit messages:
|
|
31
|
+
```
|
|
32
|
+
BASE=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's|refs/remotes/origin/||') || BASE="main"
|
|
33
|
+
git log --oneline "$BASE"...HEAD
|
|
34
|
+
```
|
|
35
|
+
2. Check for spec in `docs/specs/<feature>/<feature>.md` — review against INTENT.
|
|
36
|
+
3. If the spec contains `## Behavior Matrix`, treat each `BM.AS-NNN.<surface>` row as review intent. Keep the matrix open while reading the diff.
|
|
37
|
+
4. Use the invariant registry README/schema as base knowledge; README examples are not runtime entries. Then read project-local invariant entries if present: `docs/invariants/INV-*.md`. If none exist, continue and note "No invariant registry found" internally.
|
|
38
|
+
5. Read the diff: `git diff "$BASE"...HEAD`
|
|
39
|
+
6. **Expand blast radius.** **If GA available (per Phase 0a):** run `ga_impact(diff=<full diff>)` (or `changed_files=[...]`) to get impacted files, affected tests, affected routes/configs, and a 4-dim risk score in one call — this is the flagship review tool, prefer it over any chain of grep + manual reading. Cross-check with `ga_architecture` for module/layer membership (auth, payment, core) and `ga_risk(changed_files=[...])` for a refactor-safety gate. **If GA unavailable:** grep for each changed function/type name across the rest of the tree to find affected files; identify sensitive paths (`auth/`, `payment/`, `core/`) by directory.
|
|
40
|
+
7. **What already exists:** List any code/flows that already partially solve the problem in this diff. Flag if the diff rebuilds something that already exists.
|
|
41
|
+
|
|
42
|
+
If `$ARGUMENTS` provided → scope to those files only.
|
|
43
|
+
If diff > 500 lines → review file-by-file, prioritize by smart focus below.
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## Phase 1: Smart Focus
|
|
48
|
+
|
|
49
|
+
Auto-detect primary focus from diff content:
|
|
50
|
+
|
|
51
|
+
| Diff contains | Focus heavily on |
|
|
52
|
+
|--------------|-----------------|
|
|
53
|
+
| auth, login, token, session, password, JWT | Security — full depth |
|
|
54
|
+
| SQL, query, database, migration | Injection + data integrity |
|
|
55
|
+
| API, endpoint, route, controller, handler | Input validation + error handling |
|
|
56
|
+
| .env, config, secret, key, credential | Secret exposure |
|
|
57
|
+
| Test files only | Test quality (skip security deep-dive) |
|
|
58
|
+
| Docs/comments only | Accuracy only (minimal review) |
|
|
59
|
+
| Payment, billing, transaction | Correctness + idempotency |
|
|
60
|
+
| Spec has `## Behavior Matrix`, or diff contains state/status/role/viewer/surface/read-model/feed/calendar/email/list/detail/worklist/dashboard | Lifecycle + parity + cascade |
|
|
61
|
+
| Diff touches code named in invariant logs | Regression invariants for that component |
|
|
62
|
+
|
|
63
|
+
Spend 60% of analysis on the primary focus. Cover all categories, but proportionally.
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Phase 2: Checklist
|
|
68
|
+
|
|
69
|
+
### Security (Critical)
|
|
70
|
+
- **Injection:** Search diff for string concatenation in SQL/shell/HTML. Look for `${var}` in queries, `.innerHTML`, template literals in SQL. Flag any user input reaching a query without parameterization.
|
|
71
|
+
- **Auth/Authz:** New endpoint → has auth middleware? Can user A access user B's data? ID in URL without ownership check?
|
|
72
|
+
- **Secrets:** Hardcoded strings matching `sk-`, `ghp_`, `Bearer `, long base64. New env vars committed?
|
|
73
|
+
- **Error exposure:** Catch blocks sending raw errors to users? Stack traces, file paths, DB schemas in responses?
|
|
74
|
+
- **Dependencies:** New packages — maintained? >1000 weekly downloads? Known CVEs?
|
|
75
|
+
|
|
76
|
+
### Correctness (High)
|
|
77
|
+
- **Logic vs intent:** Does the code do what commits/spec claim? "Add validation" but code just logs?
|
|
78
|
+
- **Edge cases:** null, empty, 0, negative, MAX_INT, unicode, very long strings — handled?
|
|
79
|
+
- **Error handling:** For each try/catch — error logged with context? User shown safe message? Resources cleaned in finally?
|
|
80
|
+
- **Concurrency:** Shared state without locks? Read-then-write without atomicity? Non-atomic DB updates?
|
|
81
|
+
- **Null safety:** Optionals used without guards? `object!.property` without nil check?
|
|
82
|
+
|
|
83
|
+
### API/Backend (High)
|
|
84
|
+
|
|
85
|
+
- **Unvalidated input** — request body/params used without schema validation
|
|
86
|
+
- **Missing rate limiting** — public endpoints without throttling
|
|
87
|
+
- **Missing timeouts** — external HTTP calls without timeout configuration
|
|
88
|
+
- **Missing CORS configuration** — APIs accessible from unintended origins
|
|
89
|
+
- **Error message leakage** — stack traces, file paths, DB schemas in responses
|
|
90
|
+
|
|
91
|
+
### Spec-Test Alignment (Medium)
|
|
92
|
+
- Source changed but no spec update in `docs/specs/<feature>/`? → flag
|
|
93
|
+
- Source changed but no test update? → flag
|
|
94
|
+
- Spec changed but acceptance scenarios or tests not updated? → flag
|
|
95
|
+
- Code removed but dead tests remain? → flag
|
|
96
|
+
- Spec contains vague requirements without metrics ("fast", "secure", "easy", "scalable")? → flag with suggestion to add SC-NNN with concrete numbers
|
|
97
|
+
- **AS-to-test name check:** Read the spec's `## Stories` section. For each AS-NNN, check if a test file contains a test named or described with that AS ID or its short description. Flag:
|
|
98
|
+
- AS in spec with no matching test → "AS-NNN: \<description\> has no corresponding test"
|
|
99
|
+
- Test referencing an AS-NNN that no longer exists in the spec → "Test references removed AS-NNN"
|
|
100
|
+
Keep this lightweight — match on AS-NNN identifiers and story name substrings, not semantic analysis.
|
|
101
|
+
|
|
102
|
+
### Behavior Matrix & Invariants (High)
|
|
103
|
+
|
|
104
|
+
Use this section when the spec has `## Behavior Matrix`, `## Sibling Surface Map`, or project-local invariant logs match the diff.
|
|
105
|
+
|
|
106
|
+
- **Cell-to-diff trace:** For each changed state transition, viewer rule, read surface, notification, queue, dashboard count, feed, calendar, or API projection, identify the corresponding `BM.AS-NNN.<surface>` row. If code changes behavior for a matrix cell but tests do not reference that AS ID or `BM.AS-NNN`, flag High.
|
|
107
|
+
- **Surface parity:** If the diff updates one read surface for a state/viewer change, check matrix siblings for list/detail/worklist/dashboard/feed/API/email/calendar parity. Flag missing sibling updates unless the matrix marks them `N/A` with a concrete reason.
|
|
108
|
+
- **Sibling candidate disposition:** If the spec has `## Sibling Surface Map`, every high/medium candidate must be `cover`, `GAP-NNN`, or `ignore(reason)`. Flag missing dispositions. If the diff changes a confirmed sibling surface but omits sibling tests/updates for the other confirmed surfaces, flag High unless a GAP/N/A covers it.
|
|
109
|
+
- **Discovery drift:** If the diff introduces or modifies an entry-point whose name/evidence matches the operation (`create_from_*`, `*_from_*`, `send_*invite*`, `*_outcome*`, `reschedule*`, `book_next*`, etc.) but it is absent from the Sibling Surface Map and invariant registry, flag "Invariant candidate missing" as Medium/High depending on risk.
|
|
110
|
+
- **Suspicious N/A/GAP:** If changed code exercises a matrix row marked `N/A` or `GAP`, flag the spec/code mismatch. `GAP` is not a test obligation, but it is a review concern when the diff implements or depends on that behavior.
|
|
111
|
+
- **Viewer-relative behavior:** Confirm visibility, labels, allowed actions, recipients, and queue membership are derived from `state/status × viewer/role`, not only from owner/assignee shortcuts.
|
|
112
|
+
- **Cascade propagation:** State transitions must update derived queues, counts, feeds, read models, notifications, calendars, and APIs named by the matrix. Flag partial propagation and stale read-path risks.
|
|
113
|
+
- **Delete/orphan/incomplete/out-of-order:** For lifecycle changes, check delete/cancel/reschedule/reassign paths for orphaned rows, stale external events, incomplete rollback, and out-of-order async delivery.
|
|
114
|
+
- **Timing/source parity:** When matrix rows imply sync/async/external-down timing, confirm tests assert the correct timing tier and user-visible source of truth.
|
|
115
|
+
- **No-vacuous boundary tests:** If a test covers `BM.AS-NNN.<surface>` but mocks the exact boundary that surface depends on (API projection, calendar provider, email provider, read-model query, queue feed), flag it. Mock outside the boundary, not the behavior being claimed.
|
|
116
|
+
- **Invariant registry check:** For each project-local `docs/invariants/INV-*.md` entry whose `component_keys`, `sibling_set`, `shared_anchor`, or keywords match the diff, verify code and tests preserve it. Status handling:
|
|
117
|
+
- `enforced` → hard review gate: if the diff touches one sibling/component in the invariant but does not update or run the `test_ref` / equivalent regression, flag High.
|
|
118
|
+
- `confirmed` → High risk advisory: flag missing sibling updates/tests unless the spec intentionally changes the invariant.
|
|
119
|
+
- `candidate` → Medium/High depending on evidence: flag as "Invariant candidate needs confirmation" if the diff repeats the class.
|
|
120
|
+
- `retired` → ignore unless the diff revives the retired component.
|
|
121
|
+
A repeated class such as carry-forward, viewer-relative labels, invite-on-reschedule, orphan cleanup, or stale dashboard count is High unless intentionally changed in the spec.
|
|
122
|
+
- **Review fix direction:** Suggested fixes should usually update the spec/test/code triangle: add or correct the matrix cell, add a `BM.AS-NNN` regression test, then fix code. Do not suggest "add generic coverage" when a precise cell is available.
|
|
123
|
+
|
|
124
|
+
### Code Quality (Medium)
|
|
125
|
+
- Dead code: removed functions still imported elsewhere?
|
|
126
|
+
- Obvious duplication: copy-pasted blocks that should be shared?
|
|
127
|
+
- Naming: consistent with codebase? Descriptive?
|
|
128
|
+
- Complexity: functions > 40 lines or > 3 nesting levels?
|
|
129
|
+
- **Diagram maintenance:** Diff touches code with ASCII diagrams in nearby comments? Check if those diagrams are still accurate. Stale diagrams are worse than no diagrams — they actively mislead. Flag even if outside immediate scope.
|
|
130
|
+
|
|
131
|
+
### Performance (Low)
|
|
132
|
+
- Flag N+1 queries, unbounded collections, redundant computation in loops.
|
|
133
|
+
|
|
134
|
+
### When Reviewing AI-Generated Code
|
|
135
|
+
|
|
136
|
+
Prioritize these concerns above standard checklist:
|
|
137
|
+
- **Behavioral regressions** — does changed code break edge cases the AI didn't consider?
|
|
138
|
+
- **Trust boundaries** — does the AI code implicitly trust external input it shouldn't?
|
|
139
|
+
- **Architecture drift** — does it introduce hidden coupling or deviate from existing patterns?
|
|
140
|
+
- **Model cost escalation** — flag workflows that escalate to higher-cost models without clear reasoning; recommend lower-cost tiers for deterministic operations.
|
|
141
|
+
|
|
142
|
+
### Failure Mode Grid
|
|
143
|
+
For each new codepath in the diff, evaluate 3 dimensions:
|
|
144
|
+
|
|
145
|
+
| Codepath | Test covers it? | Error handling? | User sees clear error? |
|
|
146
|
+
|----------|----------------|-----------------|----------------------|
|
|
147
|
+
| (path) | ✓/✗ | ✓/✗ | clear / silent |
|
|
148
|
+
|
|
149
|
+
**Critical gap** = all 3 are ✗ → flag as High severity, non-optional.
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## Confidence Calibration
|
|
154
|
+
|
|
155
|
+
Every finding MUST include a confidence score:
|
|
156
|
+
|
|
157
|
+
| Score | Meaning | Display rule |
|
|
158
|
+
|-------|---------|-------------|
|
|
159
|
+
| 9–10 | Verified by reading code directly. Concrete bug demonstrated. | Show normally |
|
|
160
|
+
| 7–8 | High-confidence pattern match. Very likely correct. | Show normally |
|
|
161
|
+
| 5–6 | Possible false positive. | Show with caveat: "verify this" |
|
|
162
|
+
| 3–4 | Low confidence. | Appendix only |
|
|
163
|
+
| 1–2 | Speculation. | Only report if severity Critical |
|
|
164
|
+
|
|
165
|
+
**Finding format:** `**[C-1] (confidence: 9/10) file.ts:42 — description**`
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## Phase 3: TL;DR Output
|
|
170
|
+
|
|
171
|
+
Print ONLY this block to terminal — concise, no full finding bodies yet. Keep all finding detail internal for Phase 5.
|
|
172
|
+
|
|
173
|
+
```
|
|
174
|
+
## Code Review: <branch>
|
|
175
|
+
Scope: X files, +Y/-Z lines | Focus: <detected> | Verdict: APPROVE | REQUEST CHANGES | NEEDS DISCUSSION
|
|
176
|
+
Counts: N Critical · N High · N Medium · N Low (total: N)
|
|
177
|
+
|
|
178
|
+
Top blockers (Critical + High only, one-liner each — cap 5):
|
|
179
|
+
- [C-1] file.ts:42 — SQL injection (conf 9/10)
|
|
180
|
+
- [H-1] api.ts:15 — empty catch swallows DB errors (conf 8/10)
|
|
181
|
+
|
|
182
|
+
Positive: <1 line — reinforce one good pattern from the diff>
|
|
183
|
+
Not in scope: <1 line, or "None identified.">
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
If total findings = 0 → print TL;DR with "No findings." and STOP. Skip Phase 4–6.
|
|
187
|
+
|
|
188
|
+
After printing TL;DR, append one line:
|
|
189
|
+
> 💡 Want a second opinion? Run `/sp-voices` on this diff for a multi-LLM cross-check before triaging — especially useful for security/payment changes or when most findings sit at confidence 5–7.
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
## Phase 4: Bulk triage
|
|
194
|
+
|
|
195
|
+
Use `AskUserQuestion`. Recommendation logic for the question text:
|
|
196
|
+
- Any Critical or High present → recommend **A (Review each)**
|
|
197
|
+
- Only Medium/Low, majority confidence ≥7 → recommend **B (Accept all)**
|
|
198
|
+
- Majority confidence ≤6 → recommend **C (Reject all)**
|
|
199
|
+
|
|
200
|
+
Append `(Recommended)` to the matching option.
|
|
201
|
+
|
|
202
|
+
```json
|
|
203
|
+
{
|
|
204
|
+
"questions": [
|
|
205
|
+
{
|
|
206
|
+
"question": "<N> findings (<C>C / <H>H / <M>M / <L>L). How to triage? RECOMMENDATION: Choose <X> — <one-line reason based on severity/confidence mix>.",
|
|
207
|
+
"header": "Triage Mode",
|
|
208
|
+
"multiSelect": false,
|
|
209
|
+
"options": [
|
|
210
|
+
{"label": "A) Review each — walk through finding by finding with full details"},
|
|
211
|
+
{"label": "B) Accept all — add every finding to action list, skip per-item review"},
|
|
212
|
+
{"label": "C) Reject all — dismiss all findings, verdict stands, no action list"},
|
|
213
|
+
{"label": "D) Exit — keep the TL;DR above, stop here"}
|
|
214
|
+
]
|
|
215
|
+
}
|
|
216
|
+
]
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
Routing: A → Phase 5. B → mark all Accepted, jump to Phase 6. C → mark all Rejected, jump to Phase 6. D → stop.
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## Phase 5: Per-finding loop (only if A chosen)
|
|
225
|
+
|
|
226
|
+
Iterate findings in order: Critical → High → Medium → Low. For EACH, print the full detail block:
|
|
227
|
+
|
|
228
|
+
```
|
|
229
|
+
[<ID>] <severity> | confidence: <N>/10 | <file:line>
|
|
230
|
+
Title: <title>
|
|
231
|
+
Description: <what's wrong — concrete>
|
|
232
|
+
Evidence: <code snippet or direct quote from diff>
|
|
233
|
+
Failure scenario: <step-by-step how this hits production>
|
|
234
|
+
Suggested fix: <specific, actionable>
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
Then ask. Append `(Recommended)` to the matching option:
|
|
238
|
+
- **Accept** if: severity ≥ High AND confidence ≥ 7
|
|
239
|
+
- **Reject** if: confidence ≤ 6
|
|
240
|
+
- **Defer** if: severity Medium/Low AND confidence ≥ 7
|
|
241
|
+
|
|
242
|
+
```json
|
|
243
|
+
{
|
|
244
|
+
"questions": [
|
|
245
|
+
{
|
|
246
|
+
"question": "Finding [<ID>]: <title>\n<1-line flaw summary>\nRECOMMENDATION: Choose <X> — <rationale: severity × confidence>.",
|
|
247
|
+
"header": "Finding <ID>",
|
|
248
|
+
"multiSelect": false,
|
|
249
|
+
"options": [
|
|
250
|
+
{"label": "A) Accept — add to action list"},
|
|
251
|
+
{"label": "B) Reject — false positive, dismiss"},
|
|
252
|
+
{"label": "C) Defer — note in PR description, don't fix now"}
|
|
253
|
+
]
|
|
254
|
+
}
|
|
255
|
+
]
|
|
256
|
+
}
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
*(Move `(Recommended)` to whichever option matches the rule above.)*
|
|
260
|
+
|
|
261
|
+
Escape hatch: if user hits Reject 3 times in a row on High/Critical items, ask once: "Skip remaining per-finding prompts? A) Continue B) Reject all remaining C) Accept all remaining" — avoids fatigue on noisy reviews.
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
## Phase 6: Summary
|
|
266
|
+
|
|
267
|
+
Print final tally:
|
|
268
|
+
|
|
269
|
+
```
|
|
270
|
+
Triage complete.
|
|
271
|
+
Accepted: N | Rejected: N | Deferred: N
|
|
272
|
+
|
|
273
|
+
Action list (accepted):
|
|
274
|
+
- [<ID>] file:line — <title> → /sp-fix "<title>"
|
|
275
|
+
- ...
|
|
276
|
+
|
|
277
|
+
Deferred (note in PR description):
|
|
278
|
+
- [<ID>] file:line — <title>
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
If accepted = 0 → print "No action items. Verdict stands: <verdict>." and stop.
|
|
282
|
+
Do **NOT** spawn `/sp-fix` automatically — user runs it per item.
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
|
|
286
|
+
## Rules
|
|
287
|
+
1. **Never auto-fix.** Report only — triage classifies, doesn't edit code.
|
|
288
|
+
2. **Specific.** Every finding has `file:line` and concrete description.
|
|
289
|
+
3. **Severity matches impact.** Style nits = Low. Injection = Critical.
|
|
290
|
+
4. **Positive notes mandatory.** Reviews aren't just about problems.
|
|
291
|
+
5. **Review against intent.** Not just "clean code?" but "does this match spec/commits?"
|
|
292
|
+
6. **Proportional.** 5-line doc change ≠ 500-line auth rewrite.
|
|
293
|
+
7. **TL;DR first, details on demand.** Never dump all finding bodies to terminal upfront — reveal detail only inside Phase 5.
|
|
294
|
+
8. **Recommendation mandatory.** Every `AskUserQuestion` includes `RECOMMENDATION:` in question text AND `(Recommended)` suffix on the matching option.
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
# Project Rules
|
|
2
|
-
|
|
3
|
-
## Spec-First Development
|
|
4
|
-
|
|
5
|
-
Every change follows this cycle: **SPEC (with acceptance scenarios) → CODE + TESTS → BUILD PASS**.
|
|
6
|
-
|
|
7
|
-
- Business logic specs live in `docs/specs/<feature>/<feature>.md`
|
|
8
|
-
- Acceptance scenarios (Given/When/Then) are embedded in the spec under `## Stories`
|
|
9
|
-
- Never write code before the spec exists. Never auto-modify specs from code.
|
|
10
|
-
- Specs are the source of truth. If code contradicts the spec, the code is wrong.
|
|
11
|
-
|
|
12
|
-
## Workflow Quick Reference
|
|
13
|
-
|
|
14
|
-
| Trigger | Commands | Details |
|
|
15
|
-
|---------|----------|---------|
|
|
16
|
-
| New project (no codebase yet) | `/sp-explore` (greenfield) → `/sp-scaffold` → `/sp-plan` → `/sp-build` | Scaffolds a runnable skeleton + ARCHITECTURE/ADRs before the first spec; `/sp-build` Foundation Gate blocks the TDD loop until a runnable harness exists |
|
|
17
|
-
| Feature unclear / complex | `/sp-explore` → `/sp-plan` | Clarify requirements before writing spec |
|
|
18
|
-
| New feature | `/sp-plan` → `/sp-challenge` (optional) → code in chunks → `/sp-build` each chunk | Start with spec or description |
|
|
19
|
-
| Update feature | `/sp-plan <spec-path> "changes"` → code → `/sp-build` | Do NOT manually edit spec before /sp-plan |
|
|
20
|
-
| Bug (complex/outage) | `/sp-investigate "description"` → `/sp-fix <investigation-file>` | OPTIONAL: diagnose root cause + blast radius before fixing |
|
|
21
|
-
| Bug fix | `/sp-fix "description"` | Test-first: write failing test → fix → green |
|
|
22
|
-
| Remove feature | `/sp-plan <spec-path> "remove stories"` → delete code + tests → build pass | /sp-plan handles snapshot before removal |
|
|
23
|
-
| Pre-merge check | `/sp-review` | Diff-based quality gate |
|
|
24
|
-
| Commit changes | `/sp-commit` | Secret scan + conventional commit |
|
|
25
|
-
| Render spec HTML | `/sp-spec-render <feature>` | Generates scannable `<feature>.html` (sidebar TOC, story cards). Run after `/sp-plan` if you want the HTML view, or to refresh a stale one |
|
|
26
|
-
| Render any markdown HTML | `/sp-md-render <file.md>` | Generic counterpart to `/sp-spec-render` for non-spec markdown (investigation, explore, RFC, retro, README). Callouts, step cards, Mermaid, dark/light theme |
|
|
27
|
-
| Multi-LLM review | `/sp-voices [target]` | Send material to 2–3 LLMs, synthesize consensus + disagreements |
|
|
28
|
-
| Rephrase to human voice | `/sp-humanize [text]` | Turn plan/notes/AI output into natural, send-ready text. Infers format + audience + tone, strips AI tone. Not part of the dev cycle |
|
|
29
|
-
|
|
30
|
-
For detailed workflow steps, templates, and decision trees, see `docs/WORKFLOW.md`.
|
|
31
|
-
|
|
32
|
-
## Testing
|
|
33
|
-
|
|
34
|
-
- **Run tests:** use the project's native test command (e.g. `npx vitest run`, `swift test`, `python3 -m pytest`, `cargo test`, `go test ./...`). `/sp-build` and `/sp-fix` auto-detect it from project markers.
|
|
35
|
-
- **Compile/typecheck BEFORE running tests.** Catch syntax errors early.
|
|
36
|
-
- **Max 3 fix loops** for test failures. If tests still fail after 3 attempts, stop and report.
|
|
37
|
-
- **NEVER fix production code** to make a test pass — ask the user first.
|
|
38
|
-
- **No mocks, fakes, stubs, or cheats** to pass builds. Real implementations only.
|
|
39
|
-
Test doubles are acceptable only when they replace external services (APIs, databases)
|
|
40
|
-
that cannot run locally.
|
|
41
|
-
|
|
42
|
-
## Project Info
|
|
43
|
-
|
|
44
|
-
> Fill these in when setting up the project (or let `setup.sh` do it automatically).
|
|
45
|
-
|
|
46
|
-
- **Language:** [CUSTOMIZE]
|
|
47
|
-
- **Test framework:** [CUSTOMIZE]
|
|
48
|
-
- **Source directory:** [CUSTOMIZE]
|
|
49
|
-
- **Test directory:** [CUSTOMIZE]
|
|
50
|
-
|
|
51
|
-
## Conventions
|
|
52
|
-
|
|
53
|
-
- **Commits:** Conventional format — `type(scope): description`
|
|
54
|
-
Types: `feat`, `fix`, `docs`, `refactor`, `test`, `chore`, `perf`, `build`, `ci`
|
|
55
|
-
- **File naming:** Descriptive enough that AI tools understand the purpose from the path alone.
|
|
56
|
-
Prefer kebab-case for new files (e.g., `user-authentication-service.ts`).
|
|
57
|
-
- **Dates in filenames:** Use `$(date +%Y-%m-%d)` — never guess dates.
|
|
58
|
-
- **Spec naming:**
|
|
59
|
-
- kebab-case, lowercase: `user-auth/user-auth.md`, `file-sync/file-sync.md`
|
|
60
|
-
- Feature name, not module name: `user-auth/` not `AuthService/`
|
|
61
|
-
- Each feature gets its own directory: `docs/specs/<feature>/<feature>.md`
|
|
62
|
-
- Short (2-3 words): `payment-flow/` not `payment-processing-with-stripe-integration/`
|
|
63
|
-
- No prefix/suffix: `user-auth.md` not `spec-user-auth.md`
|
|
64
|
-
|
|
65
|
-
## Forbidden
|
|
66
|
-
|
|
67
|
-
These patterns are never acceptable in this project:
|
|
68
|
-
|
|
69
|
-
- `any` / `Any` type without explicit justification in a comment
|
|
70
|
-
- Force unwrap (`!`) or force cast (`as!`) without a preceding guard
|
|
71
|
-
- Hardcoded secrets, API keys, tokens, or credentials in source files
|
|
72
|
-
- Mocks or fake data used solely to make tests pass
|
|
73
|
-
- `git push --force` to main or master branches
|
|
74
|
-
- Editing generated files, vendor directories, or lock files
|
|
75
|
-
- Committing `.env` files, certificates, or private keys
|
|
76
|
-
- Ignoring compiler/linter warnings without documented reason
|
|
77
|
-
- Replacing real code with placeholder comments like `// ... existing code ...`
|
|
78
|
-
- Renaming parameters to `_param` instead of actually fixing unused parameter issues
|
|
79
|
-
- Reading or writing `.env`, `.pem`, `.key`, or other sensitive files (use `.env.example` for templates)
|
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# path-guard.sh — PreToolUse hook for Claude Code
|
|
3
|
-
#
|
|
4
|
-
# Blocks Bash commands that target directories known to be large and wasteful
|
|
5
|
-
# to explore (node_modules, build artifacts, .git internals, etc.).
|
|
6
|
-
#
|
|
7
|
-
# Exit codes:
|
|
8
|
-
# 0 — command allowed
|
|
9
|
-
# 2 — command blocked (policy)
|
|
10
|
-
#
|
|
11
|
-
# Environment:
|
|
12
|
-
# PATH_GUARD_EXTRA — additional pipe-separated patterns to block
|
|
13
|
-
# e.g. "\.terraform|\.vagrant"
|
|
14
|
-
|
|
15
|
-
set -euo pipefail
|
|
16
|
-
|
|
17
|
-
# Windows note: this hook requires bash (WSL or Git Bash).
|
|
18
|
-
# On Windows without bash, Claude Code will fail to run this hook and skip it silently.
|
|
19
|
-
# Install WSL or Git Bash and ensure `bash` is in PATH to activate protection.
|
|
20
|
-
|
|
21
|
-
# ─── Read hook payload from stdin ───────────────────────────────────
|
|
22
|
-
|
|
23
|
-
INPUT=$(cat)
|
|
24
|
-
[[ -z "$INPUT" ]] && exit 0
|
|
25
|
-
|
|
26
|
-
# Extract command from JSON — try node first, fall back to grep/sed
|
|
27
|
-
extract_command() {
|
|
28
|
-
if command -v node &>/dev/null; then
|
|
29
|
-
printf '%s' "$1" | node -e "
|
|
30
|
-
try {
|
|
31
|
-
const d = JSON.parse(require('fs').readFileSync(0, 'utf-8'));
|
|
32
|
-
const cmd = d.tool_input?.command;
|
|
33
|
-
if (typeof cmd === 'string') process.stdout.write(cmd);
|
|
34
|
-
} catch {}
|
|
35
|
-
" 2>/dev/null
|
|
36
|
-
else
|
|
37
|
-
# Lightweight fallback: extract "command":"..." from JSON
|
|
38
|
-
printf '%s' "$1" | grep -o '"command":"[^"]*"' | head -1 | sed 's/^"command":"//;s/"$//' 2>/dev/null
|
|
39
|
-
fi
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
COMMAND=$(extract_command "$INPUT") || exit 0
|
|
43
|
-
|
|
44
|
-
[[ -z "$COMMAND" ]] && exit 0
|
|
45
|
-
|
|
46
|
-
# ─── Blocked directory patterns ─────────────────────────────────────
|
|
47
|
-
|
|
48
|
-
# Use explicit path separators to avoid substring false positives.
|
|
49
|
-
# [/\\] matches both forward slash (Unix/macOS) and backslash (Windows Git Bash).
|
|
50
|
-
# e.g. "build/" should not match "rebuild/src" or "my-build-tool"
|
|
51
|
-
SEP="[/\\\\]"
|
|
52
|
-
BLOCKED="(^|[ /\\\\])node_modules(${SEP}|$| )"
|
|
53
|
-
BLOCKED+="|(__pycache__)"
|
|
54
|
-
BLOCKED+="|\.git${SEP}(objects|refs)"
|
|
55
|
-
BLOCKED+="|(^|[ /\\\\])dist${SEP}"
|
|
56
|
-
BLOCKED+="|(^|[ /\\\\])build${SEP}"
|
|
57
|
-
BLOCKED+="|\.next${SEP}"
|
|
58
|
-
BLOCKED+="|(^|[ /\\\\])vendor(${SEP}|$| )"
|
|
59
|
-
BLOCKED+="|(^|[ /\\\\])Pods(${SEP}|$| )"
|
|
60
|
-
BLOCKED+="|\.build${SEP}"
|
|
61
|
-
BLOCKED+="|DerivedData"
|
|
62
|
-
BLOCKED+="|\.gradle${SEP}"
|
|
63
|
-
BLOCKED+="|(^|[ /\\\\])target${SEP}"
|
|
64
|
-
BLOCKED+="|\.nuget"
|
|
65
|
-
BLOCKED+="|\.cache(${SEP}|$| )"
|
|
66
|
-
# Python
|
|
67
|
-
BLOCKED+="|(^|[ /\\\\])\.venv${SEP}"
|
|
68
|
-
BLOCKED+="|(^|[ /\\\\])venv${SEP}"
|
|
69
|
-
BLOCKED+="|\.mypy_cache${SEP}"
|
|
70
|
-
BLOCKED+="|\.pytest_cache${SEP}"
|
|
71
|
-
BLOCKED+="|\.ruff_cache${SEP}"
|
|
72
|
-
BLOCKED+="|\.egg-info(${SEP}|$| )"
|
|
73
|
-
# C# .NET (match .NET-specific subdirs to avoid false positives on generic bin/)
|
|
74
|
-
BLOCKED+="|(^|[ /\\\\])bin${SEP}(Debug|Release|net|x64|x86)"
|
|
75
|
-
BLOCKED+="|(^|[ /\\\\])obj${SEP}(Debug|Release|net)"
|
|
76
|
-
# Node.js frameworks
|
|
77
|
-
BLOCKED+="|\.nuxt${SEP}"
|
|
78
|
-
BLOCKED+="|\.svelte-kit${SEP}"
|
|
79
|
-
BLOCKED+="|\.parcel-cache${SEP}"
|
|
80
|
-
BLOCKED+="|\.turbo${SEP}"
|
|
81
|
-
BLOCKED+="|(^|[ /\\\\])out${SEP}(server|static|_next)"
|
|
82
|
-
# Ruby
|
|
83
|
-
BLOCKED+="|\.bundle${SEP}"
|
|
84
|
-
|
|
85
|
-
# Append project-specific patterns from env
|
|
86
|
-
if [[ -n "${PATH_GUARD_EXTRA:-}" ]]; then
|
|
87
|
-
BLOCKED+="|$PATH_GUARD_EXTRA"
|
|
88
|
-
fi
|
|
89
|
-
|
|
90
|
-
# ─── Exploration-verb pre-check ─────────────────────────────────────
|
|
91
|
-
# Only apply blocked-path rules when the command contains a file-reading
|
|
92
|
-
# or directory-listing verb. This avoids false positives for commands that
|
|
93
|
-
# merely REFERENCE a path through a blocked directory without exploring it
|
|
94
|
-
# (e.g. variable assignments, [ -x "$B" ] binary existence checks, or
|
|
95
|
-
# running a compiled binary whose path happens to include /dist/).
|
|
96
|
-
#
|
|
97
|
-
# Verbs that indicate directory/file exploration:
|
|
98
|
-
EXPLORE_VERB_RE="(^|[[:space:]|;&\`(])(ls|ll|la|find|cat|head|tail|less|more|wc|stat|du|tree|bat|od|xxd|hexdump|nl)([[:space:]]|$)"
|
|
99
|
-
|
|
100
|
-
if ! printf '%s\n' "$COMMAND" | grep -qE "$EXPLORE_VERB_RE"; then
|
|
101
|
-
exit 0
|
|
102
|
-
fi
|
|
103
|
-
|
|
104
|
-
# ─── Match and block ────────────────────────────────────────────────
|
|
105
|
-
|
|
106
|
-
# Strip node_modules/.bin/<binary> references before checking blocked paths.
|
|
107
|
-
# Executing an installed binary (e.g. node_modules/.bin/playwright) is not
|
|
108
|
-
# directory exploration — only the binary itself is referenced, not the tree.
|
|
109
|
-
COMMAND_FOR_CHECK=$(printf '%s\n' "$COMMAND" | sed -E "s|node_modules[/\\]\.bin[/\\][^[:space:]]*||g")
|
|
110
|
-
|
|
111
|
-
if printf '%s\n' "$COMMAND_FOR_CHECK" | grep -qE "$BLOCKED"; then
|
|
112
|
-
# Extract which pattern matched for a useful error message
|
|
113
|
-
MATCHED=$(printf '%s\n' "$COMMAND" | grep -oE "$BLOCKED" | head -1)
|
|
114
|
-
echo "Blocked: command references '$MATCHED' — this directory is typically large and exploring it wastes tokens. Use Glob or Grep tools instead." >&2
|
|
115
|
-
exit 2
|
|
116
|
-
fi
|
|
117
|
-
|
|
118
|
-
exit 0
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# self-review.sh — Stop hook for Claude Code
|
|
3
|
-
#
|
|
4
|
-
# Injects a self-review checklist when Claude is about to finish.
|
|
5
|
-
# Non-blocking: always exits 0, just adds context for Claude to consider.
|
|
6
|
-
#
|
|
7
|
-
# Environment:
|
|
8
|
-
# SELF_REVIEW_ENABLED — set to "false" to disable (default: true)
|
|
9
|
-
|
|
10
|
-
# No set -euo pipefail — this hook must NEVER fail
|
|
11
|
-
# Windows note: requires bash (WSL or Git Bash). Silently skipped on Windows native.
|
|
12
|
-
|
|
13
|
-
# Check if disabled
|
|
14
|
-
if [[ "${SELF_REVIEW_ENABLED:-true}" == "false" ]]; then
|
|
15
|
-
exit 0
|
|
16
|
-
fi
|
|
17
|
-
|
|
18
|
-
# Read stdin (Stop event payload — may be empty or minimal)
|
|
19
|
-
cat > /dev/null 2>&1 || true
|
|
20
|
-
|
|
21
|
-
# Inject self-review checklist as context
|
|
22
|
-
cat <<'REVIEW_JSON'
|
|
23
|
-
{
|
|
24
|
-
"continue": true,
|
|
25
|
-
"systemMessage": "Self-review before finishing:\n1. Did you leave any TODO/FIXME comments that should be resolved now?\n2. Did you create mock or fake implementations just to pass tests?\n3. Did you replace real code with placeholder comments like '// ... existing code'?\n4. Do all changed files compile and typecheck cleanly?\n5. Did you run the full test suite, not just the new tests?\n6. Are there any files you modified but forgot to include in the summary?"
|
|
26
|
-
}
|
|
27
|
-
REVIEW_JSON
|