prizmkit 1.1.40 → 1.1.42

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 (33) hide show
  1. package/bundled/VERSION.json +3 -3
  2. package/bundled/dev-pipeline/SCHEMA_ANALYSIS.md +1 -1
  3. package/bundled/dev-pipeline/run-bugfix.sh +74 -0
  4. package/bundled/dev-pipeline/run-feature.sh +74 -0
  5. package/bundled/dev-pipeline/run-refactor.sh +74 -0
  6. package/bundled/dev-pipeline/scripts/generate-bootstrap-prompt.py +1 -7
  7. package/bundled/dev-pipeline/scripts/generate-bugfix-prompt.py +1 -1
  8. package/bundled/dev-pipeline/scripts/generate-recovery-prompt.py +1 -1
  9. package/bundled/dev-pipeline/scripts/generate-refactor-prompt.py +1 -1
  10. package/bundled/dev-pipeline/templates/bootstrap-prompt.md +1 -1
  11. package/bundled/dev-pipeline/templates/bootstrap-tier1.md +0 -23
  12. package/bundled/dev-pipeline/templates/bootstrap-tier2.md +0 -23
  13. package/bundled/dev-pipeline/templates/bootstrap-tier3.md +0 -23
  14. package/bundled/dev-pipeline/templates/bugfix-bootstrap-prompt.md +1 -1
  15. package/bundled/dev-pipeline/templates/refactor-bootstrap-prompt.md +1 -1
  16. package/bundled/dev-pipeline/tests/test-deploy-safety.sh +223 -0
  17. package/bundled/skills/_metadata.json +3 -3
  18. package/bundled/skills/app-planner/SKILL.md +0 -3
  19. package/bundled/skills/bugfix-pipeline-launcher/SKILL.md +15 -2
  20. package/bundled/skills/feature-pipeline-launcher/SKILL.md +15 -2
  21. package/bundled/skills/prizmkit-committer/SKILL.md +2 -1
  22. package/bundled/skills/prizmkit-deploy/SKILL.md +491 -209
  23. package/bundled/skills/prizmkit-deploy/references/cloud-platform-deploy.md +93 -0
  24. package/bundled/skills/prizmkit-deploy/references/deploy-config-schema.md +147 -0
  25. package/bundled/skills/prizmkit-deploy/references/deploy-history-schema.md +62 -0
  26. package/bundled/skills/prizmkit-deploy/references/docker-deploy.md +31 -0
  27. package/bundled/skills/prizmkit-deploy/references/nginx-blue-green.md +59 -0
  28. package/bundled/skills/prizmkit-init/SKILL.md +0 -2
  29. package/bundled/skills/prizmkit-plan/SKILL.md +0 -3
  30. package/bundled/skills/refactor-pipeline-launcher/SKILL.md +15 -2
  31. package/package.json +1 -1
  32. package/bundled/dev-pipeline/templates/sections/phase-deploy-verification.md +0 -31
  33. package/bundled/skills/prizmkit-deploy/assets/deploy-template.md +0 -187
@@ -0,0 +1,223 @@
1
+ #!/usr/bin/env bash
2
+ # Test deploy safety check logic across different task status scenarios
3
+ # Run: bash dev-pipeline/tests/test-deploy-safety.sh
4
+ set -euo pipefail
5
+
6
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
7
+ REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
8
+
9
+ RED='\033[0;31m'
10
+ GREEN='\033[0;32m'
11
+ YELLOW='\033[1;33m'
12
+ NC='\033[0m'
13
+
14
+ PASS=0
15
+ FAIL=0
16
+ TOTAL=0
17
+
18
+ pass() { echo -e " ${GREEN}PASS${NC} $1"; PASS=$((PASS + 1)); TOTAL=$((TOTAL + 1)); }
19
+ fail() { echo -e " ${RED}FAIL${NC} $1 — $2"; FAIL=$((FAIL + 1)); TOTAL=$((TOTAL + 1)); }
20
+
21
+ echo "================================="
22
+ echo " Deploy Safety Check Tests"
23
+ echo "================================="
24
+ echo ""
25
+
26
+ # --- Test 1: All tasks completed -> deploy should proceed ---
27
+ echo "[Test 1] All 'completed': incomplete_count should be 0"
28
+ cat > /tmp/test-deploy-all-completed.json << 'JSON'
29
+ {"features": [{"id": "F-A", "status": "completed"}, {"id": "F-B", "status": "completed"}]}
30
+ JSON
31
+ count=$(python3 -c "
32
+ import json
33
+ with open('/tmp/test-deploy-all-completed.json') as f:
34
+ data = json.load(f)
35
+ bad = [f for f in data.get('features', [])
36
+ if f.get('status') not in ('completed', 'skipped')]
37
+ print(len(bad))
38
+ ")
39
+ if [[ "$count" == "0" ]]; then
40
+ pass "incomplete_count=0, deploy proceeds"
41
+ else
42
+ fail "incomplete_count=$count, expected 0"
43
+ fi
44
+
45
+ # --- Test 2: One failed, one completed -> deploy blocked ---
46
+ echo "[Test 2] Mixed 'completed' + 'failed': incomplete_count should be 1"
47
+ cat > /tmp/test-deploy-mixed.json << 'JSON'
48
+ {"features": [{"id": "F-A", "status": "completed"}, {"id": "F-B", "status": "failed"}]}
49
+ JSON
50
+ count=$(python3 -c "
51
+ import json
52
+ with open('/tmp/test-deploy-mixed.json') as f:
53
+ data = json.load(f)
54
+ bad = [f for f in data.get('features', [])
55
+ if f.get('status') not in ('completed', 'skipped')]
56
+ print(len(bad))
57
+ ")
58
+ if [[ "$count" == "1" ]]; then
59
+ pass "incomplete_count=1, deploy blocked"
60
+ else
61
+ fail "incomplete_count=$count, expected 1"
62
+ fi
63
+
64
+ # --- Test 3: All skipped -> deploy proceeds (skipped is non-blocking) ---
65
+ echo "[Test 3] All 'skipped': incomplete_count should be 0"
66
+ cat > /tmp/test-deploy-all-skipped.json << 'JSON'
67
+ {"features": [{"id": "F-A", "status": "skipped"}, {"id": "F-B", "status": "skipped"}]}
68
+ JSON
69
+ count=$(python3 -c "
70
+ import json
71
+ with open('/tmp/test-deploy-all-skipped.json') as f:
72
+ data = json.load(f)
73
+ bad = [f for f in data.get('features', [])
74
+ if f.get('status') not in ('completed', 'skipped')]
75
+ print(len(bad))
76
+ ")
77
+ if [[ "$count" == "0" ]]; then
78
+ pass "incomplete_count=0, deploy proceeds (skipped is non-blocking)"
79
+ else
80
+ fail "incomplete_count=$count, expected 0"
81
+ fi
82
+
83
+ # --- Test 4: Timed-out status -> deploy blocked ---
84
+ echo "[Test 4] 'timed_out' status: incomplete_count should be 1"
85
+ cat > /tmp/test-deploy-timeout.json << 'JSON'
86
+ {"features": [{"id": "F-A", "status": "completed"}, {"id": "F-B", "status": "timed_out"}]}
87
+ JSON
88
+ count=$(python3 -c "
89
+ import json
90
+ with open('/tmp/test-deploy-timeout.json') as f:
91
+ data = json.load(f)
92
+ bad = [f for f in data.get('features', [])
93
+ if f.get('status') not in ('completed', 'skipped')]
94
+ print(len(bad))
95
+ ")
96
+ if [[ "$count" == "1" ]]; then
97
+ pass "incomplete_count=1, deploy blocked"
98
+ else
99
+ fail "incomplete_count=$count, expected 1"
100
+ fi
101
+
102
+ # --- Test 5: tee /dev/stderr | tail -1 pattern extracts only count ---
103
+ echo "[Test 5] Multi-line output extraction: only last line (integer) captured"
104
+ cat > /tmp/test-deploy-tee.json << 'JSON'
105
+ {"features": [{"id": "F-001", "status": "failed", "title": "Broken feature"}, {"id": "F-002", "status": "crashed", "title": "Also broken"}]}
106
+ JSON
107
+ result=$({ python3 -c "
108
+ import json
109
+ with open('/tmp/test-deploy-tee.json') as f:
110
+ data = json.load(f)
111
+ bad = [f for f in data.get('features', [])
112
+ if f.get('status') not in ('completed', 'skipped')]
113
+ for f in bad:
114
+ print(f\" {f['id']}: {f.get('status', 'unknown')} — {f.get('title', '')}\")
115
+ print(len(bad))
116
+ " /tmp/test-deploy-tee.json 2>/dev/null || echo "0"; } | tail -1)
117
+ if [[ "$result" =~ ^[0-9]+$ ]]; then
118
+ pass "extracted count is integer: $result"
119
+ else
120
+ fail "extracted count is not a clean integer: '$result'"
121
+ fi
122
+
123
+ # --- Test 6: Empty feature list -> deploy proceeds ---
124
+ echo "[Test 6] Empty list: incomplete_count should be 0"
125
+ cat > /tmp/test-deploy-empty.json << 'JSON'
126
+ {"features": []}
127
+ JSON
128
+ count=$(python3 -c "
129
+ import json
130
+ with open('/tmp/test-deploy-empty.json') as f:
131
+ data = json.load(f)
132
+ bad = [f for f in data.get('features', [])
133
+ if f.get('status') not in ('completed', 'skipped')]
134
+ print(len(bad))
135
+ ")
136
+ if [[ "$count" == "0" ]]; then
137
+ pass "incomplete_count=0, deploy proceeds"
138
+ else
139
+ fail "incomplete_count=$count, expected 0"
140
+ fi
141
+
142
+ # --- Test 7: Bugfix variant with needs_info (non-blocking) ---
143
+ echo "[Test 7] Bugfix: 'needs_info' should NOT block deploy"
144
+ cat > /tmp/test-deploy-bugfix.json << 'JSON'
145
+ {"bugs": [{"id": "B-001", "status": "completed"}, {"id": "B-002", "status": "needs_info"}]}
146
+ JSON
147
+ count=$(python3 -c "
148
+ import json
149
+ with open('/tmp/test-deploy-bugfix.json') as f:
150
+ data = json.load(f)
151
+ bad = [b for b in data.get('bugs', [])
152
+ if b.get('status') not in ('completed', 'skipped', 'needs_info')]
153
+ print(len(bad))
154
+ ")
155
+ if [[ "$count" == "0" ]]; then
156
+ pass "incomplete_count=0, deploy proceeds (needs_info non-blocking)"
157
+ else
158
+ fail "incomplete_count=$count, expected 0"
159
+ fi
160
+
161
+ # --- Test 8: Refactor variant ---
162
+ echo "[Test 8] Refactor: completed + skipped -> deploy proceeds"
163
+ cat > /tmp/test-deploy-refactor.json << 'JSON'
164
+ {"refactors": [{"id": "R-001", "status": "completed"}, {"id": "R-002", "status": "skipped"}]}
165
+ JSON
166
+ count=$(python3 -c "
167
+ import json
168
+ with open('/tmp/test-deploy-refactor.json') as f:
169
+ data = json.load(f)
170
+ bad = [r for r in data.get('refactors', [])
171
+ if r.get('status') not in ('completed', 'skipped')]
172
+ print(len(bad))
173
+ ")
174
+ if [[ "$count" == "0" ]]; then
175
+ pass "incomplete_count=0, deploy proceeds"
176
+ else
177
+ fail "incomplete_count=$count, expected 0"
178
+ fi
179
+
180
+ # --- Test 9: Real feature-list.json ---
181
+ echo "[Test 9] Real feature-list.json: both completed -> deploy proceeds"
182
+ if [[ -f "$REPO_ROOT/.prizmkit/plans/feature-list.json" ]]; then
183
+ count=$(python3 -c "
184
+ import json
185
+ with open('$REPO_ROOT/.prizmkit/plans/feature-list.json') as f:
186
+ data = json.load(f)
187
+ bad = [f for f in data.get('features', [])
188
+ if f.get('status') not in ('completed', 'skipped')]
189
+ print(len(bad))
190
+ ")
191
+ if [[ "$count" == "0" ]]; then
192
+ pass "real list: incomplete_count=0"
193
+ else
194
+ fail "real list: incomplete_count=$count, expected 0"
195
+ fi
196
+ else
197
+ echo " ${YELLOW}SKIP${NC} No real feature-list.json found"
198
+ fi
199
+
200
+ # --- Test 10: ENABLE_DEPLOY=0 skips the entire block ---
201
+ echo "[Test 10] ENABLE_DEPLOY=0: deploy block should be skipped entirely"
202
+ ENABLE_DEPLOY=0
203
+ executed=false
204
+ if [[ "$ENABLE_DEPLOY" == "1" ]]; then
205
+ executed=true
206
+ fi
207
+ if [[ "$executed" == "false" ]]; then
208
+ pass "ENABLE_DEPLOY=0: deploy block skipped"
209
+ else
210
+ fail "ENABLE_DEPLOY=0: deploy block should NOT execute"
211
+ fi
212
+
213
+ # --- Cleanup ---
214
+ rm -f /tmp/test-deploy-*.json
215
+
216
+ echo ""
217
+ echo "================================="
218
+ echo " Results: $PASS passed, $FAIL failed ($TOTAL total)"
219
+ echo "================================="
220
+
221
+ if [[ $FAIL -gt 0 ]]; then
222
+ exit 1
223
+ fi
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.1.40",
2
+ "version": "1.1.42",
3
3
  "skills": {
4
4
  "prizm-kit": {
5
5
  "description": "Full-lifecycle dev toolkit. Covers spec-driven development, Prizm context docs, code quality, debugging, deployment, and knowledge management.",
@@ -58,10 +58,10 @@
58
58
  "hasScripts": false
59
59
  },
60
60
  "prizmkit-deploy": {
61
- "description": "Generate or update deployment documentation (.prizmkit/deploy.md) by scanning project state and deploy strategy. On-demand skill.",
61
+ "description": "Universal deployment gateway: auto-discovers project type and target, routes to SSH automation (PM2 + Nginx + blue/green), guided cloud/Docker deployment, or documentation fallback. Also operates existing deployments (status/logs/restart/rollback).",
62
62
  "tier": "1",
63
63
  "category": "prizmkit-skill",
64
- "hasAssets": true,
64
+ "hasAssets": false,
65
65
  "hasScripts": false
66
66
  },
67
67
  "feature-workflow": {
@@ -37,7 +37,6 @@ If you believe the task is better suited for a different workflow, you MUST:
37
37
  1. `.prizmkit/plans/project-brief.md` (`.prizmkit/plans/` — accumulated project context brief)
38
38
  2. Project conventions and architecture decisions appended to `CLAUDE.md` / `CODEBUDDY.md` (with user consent)
39
39
  3. Infrastructure configuration (database conventions + deployment config) appended to `CLAUDE.md` / `CODEBUDDY.md` `### Infrastructure` section
40
- 4. `.prizmkit/deploy.md` — deployment documentation (created or updated with infrastructure config)
41
40
 
42
41
  **After planning is complete**, you MUST:
43
42
  1. Present the summary of captured project-level context (vision, conventions, architecture decisions, project brief)
@@ -199,7 +198,6 @@ Do NOT use this skill when:
199
198
  #### Deployment Credentials Reference
200
199
  - [platform]: [token/auth method description]
201
200
  ```
202
- - Update `.prizmkit/deploy.md` if it exists — append deployment details to relevant sections (Prerequisites, Production Deployment, Environment Variables). If it does not exist, create it from the `prizmkit-deploy` template with known information filled in.
203
201
  - Items still marked "Skip — decide later" remain as `<!-- [topic]: deferred -->` in CLAUDE.md for `prizmkit-deploy` to pick up later.
204
202
 
205
203
  4. **Project brief accumulation** — throughout all interactive phases:
@@ -443,7 +441,6 @@ After all checkpoints pass, present a summary and end the session:
443
441
  - Infrastructure config → `CLAUDE.md` / `CODEBUDDY.md` `### Infrastructure` (database conventions + deployment config)
444
442
  - Tech stack → `.prizmkit/config.json`
445
443
  - Architecture decisions (if any) → `CLAUDE.md` / `CODEBUDDY.md` `### Architecture Decisions`
446
- - Deployment docs → `.prizmkit/deploy.md` (if created/updated)
447
444
  - Project brief → `.prizmkit/plans/project-brief.md`
448
445
 
449
446
  2. **Suggest possible next steps** (as text, NOT auto-invoked):
@@ -121,6 +121,13 @@ Detect user intent from their message, then follow the corresponding workflow:
121
121
 
122
122
  5. **Ask configuration options** ⚠️ MANDATORY INTERACTIVE STEP — applies to ALL execution modes (Foreground, Background, AND Manual). You MUST ask the user to configure options and WAIT for their response BEFORE proceeding to step 6. Do NOT skip this step or merge it with step 6.
123
123
 
124
+ ⛔ **HARD STOP**: You MUST call `AskUserQuestion` with the questions below and WAIT for the user's response. You MUST NOT:
125
+ - Skip this step and jump to the next step
126
+ - Merge this step and the next step into one response
127
+ - Assume default values and show the command without asking
128
+ - Show the command as text and ask "ready?" without presenting the options
129
+ If you find yourself writing the final command before the user has answered these questions, STOP — you are violating this rule.
130
+
124
131
  Use `AskUserQuestion` to present the following configuration choices. Each question is a separate selectable option:
125
132
 
126
133
  **Question 1 — Verbose logging** (multiSelect: false):
@@ -154,6 +161,10 @@ Detect user intent from their message, then follow the corresponding workflow:
154
161
  - Off (default) — Pipeline continues to next task after failure
155
162
  - On — Pipeline halts immediately when a task exhausts all retries (`STOP_ON_FAILURE=1`)
156
163
 
164
+ **Question 3 — Deploy after completion?** (multiSelect: false):
165
+ - No (default) — Skip deployment after pipeline completes
166
+ - Yes — Run /prizmkit-deploy automatically after all bugs fixed successfully (`ENABLE_DEPLOY=1`). Deployment is blocked if any bug was not fixed (status not 'completed', 'skipped', or 'needs_info').
167
+
157
168
  **Environment variable mapping** (for translating user responses → env vars):
158
169
 
159
170
  | Config choice | Environment variable |
@@ -164,6 +175,7 @@ Detect user intent from their message, then follow the corresponding workflow:
164
175
  | Critic: On | `ENABLE_CRITIC=true` |
165
176
  | Timeout: value | `SESSION_TIMEOUT=<seconds>` |
166
177
  | Stop on failure: On | `STOP_ON_FAILURE=1` |
178
+ | Deploy: Yes | `ENABLE_DEPLOY=1` |
167
179
 
168
180
  **Advanced environment variables** (not exposed in interactive menu, pass via `--env`):
169
181
 
@@ -188,7 +200,7 @@ Detect user intent from their message, then follow the corresponding workflow:
188
200
  ```
189
201
  With all options:
190
202
  ```bash
191
- VERBOSE=1 MAX_RETRIES=5 SESSION_TIMEOUT=3600 \
203
+ VERBOSE=1 MAX_RETRIES=5 SESSION_TIMEOUT=3600 ENABLE_DEPLOY=1 \
192
204
  dev-pipeline/run-bugfix.sh run .prizmkit/plans/bug-fix-list.json
193
205
  ```
194
206
 
@@ -199,7 +211,7 @@ Detect user intent from their message, then follow the corresponding workflow:
199
211
  With all options:
200
212
  ```bash
201
213
  dev-pipeline/launch-bugfix-daemon.sh start .prizmkit/plans/bug-fix-list.json \
202
- --env "VERBOSE=1 MAX_RETRIES=5"
214
+ --env "VERBOSE=1 MAX_RETRIES=5 ENABLE_DEPLOY=1"
203
215
  ```
204
216
 
205
217
  **Manual mode**: Print the assembled command(s) and **stop here**. Do not execute anything. Do not proceed to step 7.
@@ -334,6 +346,7 @@ dev-pipeline/reset-bug.sh B-001 --clean --run .prizmkit/plans/bug-fix-list.json
334
346
  | All bugs blocked/failed/needs-info | Show status, suggest retrying or providing more info |
335
347
  | `playwright-cli` not installed | Browser verification skipped for playwright bugs (non-blocking). Suggest: `npm install -g @playwright/cli@latest && playwright-cli install --skills` |
336
348
  | `opencli` not installed | Browser verification skipped for opencli bugs (non-blocking). Install opencli for Chrome session-based browser verification |
349
+ | Deploy session failed | Pipeline completed but deploy session exited non-zero. Check `.prizmkit/state/bugfix/deploy/<session_id>/logs/session.log`. Retry manually: `/prizmkit-deploy`. |
337
350
  | Permission denied on script | Run `chmod +x dev-pipeline/launch-bugfix-daemon.sh dev-pipeline/run-bugfix.sh` |
338
351
 
339
352
  ### Integration Notes
@@ -138,6 +138,13 @@ Detect user intent from their message, then follow the corresponding workflow:
138
138
 
139
139
  6. **Ask configuration options** ⚠️ MANDATORY INTERACTIVE STEP — applies to ALL execution modes (Foreground, Background, AND Manual). You MUST ask the user to configure options and WAIT for their response BEFORE proceeding to step 7. Do NOT skip this step or merge it with step 7.
140
140
 
141
+ ⛔ **HARD STOP**: You MUST call `AskUserQuestion` with the 4 questions below and WAIT for the user's response. You MUST NOT:
142
+ - Skip this step and jump to step 7
143
+ - Merge step 6 and step 7 into one response
144
+ - Assume default values and show the command without asking
145
+ - Show the command as text and ask "ready?" without presenting the options
146
+ If you find yourself writing the final command before the user has answered these questions, STOP — you are violating this rule.
147
+
141
148
  Use `AskUserQuestion` to present the following configuration choices. Each question is a separate selectable option:
142
149
 
143
150
  **Question 1 — Critic review** (multiSelect: false):
@@ -173,6 +180,10 @@ Detect user intent from their message, then follow the corresponding workflow:
173
180
  - Off (default) — Pipeline continues to next task after failure
174
181
  - On — Pipeline halts immediately when a task exhausts all retries (`STOP_ON_FAILURE=1`)
175
182
 
183
+ **Question 3 — Deploy after completion?** (multiSelect: false):
184
+ - No (default) — Skip deployment after pipeline completes
185
+ - Yes — Run /prizmkit-deploy automatically after all features complete successfully (`ENABLE_DEPLOY=1`). Deployment is blocked if any feature did not complete successfully (status not 'completed' or manually 'skipped').
186
+
176
187
  **Environment variable mapping** (for translating user responses → env vars):
177
188
 
178
189
  | Config choice | Environment variable |
@@ -183,6 +194,7 @@ Detect user intent from their message, then follow the corresponding workflow:
183
194
  | Max retries: N | `MAX_RETRIES=N` |
184
195
  | Timeout: value | `SESSION_TIMEOUT=<seconds>` |
185
196
  | Stop on failure: On | `STOP_ON_FAILURE=1` |
197
+ | Deploy: Yes | `ENABLE_DEPLOY=1` |
186
198
 
187
199
  **Advanced environment variables** (not exposed in interactive menu, pass via `--env`):
188
200
 
@@ -208,7 +220,7 @@ Detect user intent from their message, then follow the corresponding workflow:
208
220
  ```
209
221
  With all options:
210
222
  ```bash
211
- VERBOSE=1 ENABLE_CRITIC=true MAX_RETRIES=5 SESSION_TIMEOUT=3600 \
223
+ VERBOSE=1 ENABLE_CRITIC=true MAX_RETRIES=5 SESSION_TIMEOUT=3600 ENABLE_DEPLOY=1 \
212
224
  dev-pipeline/run-feature.sh run .prizmkit/plans/feature-list.json --features F-001:F-005
213
225
  ```
214
226
 
@@ -219,7 +231,7 @@ Detect user intent from their message, then follow the corresponding workflow:
219
231
  With all options:
220
232
  ```bash
221
233
  dev-pipeline/launch-feature-daemon.sh start .prizmkit/plans/feature-list.json --features F-001:F-005 \
222
- --env "VERBOSE=1 ENABLE_CRITIC=true MAX_RETRIES=5"
234
+ --env "VERBOSE=1 ENABLE_CRITIC=true MAX_RETRIES=5 ENABLE_DEPLOY=1"
223
235
  ```
224
236
 
225
237
  **Manual mode**: Print the assembled command(s) and **stop here**. Do not execute anything. Do not proceed to step 8.
@@ -399,6 +411,7 @@ After pipeline completion, if features have `browser_interaction` fields and the
399
411
  | `opencli` not installed | Browser verification skipped for opencli features (non-blocking). Install opencli for Chrome session-based browser verification |
400
412
  | Permission denied on script | Run `chmod +x dev-pipeline/launch-feature-daemon.sh dev-pipeline/run-feature.sh` |
401
413
  | Pipeline stop failed (process won't die) | Process may be stuck in I/O wait. Try `kill -9 <PID>` manually. Check for orphaned child processes with `ps aux \| grep claude` |
414
+ | Deploy session failed | Pipeline completed but deploy session exited non-zero. Check `.prizmkit/state/features/deploy/<session_id>/logs/session.log`. Retry manually: `/prizmkit-deploy`. |
402
415
  | `.env.local` missing or incomplete | Warn: database connection variables not found. Suggest creating env file with required connection variables for the project's database |
403
416
  | Database unreachable | Warn: database features will produce mock-only tests. Suggest checking database service status and connection credentials |
404
417
  | Migrations not applied | Warn: tables or schema referenced in migration files not found in database. Suggest applying pending migrations |
@@ -17,7 +17,6 @@ description: "Pure git commit workflow with safety checks. Stages files, generat
17
17
  | Uncommitted changes exist | `git status` shows modified/added/untracked files | Inform user "nothing to commit" and stop |
18
18
  | `.prizm-docs/` synced (feature/refactor) | `/prizmkit-retrospective` has run | Run `/prizmkit-retrospective` first |
19
19
  | Code review passed (pipeline mode) | `review-report.md` in artifact directory has `## Verdict: PASS` | Run `/prizmkit-code-review` first |
20
- | `.prizmkit/deploy.md` updated (if applicable) | If `/prizmkit-deploy` ran, `.prizmkit/deploy.md` is staged | Run `/prizmkit-deploy` or skip if no infrastructure changes |
21
20
 
22
21
  ### Workflow
23
22
 
@@ -67,6 +66,8 @@ Ask user: "Push to remote?"
67
66
  - Yes: `git push`
68
67
  - No: Stop
69
68
 
69
+ **Headless mode**: If the skill was invoked with `--headless` in the args (e.g., `/prizmkit-committer --headless feat(F-001): ...`), **SKIP this step entirely**. Do NOT ask the question. Do NOT push. Stop after Step 5 verification. Headless mode is used by autonomous pipeline sessions where there is no human to answer interactive prompts.
70
+
70
71
  ## Example
71
72
 
72
73
  **Feature commit:**