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.
Files changed (46) hide show
  1. package/README.md +111 -311
  2. package/package.json +2 -1
  3. package/src/cli.js +16 -6
  4. package/src/commands/diff.js +1 -1
  5. package/src/commands/init-agents.js +40 -20
  6. package/src/commands/init-global.js +88 -33
  7. package/src/commands/init-interactive.js +71 -0
  8. package/src/commands/init.js +61 -22
  9. package/src/commands/remove.js +159 -49
  10. package/src/commands/upgrade.js +21 -56
  11. package/src/lib/agent-guards.js +34 -78
  12. package/src/lib/agent-install.js +38 -25
  13. package/src/lib/agents.js +53 -11
  14. package/src/lib/claude-global.js +50 -77
  15. package/src/lib/hooks.js +203 -0
  16. package/src/lib/installer.js +73 -61
  17. package/src/lib/reconcile.js +13 -8
  18. package/templates/{.claude/hooks → hooks}/file-guard.js +26 -21
  19. package/templates/hooks/specpipe-read-guard.sh +94 -21
  20. package/templates/hooks/specpipe-shell-guard.sh +121 -29
  21. package/templates/rules/specpipe-rules.md +77 -0
  22. package/templates/skills/sp-build/SKILL.md +101 -1
  23. package/templates/skills/sp-build-behavior-matrix/SKILL.md +876 -0
  24. package/templates/skills/sp-challenge/SKILL.md +34 -0
  25. package/templates/skills/sp-challenge-behavior-matrix/SKILL.md +289 -0
  26. package/templates/skills/sp-explore/SKILL.md +132 -0
  27. package/templates/skills/sp-explore-behavior-matrix/SKILL.md +862 -0
  28. package/templates/skills/sp-fix/SKILL.md +73 -1
  29. package/templates/skills/sp-fix-behavior-matrix/SKILL.md +338 -0
  30. package/templates/skills/sp-investigate/SKILL.md +70 -0
  31. package/templates/skills/sp-investigate-behavior-matrix/SKILL.md +718 -0
  32. package/templates/skills/sp-plan/SKILL.md +90 -0
  33. package/templates/skills/sp-plan-behavior-matrix/SKILL.md +1037 -0
  34. package/templates/skills/sp-review/SKILL.md +29 -3
  35. package/templates/skills/sp-review-behavior-matrix/SKILL.md +294 -0
  36. package/templates/.claude/CLAUDE.md +0 -79
  37. package/templates/.claude/hooks/path-guard.sh +0 -118
  38. package/templates/.claude/hooks/self-review.sh +0 -27
  39. package/templates/.claude/hooks/sensitive-guard.sh +0 -227
  40. package/templates/.claude/settings.json +0 -68
  41. package/templates/docs/WORKFLOW.md +0 -325
  42. package/templates/docs/specs/.gitkeep +0 -0
  43. package/templates/rules/specpipe-guards.md +0 -40
  44. package/templates/scripts/test-hooks.sh +0 -66
  45. /package/templates/{.claude/hooks → hooks}/comment-guard.js +0 -0
  46. /package/templates/{.claude/hooks → hooks}/glob-guard.js +0 -0
@@ -1,227 +0,0 @@
1
- #!/usr/bin/env bash
2
- # sensitive-guard.sh — PreToolUse hook for Claude Code
3
- #
4
- # Blocks access to sensitive files: .env, private keys, credentials, tokens.
5
- # Supports .agentignore for project-specific patterns.
6
- #
7
- # Exit codes:
8
- # 0 — access allowed
9
- # 2 — access blocked (sensitive file)
10
- #
11
- # Environment:
12
- # SENSITIVE_GUARD_EXTRA — additional pipe-separated filename patterns to block
13
-
14
- set -euo pipefail
15
-
16
- # Windows note: this hook requires bash (WSL or Git Bash).
17
- # On Windows without bash, Claude Code will fail to run this hook and skip it silently.
18
- # Install WSL or Git Bash and ensure `bash` is in PATH to activate protection.
19
-
20
- # ─── Read hook payload from stdin ───────────────────────────────────
21
-
22
- INPUT=$(cat)
23
- [[ -z "$INPUT" ]] && exit 0
24
-
25
- # Check Node.js availability — security hook should warn loudly if disabled
26
- if ! command -v node &>/dev/null; then
27
- echo "WARNING: sensitive-guard disabled — Node.js not found. Sensitive files are NOT protected." >&2
28
- exit 0
29
- fi
30
-
31
- # Extract file path and/or command using inline Node.js
32
- PARSED=$(printf '%s' "$INPUT" | node -e "
33
- try {
34
- const d = JSON.parse(require('fs').readFileSync(0, 'utf-8'));
35
- const fp = d.tool_input?.file_path || d.tool_input?.path || '';
36
- const cmd = d.tool_input?.command || '';
37
- const pat = d.tool_input?.pattern || '';
38
- process.stdout.write(fp + '\n' + cmd + '\n' + pat);
39
- } catch { process.exit(0); }
40
- " 2>/dev/null) || exit 0
41
-
42
- FILE_PATH=$(printf '%s' "$PARSED" | sed -n '1p')
43
- COMMAND=$(printf '%s' "$PARSED" | sed -n '2p')
44
- PATTERN=$(printf '%s' "$PARSED" | sed -n '3p')
45
-
46
- # ─── Sensitive filename patterns ────────────────────────────────────
47
-
48
- # Returns 0 (true) if the path matches a sensitive pattern
49
- is_sensitive() {
50
- local filepath="$1"
51
- local basename
52
- basename=$(basename "$filepath" 2>/dev/null) || return 1
53
-
54
- # Exact filenames (basename match)
55
- case "$basename" in
56
- .env|.env.local|.env.development|.env.production|.env.staging|.env.test)
57
- return 0 ;;
58
- .npmrc|.pypirc|.netrc)
59
- return 0 ;;
60
- id_rsa|id_ecdsa|id_ed25519|id_dsa)
61
- return 0 ;;
62
- serviceAccountKey.json|service-account*.json)
63
- return 0 ;;
64
- config.json)
65
- # config.json only sensitive inside .docker/
66
- [[ "$filepath" == *".docker/config.json"* ]] && return 0
67
- ;;
68
- esac
69
-
70
- # Extension patterns
71
- case "$basename" in
72
- *.pem|*.key|*.p12|*.pfx|*.jks|*.keystore|*.truststore)
73
- return 0 ;;
74
- *_rsa|*_ecdsa|*_ed25519|*_dsa)
75
- return 0 ;;
76
- esac
77
-
78
- # Substring patterns (case-insensitive via bash)
79
- local lower
80
- lower=$(echo "$basename" | tr '[:upper:]' '[:lower:]')
81
- case "$lower" in
82
- *credential*|*secret*|*private_key*|*privatekey*)
83
- return 0 ;;
84
- firebase-adminsdk*)
85
- return 0 ;;
86
- esac
87
-
88
- # .env.* but NOT .env.example or .env.sample or .env.template
89
- if [[ "$basename" =~ ^\.env\. ]]; then
90
- case "$basename" in
91
- .env.example|.env.sample|.env.template) return 1 ;;
92
- *) return 0 ;;
93
- esac
94
- fi
95
-
96
- # Extra patterns from env var
97
- if [[ -n "${SENSITIVE_GUARD_EXTRA:-}" ]]; then
98
- if printf '%s\n' "$filepath" | grep -qE "$SENSITIVE_GUARD_EXTRA"; then
99
- return 0
100
- fi
101
- fi
102
-
103
- return 1
104
- }
105
-
106
- # ─── Check .agentignore ────────────────────────────────────────────
107
-
108
- check_agentignore() {
109
- local filepath="$1"
110
- local ignorefile=""
111
-
112
- # Look for ignore files in project root
113
- for candidate in .agentignore .aiignore .cursorignore; do
114
- if [[ -f "$candidate" ]]; then
115
- ignorefile="$candidate"
116
- break
117
- fi
118
- done
119
-
120
- [[ -z "$ignorefile" ]] && return 1
121
-
122
- # Simple line-by-line match (not full gitignore glob, but covers common cases)
123
- local relpath
124
- # Normalize separators to forward slash before stripping prefix (handles Git Bash on Windows)
125
- local normalized_fp normalized_pwd
126
- normalized_fp=$(printf '%s' "$filepath" | tr '\\' '/')
127
- normalized_pwd=$(pwd | tr '\\' '/')
128
- relpath=$(printf '%s' "$normalized_fp" | sed "s|^${normalized_pwd}/||") 2>/dev/null || relpath="$filepath"
129
-
130
- while IFS= read -r pattern || [[ -n "$pattern" ]]; do
131
- # Skip comments and empty lines
132
- [[ -z "$pattern" || "$pattern" == \#* ]] && continue
133
- # Simple glob match
134
- if [[ "$relpath" == $pattern ]] || [[ "$(basename "$relpath")" == $pattern ]]; then
135
- return 0
136
- fi
137
- done < "$ignorefile"
138
-
139
- return 1
140
- }
141
-
142
- # ─── Check file path access ────────────────────────────────────────
143
-
144
- block_with_message() {
145
- local filepath="$1"
146
- echo "Blocked: '$filepath' is a sensitive file (secrets, keys, or credentials). Access denied to protect sensitive data. Use .env.example for templates instead." >&2
147
- exit 2
148
- }
149
-
150
- warn_with_message() {
151
- local filepath="$1"
152
- echo "Warning: '$filepath' is a sensitive file. If the user approved this access, proceed. Otherwise, ask the user for permission first via AskUserQuestion before reading sensitive files." >&2
153
- # Warn only — exit 0 allows the command to proceed
154
- # This enables the flow: Block Read → Claude asks user → User approves → Claude uses bash cat
155
- exit 0
156
- }
157
-
158
- # ─── Fast-path: skip obviously safe files ──────────────────────────
159
-
160
- fast_path_safe() {
161
- local ext="${1##*.}"
162
- case "$ext" in
163
- md|ts|tsx|js|jsx|css|scss|html|svg|json|yaml|yml|toml|xml|txt|sh|py|rb|rs|go|java|kt|swift|c|cpp|h|hpp|cs|vue|svelte|astro)
164
- # But json could be sensitive — check name
165
- if [[ "$ext" == "json" ]]; then
166
- return 1 # not fast-path safe, need full check
167
- fi
168
- return 0 ;;
169
- esac
170
- return 1
171
- }
172
-
173
- # ─── Check direct file access (Read/Write/Edit) → BLOCK ────────────
174
-
175
- if [[ -n "$FILE_PATH" ]]; then
176
- if ! fast_path_safe "$FILE_PATH"; then
177
- if is_sensitive "$FILE_PATH" || check_agentignore "$FILE_PATH"; then
178
- block_with_message "$FILE_PATH"
179
- fi
180
- fi
181
- fi
182
-
183
- # ─── Check bash commands → WARN only (allows approved access) ──────
184
-
185
- if [[ -n "$COMMAND" ]]; then
186
- # Extract .env file references from commands
187
- SENSITIVE_IN_CMD=$(printf '%s\n' "$COMMAND" | grep -oE '[\./[:alnum:]_-]*\.env[\.[:alnum:]_-]*' | head -5) || true
188
-
189
- if [[ -n "$SENSITIVE_IN_CMD" ]]; then
190
- while IFS= read -r match; do
191
- case "$match" in
192
- *.example|*.sample|*.template) continue ;;
193
- esac
194
- if is_sensitive "$match"; then
195
- warn_with_message "$match"
196
- fi
197
- done <<< "$SENSITIVE_IN_CMD"
198
- fi
199
-
200
- # Check for key/cert file references in commands → also warn only
201
- KEY_IN_CMD=$(printf '%s\n' "$COMMAND" | grep -oE '[[:alnum:]_./-]*\.(pem|key|p12|pfx|jks|keystore)' | head -3) || true
202
- if [[ -n "$KEY_IN_CMD" ]]; then
203
- while IFS= read -r match; do
204
- warn_with_message "$match"
205
- done <<< "$KEY_IN_CMD"
206
- fi
207
-
208
- # Check for SSH keys, credentials, service accounts in commands
209
- SENSITIVE_NAMES=$(printf '%s\n' "$COMMAND" | grep -oiE '(id_rsa|id_ecdsa|id_ed25519|id_dsa|serviceAccountKey\.json|service-account[[:alnum:]_-]*\.json|\.npmrc|\.pypirc|\.netrc)' | head -3) || true
210
- if [[ -n "$SENSITIVE_NAMES" ]]; then
211
- while IFS= read -r match; do
212
- warn_with_message "$match"
213
- done <<< "$SENSITIVE_NAMES"
214
- fi
215
-
216
- # Check for credential/secret keywords in file arguments
217
- CRED_FILES=$(printf '%s\n' "$COMMAND" | grep -oiE '[[:alnum:]_./-]*(credential|secret|private_key|privatekey)[[:alnum:]_./-]*' | head -3) || true
218
- if [[ -n "$CRED_FILES" ]]; then
219
- while IFS= read -r match; do
220
- warn_with_message "$match"
221
- done <<< "$CRED_FILES"
222
- fi
223
- fi
224
-
225
- # ─── All checks passed ─────────────────────────────────────────────
226
-
227
- exit 0
@@ -1,68 +0,0 @@
1
- {
2
- "hooks": {
3
- "PreToolUse": [
4
- {
5
- "matcher": "Bash",
6
- "hooks": [
7
- {
8
- "type": "command",
9
- "command": "bash \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/path-guard.sh"
10
- },
11
- {
12
- "type": "command",
13
- "command": "bash \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/sensitive-guard.sh"
14
- }
15
- ]
16
- },
17
- {
18
- "matcher": "Read|Write|Edit|MultiEdit|Grep",
19
- "hooks": [
20
- {
21
- "type": "command",
22
- "command": "bash \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/sensitive-guard.sh"
23
- }
24
- ]
25
- },
26
- {
27
- "matcher": "Edit|MultiEdit",
28
- "hooks": [
29
- {
30
- "type": "command",
31
- "command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/comment-guard.js"
32
- }
33
- ]
34
- },
35
- {
36
- "matcher": "Glob",
37
- "hooks": [
38
- {
39
- "type": "command",
40
- "command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/glob-guard.js"
41
- }
42
- ]
43
- }
44
- ],
45
- "PostToolUse": [
46
- {
47
- "matcher": "Write|Edit|MultiEdit",
48
- "hooks": [
49
- {
50
- "type": "command",
51
- "command": "node \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/file-guard.js"
52
- }
53
- ]
54
- }
55
- ],
56
- "Stop": [
57
- {
58
- "matcher": "",
59
- "hooks": [
60
- {
61
- "type": "command",
62
- "command": "bash \"$CLAUDE_PROJECT_DIR\"/.claude/hooks/self-review.sh"
63
- }
64
- ]
65
- }
66
- ]
67
- }
68
- }
@@ -1,325 +0,0 @@
1
- # Development Workflow Reference
2
-
3
- > Spec-first development: every change follows SPEC (with acceptance scenarios) → CODE + TESTS → BUILD PASS.
4
-
5
- ---
6
-
7
- ## 1. Workflow Types
8
-
9
- ### New Project (Greenfield)
10
-
11
- When: Brand-new project — no codebase yet (empty repo, no package manager / `src/`).
12
-
13
- ```
14
- Step 1 → /sp-explore "what you're building"
15
- Detects greenfield → ALSO decides app-type + stack (versions researched,
16
- current — not recalled from memory) and emits a Bootstrap Brief.
17
- Output: docs/explore/<feature>.md (with ## Bootstrap Brief)
18
-
19
- Step 2 → /sp-scaffold
20
- Reads the Bootstrap Brief → generator-first runnable skeleton:
21
- core/ + ONE pattern-demonstrating module + co-located tests.
22
- Smoke-gated (install → build → start/smoke must be GREEN, ≥1 real test —
23
- this resolves TEST_CMD for /sp-build). Writes ARCHITECTURE.md + ADRs.
24
- Hands off ONLY when it actually runs; otherwise BLOCKED.
25
-
26
- Step 3 → /sp-plan → /sp-build
27
- Normal New Feature flow, now on a runnable base. /sp-build's Foundation
28
- Gate confirms the harness exists before the first RED.
29
- ```
30
-
31
- ### Explore Before Planning
32
-
33
- When: Requirements are unclear, multiple approaches are possible, or it's a brownfield feature with existing code to understand first.
34
-
35
- ```
36
- Step 1 → /sp-explore "feature description"
37
- Clarifies: why the feature is needed, desired behavior, boundaries,
38
- edge cases, business rules, permissions, UI expectations.
39
- Asks questions as a Client Technical Lead — one topic at a time.
40
- Output: docs/explore/<feature>.md
41
-
42
- Step 2 → /sp-plan "feature description"
43
- Auto-detects docs/explore/<feature>.md → skips redundant codebase
44
- discovery, uses explore findings as direct input for the spec.
45
- Continue with the normal New Feature flow from Step 2.
46
- ```
47
-
48
- ### New Feature
49
-
50
- When: Building something that doesn't exist yet (no code, no spec).
51
-
52
- ```
53
- Step 1 → /sp-plan "description of feature"
54
- Generates: docs/specs/<feature>/<feature>.md (spec with acceptance scenarios)
55
- Runs Scope Challenge: reuse check, complexity smell (8+ files = flag),
56
- framework built-in search, distribution check.
57
- Adds "What Already Exists" and "Not in Scope" sections to the spec.
58
- Answers validation questions with effort scales (human: X / CC: Y).
59
- At the end, suggests /sp-spec-render if you want a scannable HTML view.
60
- Review before proceeding.
61
-
62
- Step 1.5 → (Optional) /sp-spec-render <feature>
63
- Generates <feature>.html next to the .md — sidebar TOC, story cards,
64
- collapsible Given/When/Then, dark/light theme. Useful when the spec
65
- is long and you want to scan it visually or share it with stakeholders.
66
- Source .md remains canonical; .html is regenerable, never hand-edit.
67
- For non-spec markdown (investigation, explore, RFC, retro, README),
68
- use /sp-md-render <file.md> instead — same idea, generic content.
69
-
70
- Step 2 → (Optional) /sp-challenge docs/specs/<feature>/<feature>.md
71
- Adversarial review: spawns hostile reviewers to find flaws.
72
- Recommended for complex features, auth, data pipelines.
73
- Skip for simple CRUD or small features.
74
-
75
- Step 3 → Implement in chunks. After each chunk:
76
- /sp-build
77
- Checks 8 edge case categories (null, empty, invalid types, boundary,
78
- error paths, race conditions, large data, special chars).
79
- Draws Coverage Map before writing tests: traces code paths + user flows,
80
- marks [GAP], [GAP][→E2E], [GAP][→EVAL] (with pass@1/pass@3 guidance).
81
- Regression rule enforced.
82
- Repeat until chunk is green.
83
-
84
- Step 4 → /sp-review (before merge)
85
- Checks API/Backend patterns (rate limiting, timeouts, CORS, error leakage).
86
- Extra layer for AI-generated code: regressions, trust boundaries, cost escalation.
87
-
88
- Step 4.5 → (Optional) /sp-voices
89
- Multi-LLM second opinion: sends the diff (or spec) to 2–3 different LLMs,
90
- synthesizes consensus + disagreements. Use when: high-stakes change
91
- (auth/payment/data), mixed-confidence findings from /sp-review, or
92
- you want cross-model verification before merge. Skip for routine changes.
93
-
94
- Step 5 → /sp-commit
95
- ```
96
-
97
- ### Update Existing Feature
98
-
99
- When: Changing behavior, adding options, refactoring logic.
100
-
101
- ```
102
- Step 1 → /sp-plan docs/specs/<feature>/<feature>.md "description of changes"
103
- Mode C handles everything: snapshot → classification → change report → apply.
104
- Do NOT manually edit the spec before running /sp-plan — it creates the
105
- snapshot first, then applies changes. Manual edits bypass snapshot protection.
106
- At the end, suggests /sp-spec-render to refresh <feature>.html if you
107
- have an HTML view (it's stale after this update).
108
-
109
- Step 2 → Implement code changes.
110
- /sp-build
111
- Fix until green.
112
-
113
- Step 4 → /sp-review → /sp-commit
114
- ```
115
-
116
- ### Bug Fix
117
-
118
- When: Something is broken and needs fixing.
119
-
120
- ```
121
- Step 0 → (OPTIONAL) /sp-investigate "description of the bug"
122
- Use ONLY when: bug is complex, ambiguous, production outage, data
123
- corruption, regression with unclear cause, or user wants diagnosis
124
- before any code change. Skip for trivial/obvious bugs.
125
- Read-only: traces data flow, maps blast radius, lists hypotheses
126
- with confidence levels. Writes docs/investigate/<slug>-<date>.md.
127
- No code changes — hands off the report to /sp-fix.
128
-
129
- Step 1 → /sp-fix "description" (or /sp-fix docs/investigate/<slug>-<date>.md)
130
- Auto-detects investigation file if passed → skips redundant discovery.
131
- Draws Bug Path Diagram to confirm hypothesis ([GAP] must be locatable).
132
- Regression rule: if diff broke existing behavior with no test → CRITICAL test required.
133
- Writes failing test → fixes code → confirms green → runs full suite.
134
-
135
- Step 2 → /sp-commit
136
-
137
- Optional → If the bug reveals an undocumented edge case, update the spec.
138
- ```
139
-
140
- ### Remove Feature
141
-
142
- When: Deleting a feature, removing deprecated code.
143
-
144
- ```
145
- Step 1 → /sp-plan docs/specs/<feature>/<feature>.md "remove stories S-XXX"
146
- Mode C creates a snapshot (removing stories = M2 = Major),
147
- then marks stories and AS as removed in the spec.
148
- (Or if removing the entire feature: archive the directory.)
149
-
150
- Step 2 → Delete production code and related test code.
151
-
152
- Step 3 → Run the full test suite with the project's native test command.
153
- Fix any cascading breakage.
154
-
155
- Step 4 → /sp-commit
156
- ```
157
-
158
- ---
159
-
160
- ## 2. Decision Tree
161
-
162
- Use this to decide which workflow to follow:
163
-
164
- ```
165
- Is there a runnable project yet (package manager / src / build)?
166
- ├─ No → New Project (Greenfield). /sp-explore (greenfield) → /sp-scaffold → then /sp-plan.
167
- └─ Yes ↓
168
-
169
- Is this a brand new feature (no existing spec or code)?
170
- ├─ Yes
171
- │ ├─ Are requirements clear and approach decided?
172
- │ │ ├─ Yes → New Feature workflow. Start with /sp-plan.
173
- │ │ │ └─ Is the feature complex (auth, data pipeline, multi-service)?
174
- │ │ │ ├─ Yes → Run /sp-challenge after /sp-plan, before coding.
175
- │ │ │ └─ No → Skip /sp-challenge, go straight to implementation.
176
- │ │ └─ No → Explore Before Planning. Start with /sp-explore.
177
- │ │ Then /sp-plan using the explore output.
178
- └─ No
179
- ├─ Is this a bug fix?
180
- │ ├─ Yes → Bug Fix workflow.
181
- │ │ ├─ Complex / outage / ambiguous cause / data corruption?
182
- │ │ │ ├─ Yes → /sp-investigate first, then /sp-fix.
183
- │ │ │ └─ No → /sp-fix directly.
184
- │ └─ No
185
- │ ├─ Are you removing/deprecating code?
186
- │ │ ├─ Yes → Remove Feature workflow.
187
- │ │ └─ No → Update Feature workflow. Start with /sp-plan.
188
- │ │
189
- │ └─ Is the change very small (< 5 lines, behavior unchanged)?
190
- │ └─ Yes → Skip spec update. Just /sp-build and /sp-commit.
191
- ```
192
-
193
- ---
194
-
195
- ## 3. Prompt Templates
196
-
197
- Copy-paste these when working with your agent.
198
-
199
- ### Template A — Implement + Test Together
200
-
201
- ```
202
- I just implemented [brief description].
203
- Files changed: [list files]
204
-
205
- Based on:
206
- - Spec: docs/specs/<feature>/<feature>.md (section §X)
207
- - Acceptance scenarios: docs/specs/<feature>/<feature>.md (section ## Stories)
208
-
209
- Write tests for the part I just implemented.
210
- Only tests related to this change — not the entire feature.
211
- Build and run until all pass.
212
- If the spec seems incomplete, note what's missing but don't change it.
213
- ```
214
-
215
- ### Template B — Update Feature + Tests
216
-
217
- ```
218
- I'm about to change [description of change].
219
- Affected files: [list]
220
-
221
- 1. /sp-plan docs/specs/<feature>/<feature>.md "description of changes"
222
- (handles snapshot + spec update + acceptance scenarios)
223
- 2. Implement the code change
224
- 3. Update tests to match
225
- 4. Build and run → fix until green
226
- ```
227
-
228
- ### Template C — Test-First Bug Fix
229
-
230
- ```
231
- Bug: [description]
232
- Steps to reproduce: [steps]
233
- Expected: [correct behavior]
234
- Actual: [broken behavior]
235
-
236
- 1. Write a test that reproduces this bug (must fail currently)
237
- 2. Fix the production code to make the test pass
238
- 3. Run the full test suite — nothing else should break
239
- 4. Update the spec if this is an undocumented edge case
240
- ```
241
-
242
- ### Template D — Remove Feature
243
-
244
- ```
245
- Removing: [feature name]
246
- Files to delete: [list]
247
-
248
- 1. /sp-plan docs/specs/<feature>/<feature>.md "remove stories S-XXX, S-YYY"
249
- (handles snapshot + marks stories and AS as removed)
250
- 2. Delete production code
251
- 3. Delete test code
252
- 4. Run full test suite → fix cascading breaks
253
- ```
254
-
255
- ---
256
-
257
- ## 4. Token Cost Guide
258
-
259
- | Workflow | Estimated Tokens | When |
260
- |----------|-----------------|------|
261
- | `/sp-explore` | 10–20k | Before /sp-plan when requirements are unclear |
262
- | `/sp-scaffold` | 15–40k + real install/build time | Greenfield only — once, to stand up a runnable skeleton before the first spec |
263
- | `/sp-build` (incremental) | 5–10k | Daily, after each code chunk |
264
- | `/sp-investigate` (complex bug) | 8–15k | OPTIONAL before /sp-fix — complex/outage only |
265
- | `/sp-fix` (single bug) | 3–5k | As bugs arise |
266
- | `/sp-commit` | 2–4k | Each commit |
267
- | `/sp-review` (diff-based) | 10–20k | Before merge |
268
- | `/sp-plan` (new feature) | 20–40k | Start of new feature |
269
- | `/sp-challenge` (adversarial) | 15–30k | After /sp-plan, for complex features |
270
- | `/sp-spec-render` (HTML view) | 3–8k | User-invoked after `/sp-plan` if HTML view wanted, or to refresh stale `.html` |
271
- | `/sp-md-render` (HTML view, any md) | 3–8k | User-invoked for non-spec markdown — investigation, explore, RFC, retro, README |
272
- | `/sp-voices` (multi-LLM review) | 10–30k + external API cost | Optional — after /sp-review for high-stakes changes |
273
- | `/sp-humanize` (rephrase text) | 2–6k | User-invoked — rephrase plan/notes/AI output into send-ready text. Outside the dev cycle |
274
- | Full audit (manual) | 100k+ | Before release, quarterly |
275
-
276
- **Rule of thumb:** Daily work uses templates + `/sp-build` → low token cost.
277
- Save `/sp-plan` and full audits for significant milestones.
278
-
279
- ---
280
-
281
- ## 5. CI Integration Checklist
282
-
283
- Use this as a PR review checklist (enforce manually or via CI):
284
-
285
- - [ ] **Spec updated?** If production behavior changed, `docs/specs/<feature>/` should have changes.
286
- - [ ] **Acceptance scenarios updated?** If spec behavior changed, AS in spec should reflect it.
287
- - [ ] **Tests pass?** The project's test command exits 0.
288
- - [ ] **No dead tests?** Removed production code → removed corresponding tests.
289
- - [ ] **Coverage not decreased?** (Optional, per-team decision.)
290
- - [ ] **No secrets in diff?** No API keys, tokens, passwords in committed code.
291
- - [ ] **Commit messages conventional?** `type(scope): description` format.
292
-
293
- ---
294
-
295
- ## 6. Spec-Test-Code Sync Rules
296
-
297
- | Change | Must Also Update |
298
- |--------|-----------------|
299
- | Production code behavior changed | Spec (including acceptance scenarios) + tests |
300
- | Spec updated | Acceptance scenarios + tests (if behavior changed) |
301
- | Code removed | Remove related tests. Mark spec and AS as removed. |
302
- | Bug fix | Add test. Update spec if edge case was undocumented. |
303
-
304
- **Never acceptable:**
305
- - Code changed, spec not updated (spec drift)
306
- - Code changed, tests not updated (untested code)
307
- - Spec changed, acceptance scenarios or tests not updated (AS drift)
308
- - Code removed, dead tests remain (orphaned tests)
309
-
310
- **Acceptable shortcut** for changes under 5 lines with no behavior change:
311
- - Code + tests together, skip spec update (same PR).
312
-
313
- ---
314
-
315
- ## 7. Common Pitfalls
316
-
317
- | Pitfall | Symptom | Prevention |
318
- |---------|---------|------------|
319
- | **Spec drift** | Code does X, spec says Y | Always update spec before coding |
320
- | **Dead tests** | Tests pass but test removed functionality | Delete tests when removing features |
321
- | **Over-testing** | 50 tests for simple CRUD, slow suite | Focus on behavior, not implementation details |
322
- | **Mock abuse** | Tests pass with mocks, fail in production | Use real implementations; mock only external services |
323
- | **Big-bang testing** | All tests written after all code is done | Test incrementally after each chunk |
324
- | **Ignoring flaky tests** | Tests pass sometimes, fail sometimes | Fix immediately — flaky tests erode trust |
325
- | **Testing private methods** | Tests break on refactor | Test public API and behavior only |
File without changes
@@ -1,40 +0,0 @@
1
- These are the always-on operating rules for working in this repository with specpipe.
2
- On Claude Code the guardrails are enforced by hooks; on other agents this whole document
3
- is an always-on rule you must self-enforce.
4
-
5
- ## Spec-first cycle
6
-
7
- Every change follows: **SPEC (with acceptance scenarios) → CODE + TESTS → BUILD PASS**.
8
-
9
- - Specs live in `docs/specs/<feature>/<feature>.md`; acceptance scenarios (Given/When/Then)
10
- are embedded under `## Stories`.
11
- - Never write code before the spec exists. Never auto-modify a spec from code.
12
- - The spec is the source of truth — if code contradicts it, the code is wrong.
13
-
14
- ## Guardrails
15
-
16
- - **Don't explore large directories.** Never grep/list/read inside `node_modules/`,
17
- build/dist artifacts, or `.git/` internals — scope to specific paths.
18
- - **Never touch secrets.** Do not read or write `.env*`, private keys, credentials, or
19
- token stores. Respect any `.agentignore` patterns.
20
- - **Never drop real code.** Don't replace implementation with placeholder comments like
21
- `// ... existing code ...`. Reproduce the full code when editing.
22
- - **Avoid broad globs.** No `**/*.ts` at the project root; scope globs to a directory.
23
- - **Keep files focused.** Don't let a source file grow past a few hundred lines — split.
24
-
25
- ## Testing
26
-
27
- - Run the project's native test command (`npx vitest run`, `pytest`, `cargo test`,
28
- `go test ./...`, `swift test`, …). Compile/typecheck before running tests.
29
- - Max 3 fix loops on a failure, then stop and report.
30
- - **Never edit production code to make a test pass** — ask first.
31
- - No mocks/fakes/stubs to pass builds; real implementations only. Test doubles are for
32
- external services (APIs, DBs) that can't run locally.
33
-
34
- ## Conventions
35
-
36
- - Commits: conventional — `type(scope): description` (`feat`, `fix`, `docs`, `refactor`,
37
- `test`, `chore`, `perf`, `build`, `ci`).
38
- - File names: kebab-case, descriptive enough to understand purpose from the path.
39
- - Never `git push --force` to `main`/`master`; never commit `.env`, certs, or keys.
40
- - Self-review before finishing: tests pass, no secrets, no debug code, matches the spec.