@pareto4/pp-core 1.18.0 → 1.20.0

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 (194) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/agents/pp-code-fixer.md +9 -5
  3. package/agents/pp-code-reviewer.md +1 -0
  4. package/agents/pp-codebase-mapper.md +3 -0
  5. package/agents/pp-debugger.md +3 -2
  6. package/agents/pp-executor.md +16 -7
  7. package/agents/pp-integration-checker.md +1 -0
  8. package/agents/pp-phase-researcher.md +13 -1
  9. package/agents/pp-plan-checker.md +3 -0
  10. package/agents/pp-planner.md +20 -1
  11. package/agents/pp-research-synthesizer.md +1 -1
  12. package/agents/pp-ui-auditor.md +1 -0
  13. package/agents/pp-ui-researcher.md +3 -1
  14. package/agents/pp-vault-reviewer.md +2 -0
  15. package/agents/pp-verifier.md +22 -10
  16. package/commands/pp-add-tests.md +1 -1
  17. package/commands/pp-debug.md +1 -0
  18. package/commands/pp-discovery.md +3 -2
  19. package/commands/pp-init.md +4 -3
  20. package/commands/pp-quick.md +3 -0
  21. package/commands/pp-review-backlog.md +2 -1
  22. package/gemini-extension.json +1 -1
  23. package/package.json +6 -3
  24. package/pareto-skills/_shared/pp-claude-md-protocol.md +1 -1
  25. package/pareto-skills/pp-project-setup/SKILL.md +18 -343
  26. package/pp-core/bin/lib/capability-registry.cjs +3 -3
  27. package/pp-core/bin/lib/check-command-router.cjs +60 -20
  28. package/pp-core/bin/lib/commands.cjs +79 -4
  29. package/pp-core/bin/lib/compose-bindings.cjs +97 -14
  30. package/pp-core/bin/lib/discovery-access.cjs +276 -0
  31. package/pp-core/bin/lib/discovery-charter.cjs +664 -0
  32. package/pp-core/bin/lib/discovery-deviations.cjs +264 -0
  33. package/pp-core/bin/lib/discovery-entities.cjs +323 -0
  34. package/pp-core/bin/lib/discovery-for-phase.cjs +628 -0
  35. package/pp-core/bin/lib/discovery-integrations.cjs +286 -0
  36. package/pp-core/bin/lib/discovery-migration.cjs +246 -0
  37. package/pp-core/bin/lib/discovery-phases.cjs +233 -0
  38. package/pp-core/bin/lib/discovery-processes.cjs +355 -0
  39. package/pp-core/bin/lib/discovery-research-track.cjs +5 -4
  40. package/pp-core/bin/lib/discovery-rollup.cjs +12 -8
  41. package/pp-core/bin/lib/discovery-rules.cjs +216 -0
  42. package/pp-core/bin/lib/discovery-screens.cjs +21 -3
  43. package/pp-core/bin/lib/discovery-session-check.cjs +264 -0
  44. package/pp-core/bin/lib/discovery-stories.cjs +273 -0
  45. package/pp-core/bin/lib/discovery-sweep.cjs +13 -4
  46. package/pp-core/bin/lib/discovery-table.cjs +55 -0
  47. package/pp-core/bin/lib/discovery-vault-check.cjs +37 -3
  48. package/pp-core/bin/lib/init-contract.cjs +48 -7
  49. package/pp-core/bin/lib/io.cjs +22 -0
  50. package/pp-core/bin/lib/vault-coordinates.cjs +1 -1
  51. package/pp-core/bin/lib/vault-index.cjs +18 -5
  52. package/pp-core/bin/lib/vault-standards-review.cjs +50 -2
  53. package/pp-core/bin/lib/vault-update.cjs +4 -0
  54. package/pp-core/bin/lib/vault.cjs +2 -2
  55. package/pp-core/bin/pp-tools.cjs +153 -5
  56. package/pp-core/org-profile.json +1 -1
  57. package/pp-core/references/autonomous-best-effort.md +3 -2
  58. package/pp-core/references/autonomous-lifecycle.md +1 -0
  59. package/pp-core/references/autonomous-smart-discuss.md +5 -1
  60. package/pp-core/references/discovery-access.md +112 -0
  61. package/pp-core/references/discovery-build-consumption.md +256 -0
  62. package/pp-core/references/discovery-charter.md +127 -0
  63. package/pp-core/references/discovery-data-model.md +145 -0
  64. package/pp-core/references/discovery-id-conventions.md +77 -8
  65. package/pp-core/references/discovery-integrations.md +151 -0
  66. package/pp-core/references/discovery-processes.md +190 -0
  67. package/pp-core/references/discovery-rebaseline.md +2 -2
  68. package/pp-core/references/discovery-research-track.md +5 -6
  69. package/pp-core/references/discovery-session-output.md +70 -0
  70. package/pp-core/references/discovery-standards.md +107 -0
  71. package/pp-core/references/discovery-traceability.md +2 -2
  72. package/pp-core/references/execute-mvp-tdd.md +3 -3
  73. package/pp-core/references/git-integration.md +57 -33
  74. package/pp-core/references/git-planning-commit.md +31 -9
  75. package/pp-core/references/phase-argument-parsing.md +1 -0
  76. package/pp-core/references/planner-discovery-extract.md +35 -0
  77. package/pp-core/references/planner-gap-closure.md +1 -0
  78. package/pp-core/references/planner-revision.md +3 -1
  79. package/pp-core/references/planner-tdd.md +4 -4
  80. package/pp-core/references/planning-config.md +3 -3
  81. package/pp-core/references/shell-portability.md +28 -0
  82. package/pp-core/references/tdd.md +20 -16
  83. package/pp-core/references/verifier-discovery-conformance.md +36 -0
  84. package/pp-core/references/worktree-path-safety.md +1 -0
  85. package/pp-core/templates/milestone.md +5 -5
  86. package/pp-core/templates/project-charter.md +161 -100
  87. package/pp-core/templates/project.md +3 -3
  88. package/pp-core/templates/requirements.md +18 -0
  89. package/pp-core/templates/verification-report.md +16 -0
  90. package/pp-core/workflows/add-backlog.md +1 -1
  91. package/pp-core/workflows/add-tests.md +5 -2
  92. package/pp-core/workflows/add-todo.md +3 -1
  93. package/pp-core/workflows/ai-integration-phase.md +2 -1
  94. package/pp-core/workflows/audit-fix.md +4 -3
  95. package/pp-core/workflows/audit-milestone.md +1 -0
  96. package/pp-core/workflows/autonomous.md +6 -0
  97. package/pp-core/workflows/check-todos.md +2 -1
  98. package/pp-core/workflows/cleanup.md +3 -1
  99. package/pp-core/workflows/code-review-fix.md +12 -5
  100. package/pp-core/workflows/code-review.md +15 -1
  101. package/pp-core/workflows/complete-milestone.md +13 -3
  102. package/pp-core/workflows/debug.md +2 -0
  103. package/pp-core/workflows/diagnose-issues.md +1 -1
  104. package/pp-core/workflows/discovery-sprint/charter.md +114 -0
  105. package/pp-core/workflows/discovery-sprint/prefill.md +1 -1
  106. package/pp-core/workflows/discovery-sprint/prototype.md +4 -4
  107. package/pp-core/workflows/discovery-sprint/session-13-gates.md +11 -1
  108. package/pp-core/workflows/discovery-sprint/sessions/01-kick-off.md +54 -7
  109. package/pp-core/workflows/discovery-sprint/sessions/02-as-is.md +31 -7
  110. package/pp-core/workflows/discovery-sprint/sessions/03-to-be.md +64 -37
  111. package/pp-core/workflows/discovery-sprint/sessions/04-ux-design.md +12 -3
  112. package/pp-core/workflows/discovery-sprint/sessions/05-architecture.md +45 -22
  113. package/pp-core/workflows/discovery-sprint/sessions/06-security.md +30 -15
  114. package/pp-core/workflows/discovery-sprint/sessions/07-identity.md +43 -25
  115. package/pp-core/workflows/discovery-sprint/sessions/08-integration.md +63 -24
  116. package/pp-core/workflows/discovery-sprint/sessions/09-qa.md +28 -13
  117. package/pp-core/workflows/discovery-sprint/sessions/10-infrastructure.md +35 -16
  118. package/pp-core/workflows/discovery-sprint/sessions/11-roadmap.md +32 -8
  119. package/pp-core/workflows/discovery-sprint/sessions/12-delivery-model.md +21 -18
  120. package/pp-core/workflows/discovery-sprint/sessions/13-wrap-up.md +29 -12
  121. package/pp-core/workflows/discovery-sprint/vault-context.md +14 -3
  122. package/pp-core/workflows/discovery-sprint.md +23 -23
  123. package/pp-core/workflows/discovery-to-build/steps/architecture-deliverables.md +81 -29
  124. package/pp-core/workflows/discovery-to-build/steps/{screen-inventory-gate.md → handoff-gates.md} +111 -3
  125. package/pp-core/workflows/discovery-to-build/templates/discovery-references.md +12 -9
  126. package/pp-core/workflows/discovery-to-build/templates/pp-handoff.md +27 -26
  127. package/pp-core/workflows/discovery-to-build.md +70 -34
  128. package/pp-core/workflows/discuss-phase/discovery.md +83 -0
  129. package/pp-core/workflows/discuss-phase/templates/context.md +4 -0
  130. package/pp-core/workflows/discuss-phase-assumptions.md +5 -3
  131. package/pp-core/workflows/discuss-phase.md +18 -10
  132. package/pp-core/workflows/docs-update.md +1 -0
  133. package/pp-core/workflows/eval-review.md +2 -1
  134. package/pp-core/workflows/execute-phase/steps/check-query-gate.md +7 -6
  135. package/pp-core/workflows/execute-phase/steps/cross-ai-delegation.md +1 -0
  136. package/pp-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +1 -0
  137. package/pp-core/workflows/execute-phase/steps/vault-fetch.md +12 -0
  138. package/pp-core/workflows/execute-phase.md +19 -7
  139. package/pp-core/workflows/execute-plan.md +18 -7
  140. package/pp-core/workflows/explore.md +1 -1
  141. package/pp-core/workflows/forensics.md +4 -2
  142. package/pp-core/workflows/health.md +1 -0
  143. package/pp-core/workflows/import.md +2 -1
  144. package/pp-core/workflows/ingest-docs.md +1 -0
  145. package/pp-core/workflows/init/steps/client-context-capture.md +1 -0
  146. package/pp-core/workflows/init/steps/github-provisioning.md +145 -0
  147. package/pp-core/workflows/init/steps/gitlab-provisioning.md +18 -4
  148. package/pp-core/workflows/init/steps/reachability-outcome.md +3 -1
  149. package/pp-core/workflows/init.md +56 -66
  150. package/pp-core/workflows/map-codebase.md +5 -1
  151. package/pp-core/workflows/milestone-summary.md +2 -1
  152. package/pp-core/workflows/mvp-phase.md +1 -0
  153. package/pp-core/workflows/new-milestone.md +9 -5
  154. package/pp-core/workflows/new-project.md +12 -11
  155. package/pp-core/workflows/new-workspace.md +1 -0
  156. package/pp-core/workflows/next.md +2 -1
  157. package/pp-core/workflows/pause-work.md +6 -4
  158. package/pp-core/workflows/plan-milestone-gaps.md +3 -1
  159. package/pp-core/workflows/plan-phase/steps/chunked-planning.md +1 -1
  160. package/pp-core/workflows/plan-phase/steps/discovery-extract.md +41 -0
  161. package/pp-core/workflows/plan-phase.md +36 -16
  162. package/pp-core/workflows/plan-review-convergence.md +2 -0
  163. package/pp-core/workflows/plant-seed.md +4 -2
  164. package/pp-core/workflows/pr-branch.md +2 -0
  165. package/pp-core/workflows/progress.md +5 -0
  166. package/pp-core/workflows/quick.md +11 -4
  167. package/pp-core/workflows/reapply-patches.md +3 -0
  168. package/pp-core/workflows/remove-phase.md +1 -1
  169. package/pp-core/workflows/resume-project.md +3 -0
  170. package/pp-core/workflows/review.md +7 -1
  171. package/pp-core/workflows/secure-phase.md +2 -1
  172. package/pp-core/workflows/session-report.md +1 -0
  173. package/pp-core/workflows/ship.md +8 -1
  174. package/pp-core/workflows/sketch-wrap-up.md +1 -1
  175. package/pp-core/workflows/sketch.md +3 -2
  176. package/pp-core/workflows/spec-phase.md +2 -1
  177. package/pp-core/workflows/spike-wrap-up.md +1 -1
  178. package/pp-core/workflows/spike.md +4 -3
  179. package/pp-core/workflows/sync-skills.md +5 -2
  180. package/pp-core/workflows/thread.md +3 -2
  181. package/pp-core/workflows/transition.md +6 -0
  182. package/pp-core/workflows/ui-phase.md +3 -1
  183. package/pp-core/workflows/ui-review.md +2 -1
  184. package/pp-core/workflows/ultraplan-phase.md +1 -0
  185. package/pp-core/workflows/undo.md +14 -10
  186. package/pp-core/workflows/update.md +5 -0
  187. package/pp-core/workflows/validate-phase.md +6 -3
  188. package/pp-core/workflows/vault-review.md +7 -1
  189. package/pp-core/workflows/vault-write-back.md +5 -0
  190. package/pp-core/workflows/verify-phase.md +5 -0
  191. package/pp-core/workflows/verify-work.md +8 -1
  192. package/scripts/prompt-injection-scan.sh +1 -1
  193. package/scripts/sync-runtime-launcher.cjs +115 -5
  194. package/pp-core/workflows/discovery-sprint/templates/context-template.md +0 -266
@@ -84,6 +84,7 @@ gate on the `execute:pre` payload, filtered in the fence to the `vault`
84
84
  capability (D-30):
85
85
 
86
86
  ```bash
87
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
87
88
  AT_EXECUTE_PRE_HOOKS_JSON=$(pp_run loop render-hooks execute:pre --raw | node -e "const d=require('fs').readFileSync(0,'utf-8');try{const j=JSON.parse(d);j.activeHooks=(j.activeHooks||[]).filter((x)=>x&&x.capId==='vault');process.stdout.write(JSON.stringify(j));}catch{process.stdout.write('');}")
88
89
  printf '%s' "$AT_EXECUTE_PRE_HOOKS_JSON" | node -e "let h=[];try{h=JSON.parse(require('fs').readFileSync(0,'utf-8')).activeHooks||[]}catch{}console.log('AT_EXECUTE_PRE_HOOKS_JSON='+JSON.stringify({activeHooks:h}))"
89
90
  ```
@@ -186,6 +187,7 @@ If user selects "Cancel": exit gracefully.
186
187
  Before generating the test plan, discover the project's existing test structure:
187
188
 
188
189
  ```bash
190
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
189
191
  # Find existing test directories
190
192
  find . -type d -name "*test*" -o -name "*spec*" -o -name "*__tests__*" 2>/dev/null | head -20
191
193
  # Find existing test files for convention matching
@@ -349,7 +351,8 @@ If there are passing tests to commit:
349
351
 
350
352
  ```bash
351
353
  git add {test files}
352
- git commit -m "test(phase-${phase_number}): add unit and E2E tests from add-tests command"
354
+ # {area}: the part of the codebase the tests cover; drop "({area})" when no single area fits
355
+ git commit -m "test({area}): add unit and E2E tests from add-tests command" -m "Phase: ${padded_phase}"
353
356
  ```
354
357
 
355
358
  Vault door record (D-12): after the door's last source commit, set `DOOR_DIR="${phase_dir}"`,
@@ -364,7 +367,7 @@ The verb writes a `## Vault Door Record` (mode, vault ref and sha, governing pha
364
367
  recorded and the end commit; the agent never types a sha) into a fresh per-run artifact, because it refuses a second record
365
368
  in one file (D-57) and a rewritten report would drop the earlier run's coverage (D-79). It prints
366
369
  nothing and writes nothing unless `vault admission` answers `on`. When it wrote the file and
367
- `commit_docs` is true, commit the `artifact` path it printed: `pp_run query commit "docs(phase-${phase_number}): vault door record for add-tests" --files "<that artifact>"`.
370
+ `commit_docs` is true, commit the `artifact` path it printed: `pp_run query commit "docs(planning): vault door record for add-tests" --phase "${padded_phase}" --files "<that artifact>"`.
368
371
 
369
372
  Present next steps:
370
373
 
@@ -63,6 +63,7 @@ Use existing area from step 2 if similar match exists.
63
63
 
64
64
  <step name="check_duplicates">
65
65
  ```bash
66
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
66
67
  # Search for key words from title in existing todos
67
68
  grep -l -i "[key words from title]" .planning/todos/pending/*.md 2>/dev/null || true
68
69
  ```
@@ -122,7 +123,8 @@ If `.planning/STATE.md` exists:
122
123
  Commit the todo and any updated state:
123
124
 
124
125
  ```bash
125
- pp_run query commit "docs: capture todo - [title]" --files .planning/todos/pending/[filename] .planning/STATE.md
126
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
127
+ pp_run query commit "docs(planning): capture todo - [title]" --files .planning/todos/pending/[filename] .planning/STATE.md
126
128
  ```
127
129
 
128
130
  Tool respects `commit_docs` config and gitignore automatically.
@@ -73,6 +73,7 @@ Continue (non-blocking).
73
73
  ## 4. Check Existing AI-SPEC
74
74
 
75
75
  ```bash
76
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
76
77
  AI_SPEC_FILE=$(ls "${PHASE_DIR}"/*-AI-SPEC.md 2>/dev/null | head -1)
77
78
  ```
78
79
 
@@ -259,7 +260,7 @@ Read the completed AI-SPEC.md. Check that:
259
260
  **If `commit_docs` is true:**
260
261
  ```bash
261
262
  git add "${AI_SPEC_FILE}"
262
- git commit -m "docs({phase_slug}): generate AI-SPEC.md — {primary_framework} + domain context + eval strategy"
263
+ git commit -m "docs(planning): generate AI-SPEC.md — {primary_framework} + domain context + eval strategy" -m "Phase: {padded_phase}"
263
264
  ```
264
265
 
265
266
  ## 12. Display Completion
@@ -110,6 +110,7 @@ gate on the `execute:pre` payload, filtered in the fence to the `vault`
110
110
  capability (D-30):
111
111
 
112
112
  ```bash
113
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
113
114
  AF_EXECUTE_PRE_HOOKS_JSON=$(pp_run loop render-hooks execute:pre --raw | node -e "const d=require('fs').readFileSync(0,'utf-8');try{const j=JSON.parse(d);j.activeHooks=(j.activeHooks||[]).filter((x)=>x&&x.capId==='vault');process.stdout.write(JSON.stringify(j));}catch{process.stdout.write('');}")
114
115
  printf '%s' "$AF_EXECUTE_PRE_HOOKS_JSON" | node -e "let h=[];try{h=JSON.parse(require('fs').readFileSync(0,'utf-8')).activeHooks||[]}catch{}console.log('AF_EXECUTE_PRE_HOOKS_JSON='+JSON.stringify({activeHooks:h}))"
115
116
  ```
@@ -168,9 +169,9 @@ fi
168
169
  **c. If tests pass** — commit atomically:
169
170
  ```bash
170
171
  git add {changed_files}
171
- git commit -m "fix({scope}): resolve {ID} — {description}"
172
+ git commit -m "fix({area}): resolve {ID} — {description}"
172
173
  ```
173
- The commit message **must** include the finding ID (e.g., F-01) for traceability.
174
+ `{area}` names the part of the codebase the fix touches (`auth`, `billing`); omit `({area})` when no single area fits. The commit message **must** include the finding ID (e.g., F-01) for traceability.
174
175
 
175
176
  **d. If tests fail** — revert changes, mark finding as `fix-failed`, and **stop the pipeline**:
176
177
  ```bash
@@ -200,7 +201,7 @@ The verb writes a `## Vault Door Record` (mode, vault ref and sha, governing pha
200
201
  recorded and the end commit; the agent never types a sha) into a fresh per-run artifact, because it refuses a second record
201
202
  in one file (D-57) and a rewritten report would drop the earlier run's coverage (D-79). It prints
202
203
  nothing and writes nothing unless `vault admission` answers `on`. When it wrote the file and
203
- `commit_docs` is true, commit the `artifact` path it printed: `pp_run query commit "docs: vault door record for audit-fix" --files "<that artifact>"`.
204
+ `commit_docs` is true, commit the `artifact` path it printed: `pp_run query commit "docs(planning): vault door record for audit-fix" --files "<that artifact>"`.
204
205
  </step>
205
206
 
206
207
  <step name="report">
@@ -116,6 +116,7 @@ For each phase's VERIFICATION.md, extract the expanded requirements table:
116
116
 
117
117
  For each phase's SUMMARY.md, extract `requirements-completed` from YAML frontmatter:
118
118
  ```bash
119
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
119
120
  for summary in .planning/phases/*-*/*-SUMMARY.md; do
120
121
  [ -e "$summary" ] || continue
121
122
  pp_run query summary-extract "$summary" --fields requirements_completed --pick requirements_completed
@@ -189,6 +189,7 @@ Set `FIRST_PHASE` to the first remaining phase's number, derive `RUN_STATE` per
189
189
  **Fetch details for each phase:**
190
190
 
191
191
  ```bash
192
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
192
193
  DETAIL=$(pp_run query roadmap.get-phase ${PHASE_NUM})
193
194
  ```
194
195
 
@@ -217,6 +218,7 @@ Banner math (N, T, P and the N > T fallback): reference § Banner math.
217
218
  Check if CONTEXT.md already exists for this phase:
218
219
 
219
220
  ```bash
221
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
220
222
  PHASE_STATE=$(pp_run query init.phase-op ${PHASE_NUM})
221
223
  ```
222
224
 
@@ -262,6 +264,7 @@ Skill(skill="pp-discuss-phase", args="${PHASE_NUM}")
262
264
  After discuss completes (either mode), verify context was written:
263
265
 
264
266
  ```bash
267
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
265
268
  PHASE_STATE=$(pp_run query init.phase-op ${PHASE_NUM})
266
269
  ```
267
270
 
@@ -281,6 +284,7 @@ case "$VAULT_ADMIT" in on) echo "VAULT_ADMIT=on" ;; off|inert) : ;; *) pp_run va
281
284
  Resolve active `plan:pre` hooks:
282
285
 
283
286
  ```bash
287
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
284
288
  UI_SPEC_FILE=$(ls "${PHASE_DIR}"/*-UI-SPEC.md 2>/dev/null | head -1)
285
289
  HOOKS_JSON=$(pp_run loop render-hooks plan:pre --raw)
286
290
  printf '%s' "$HOOKS_JSON" | node -e "let h=[];try{h=JSON.parse(require('fs').readFileSync(0,'utf-8')).activeHooks||[]}catch{}console.log('HOOKS_JSON='+JSON.stringify({activeHooks:h}))"
@@ -350,6 +354,7 @@ Skill(skill="pp-${ref.skill}", args="${PHASE_NUM}")
350
354
  After all step hooks return, re-read:
351
355
 
352
356
  ```bash
357
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
353
358
  UI_SPEC_FILE=$(ls "${PHASE_DIR}"/*-UI-SPEC.md 2>/dev/null | head -1)
354
359
  ```
355
360
 
@@ -554,6 +559,7 @@ Route the new status through A-3 (passed → `OUTCOME=passed`; human_needed →
554
559
  Resolve the active post-verification hooks and the UI-SPEC gate:
555
560
 
556
561
  ```bash
562
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
557
563
  UI_SPEC_FILE=$(ls "${PHASE_DIR}"/*-UI-SPEC.md 2>/dev/null | head -1)
558
564
  HOOKS_JSON=$(pp_run loop render-hooks verify:post --raw)
559
565
  ```
@@ -168,8 +168,9 @@ Re-run `init todos` to get updated count, then update STATE.md "### Pending Todo
168
168
  If todo was moved to done/, commit the change:
169
169
 
170
170
  ```bash
171
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
171
172
  git rm --cached .planning/todos/pending/[filename] 2>/dev/null || true
172
- pp_run query commit "docs: start work on todo - [title]" --files .planning/todos/completed/[filename] .planning/STATE.md
173
+ pp_run query commit "docs(planning): start work on todo - [title]" --files .planning/todos/completed/[filename] .planning/STATE.md
173
174
  ```
174
175
 
175
176
  Tool respects `commit_docs` config and gitignore automatically.
@@ -27,6 +27,7 @@ Extract each milestone version (e.g., v1.0, v1.1, v2.0).
27
27
  Check which milestone archive dirs already exist:
28
28
 
29
29
  ```bash
30
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
30
31
  ls -d .planning/milestones/v*-phases 2>/dev/null || true
31
32
  ```
32
33
 
@@ -55,6 +56,7 @@ Extract phase numbers and names from the archived roadmap (e.g., Phase 1: Founda
55
56
  Check which of those phase directories still exist in `.planning/phases/`:
56
57
 
57
58
  ```bash
59
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
58
60
  ls -d .planning/phases/*/ 2>/dev/null || true
59
61
  ```
60
62
 
@@ -162,7 +164,7 @@ Commit the changes:
162
164
 
163
165
  ```bash
164
166
  _PP_SHIM_NAME="pp-tools.cjs"; _pp_root() { ( for _v in $(env | sed -n 's/^\(GIT_[A-Za-z0-9_]*\)=.*/\1/p'); do unset "$_v"; done; _c=$(git rev-parse --git-common-dir 2>/dev/null); if [ "${_c##*/}" = .git ] && cd "$_c/.." 2>/dev/null; then pwd -P; else git rev-parse --show-toplevel 2>/dev/null || pwd; fi ); }; pp_run() { case "$PP_TOOLS" in *.cjs) node "$PP_TOOLS" "$@";; *) "$PP_TOOLS" "$@";; esac; }; _PP_RUNTIME_ROOT="${RUNTIME_DIR:-$(_pp_root)}"; PP_TOOLS="${_PP_RUNTIME_ROOT}/pp-core/bin/${_PP_SHIM_NAME}"; if [ -f "$PP_TOOLS" ]; then :; elif [ -f "${_PP_RUNTIME_ROOT}/.claude/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${_PP_RUNTIME_ROOT}/.claude/pp-core/bin/${_PP_SHIM_NAME}"; elif [ -f "${_PP_RUNTIME_ROOT}/.codex/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${_PP_RUNTIME_ROOT}/.codex/pp-core/bin/${_PP_SHIM_NAME}"; elif [ -f "$HOME/.claude/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="$HOME/.claude/pp-core/bin/${_PP_SHIM_NAME}"; elif [ -f "${HERMES_HOME:-$HOME/.hermes}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${HERMES_HOME:-$HOME/.hermes}/pp-core/bin/${_PP_SHIM_NAME}"; elif [ -f "${CURSOR_CONFIG_DIR:-$HOME/.cursor}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${CURSOR_CONFIG_DIR:-$HOME/.cursor}/pp-core/bin/${_PP_SHIM_NAME}"; elif [ -f "${CODEX_HOME:-$HOME/.codex}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${CODEX_HOME:-$HOME/.codex}/pp-core/bin/${_PP_SHIM_NAME}"; elif [ -f "${GEMINI_CONFIG_DIR:-$HOME/.gemini}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${GEMINI_CONFIG_DIR:-$HOME/.gemini}/pp-core/bin/${_PP_SHIM_NAME}"; elif [ -f "${COPILOT_CONFIG_DIR:-$HOME/.copilot}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${COPILOT_CONFIG_DIR:-$HOME/.copilot}/pp-core/bin/${_PP_SHIM_NAME}"; elif [ -f "${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/pp-core/bin/${_PP_SHIM_NAME}"; elif [ -f "${AUGMENT_CONFIG_DIR:-$HOME/.augment}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${AUGMENT_CONFIG_DIR:-$HOME/.augment}/pp-core/bin/${_PP_SHIM_NAME}"; elif [ -f "${TRAE_CONFIG_DIR:-$HOME/.trae}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${TRAE_CONFIG_DIR:-$HOME/.trae}/pp-core/bin/${_PP_SHIM_NAME}"; elif [ -f "${QWEN_CONFIG_DIR:-$HOME/.qwen}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${QWEN_CONFIG_DIR:-$HOME/.qwen}/pp-core/bin/${_PP_SHIM_NAME}"; elif [ -f "${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/pp-core/bin/${_PP_SHIM_NAME}"; elif [ -f "${CLINE_CONFIG_DIR:-$HOME/.cline}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${CLINE_CONFIG_DIR:-$HOME/.cline}/pp-core/bin/${_PP_SHIM_NAME}"; elif [ -f "${GROK_AGENTS_HOME:-$HOME/.agents}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${GROK_AGENTS_HOME:-$HOME/.agents}/pp-core/bin/${_PP_SHIM_NAME}"; elif [ -f "${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/pp-core/bin/${_PP_SHIM_NAME}"; elif [ -f "${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/pp-core/bin/${_PP_SHIM_NAME}"; elif [ -f "${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/pp-core/bin/${_PP_SHIM_NAME}"; elif command -v pp-tools >/dev/null 2>&1; then PP_TOOLS="$(command -v pp-tools)"; else echo "ERROR: pp-tools.cjs not found at $PP_TOOLS and pp-tools is not on PATH. Run: npx -y @pareto4/pp-core@latest --claude --local" >&2; exit 1; fi; if [ -n "${CLAUDE_ENV_FILE:-}" ] && [ -n "${PP_TOOLS:-}" ]; then printf "export PATH='%s':\"\$PATH\"\n" "${PP_TOOLS%/*}" >> "$CLAUDE_ENV_FILE" 2>/dev/null || true; fi
165
- pp_run query commit "chore: archive phase directories from completed milestones" --files .planning/milestones/ .planning/phases/
167
+ pp_run query commit "chore(planning): archive phase directories from completed milestones" --files .planning/milestones/ .planning/phases/
166
168
  ```
167
169
 
168
170
  </step>
@@ -110,6 +110,7 @@ Do NOT auto-run code-review. Require explicit user action to ensure review inten
110
110
  Parse REVIEW.md frontmatter to check status and extract context for --auto loop:
111
111
 
112
112
  ```bash
113
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
113
114
  # Parse status field
114
115
  REVIEW_STATUS=$(REVIEW_PATH="${REVIEW_PATH}" node -e "
115
116
  const fs = require('fs');
@@ -137,6 +138,7 @@ Warning: Could not parse REVIEW.md status. Proceeding with fix attempt.
137
138
  Extract review depth for --auto re-review:
138
139
 
139
140
  ```bash
141
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
140
142
  REVIEW_DEPTH=$(REVIEW_PATH="${REVIEW_PATH}" node -e "
141
143
  const fs = require('fs');
142
144
  const content = fs.readFileSync(process.env.REVIEW_PATH, 'utf-8');
@@ -152,6 +154,7 @@ REVIEW_DEPTH=$(REVIEW_PATH="${REVIEW_PATH}" node -e "
152
154
  Extract original review file list for --auto re-review scope persistence:
153
155
 
154
156
  ```bash
157
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
155
158
  # Extract review file list — portable bash 3.2+ (no mapfile, handles spaces in paths)
156
159
  REVIEW_FILES_ARRAY=()
157
160
  while IFS= read -r line; do
@@ -199,6 +202,7 @@ gate on the `execute:pre` payload, filtered in the fence to the `vault`
199
202
  capability (D-30):
200
203
 
201
204
  ```bash
205
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
202
206
  CRF_EXECUTE_PRE_HOOKS_JSON=$(pp_run loop render-hooks execute:pre --raw | node -e "const d=require('fs').readFileSync(0,'utf-8');try{const j=JSON.parse(d);j.activeHooks=(j.activeHooks||[]).filter((x)=>x&&x.capId==='vault');process.stdout.write(JSON.stringify(j));}catch{process.stdout.write('');}")
203
207
  printf '%s' "$CRF_EXECUTE_PRE_HOOKS_JSON" | node -e "let h=[];try{h=JSON.parse(require('fs').readFileSync(0,'utf-8')).activeHooks||[]}catch{}console.log('CRF_EXECUTE_PRE_HOOKS_JSON='+JSON.stringify({activeHooks:h}))"
204
208
  ```
@@ -267,7 +271,7 @@ Check if FIX_REPORT_PATH exists:
267
271
 
268
272
  Either way:
269
273
  ```
270
- Some fix commits may already exist in git history — check git log for fix(${PADDED_PHASE}) commits.
274
+ Some fix commits may already exist in git history — check git log --grep="^Phase: ${PADDED_PHASE}$" for fix commits.
271
275
  You can retry with /pp:code-review ${PHASE_ARG} --fix.
272
276
  ```
273
277
 
@@ -278,6 +282,7 @@ Exit workflow (skip auto loop).
278
282
  Only runs if AUTO_MODE is true. If AUTO_MODE is false, skip this step entirely.
279
283
 
280
284
  ```bash
285
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
281
286
  if [ "$AUTO_MODE" = "true" ]; then
282
287
  # Iteration semantics: the initial fix pass (step 5) is iteration 1.
283
288
  # This loop runs iterations 2..MAX_ITERATIONS (re-review + re-fix cycles).
@@ -395,6 +400,7 @@ Key design decisions for --auto (addresses ALL review HIGH concerns):
395
400
  After ALL iterations complete (or single pass in non-auto mode), validate and commit REVIEW-FIX.md:
396
401
 
397
402
  ```bash
403
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
398
404
  if [ -f "${FIX_REPORT_PATH}" ]; then
399
405
  # Validate REVIEW-FIX.md has valid YAML frontmatter with status field
400
406
  HAS_STATUS=$(REVIEW_PATH="${REVIEW_PATH}" node -e "
@@ -409,7 +415,7 @@ if [ -f "${FIX_REPORT_PATH}" ]; then
409
415
 
410
416
  if [ "$COMMIT_DOCS" = "true" ]; then
411
417
  pp_run query commit \
412
- "docs(${PADDED_PHASE}): add code review fix report" \
418
+ "docs(planning): add code review fix report" --phase "${PADDED_PHASE}" \
413
419
  --files "${FIX_REPORT_PATH}"
414
420
  fi
415
421
  else
@@ -419,7 +425,7 @@ if [ -f "${FIX_REPORT_PATH}" ]; then
419
425
  else
420
426
  echo "Warning: REVIEW-FIX.md not found at ${FIX_REPORT_PATH}."
421
427
  echo "Agent may have failed before writing report."
422
- echo "Check git log for any fix(${PADDED_PHASE}) commits that were applied."
428
+ echo "Check git log --grep='^Phase: ${PADDED_PHASE}\$' for any fix commits that were applied."
423
429
  fi
424
430
  ```
425
431
 
@@ -441,7 +447,7 @@ The verb writes a `## Vault Door Record` (mode, vault ref and sha, governing pha
441
447
  recorded and the end commit; the agent never types a sha) into a fresh per-run artifact, because it refuses a second record
442
448
  in one file (D-57) and a rewritten report would drop the earlier run's coverage (D-79). It prints
443
449
  nothing and writes nothing unless `vault admission` answers `on`. When it wrote the file and
444
- `commit_docs` is true, commit the `artifact` path it printed: `pp_run query commit "docs(${PADDED_PHASE}): vault door record for code-review-fix" --files "<that artifact>"`.
450
+ `commit_docs` is true, commit the `artifact` path it printed: `pp_run query commit "docs(planning): vault door record for code-review-fix" --phase "${PADDED_PHASE}" --files "<that artifact>"`.
445
451
  </step>
446
452
 
447
453
  <step name="present_results">
@@ -459,7 +465,7 @@ if [ ! -f "${FIX_REPORT_PATH}" ]; then
459
465
  echo "───────────────────────────────────────────────────────────────"
460
466
  echo ""
461
467
  echo "The fixer agent may have failed before completing."
462
- echo "Check git log for any fix(${PADDED_PHASE}) commits."
468
+ echo "Check git log --grep='^Phase: ${PADDED_PHASE}\$' for any fix commits."
463
469
  echo ""
464
470
  echo "Retry: /pp:code-review ${PHASE_ARG} --fix"
465
471
  echo ""
@@ -471,6 +477,7 @@ fi
471
477
  Extract frontmatter fields:
472
478
 
473
479
  ```bash
480
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
474
481
  # Extract only the YAML frontmatter block (between first two --- lines)
475
482
  FIX_FRONTMATTER=$(REVIEW_PATH="${REVIEW_PATH}" node -e "
476
483
  const fs = require('fs');
@@ -18,6 +18,7 @@ Parse arguments and load project state:
18
18
 
19
19
  ```bash
20
20
  _PP_SHIM_NAME="pp-tools.cjs"; _pp_root() { ( for _v in $(env | sed -n 's/^\(GIT_[A-Za-z0-9_]*\)=.*/\1/p'); do unset "$_v"; done; _c=$(git rev-parse --git-common-dir 2>/dev/null); if [ "${_c##*/}" = .git ] && cd "$_c/.." 2>/dev/null; then pwd -P; else git rev-parse --show-toplevel 2>/dev/null || pwd; fi ); }; pp_run() { case "$PP_TOOLS" in *.cjs) node "$PP_TOOLS" "$@";; *) "$PP_TOOLS" "$@";; esac; }; _PP_RUNTIME_ROOT="${RUNTIME_DIR:-$(_pp_root)}"; PP_TOOLS="${_PP_RUNTIME_ROOT}/pp-core/bin/${_PP_SHIM_NAME}"; if [ -f "$PP_TOOLS" ]; then :; elif [ -f "${_PP_RUNTIME_ROOT}/.claude/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${_PP_RUNTIME_ROOT}/.claude/pp-core/bin/${_PP_SHIM_NAME}"; elif [ -f "${_PP_RUNTIME_ROOT}/.codex/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${_PP_RUNTIME_ROOT}/.codex/pp-core/bin/${_PP_SHIM_NAME}"; elif [ -f "$HOME/.claude/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="$HOME/.claude/pp-core/bin/${_PP_SHIM_NAME}"; elif [ -f "${HERMES_HOME:-$HOME/.hermes}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${HERMES_HOME:-$HOME/.hermes}/pp-core/bin/${_PP_SHIM_NAME}"; elif [ -f "${CURSOR_CONFIG_DIR:-$HOME/.cursor}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${CURSOR_CONFIG_DIR:-$HOME/.cursor}/pp-core/bin/${_PP_SHIM_NAME}"; elif [ -f "${CODEX_HOME:-$HOME/.codex}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${CODEX_HOME:-$HOME/.codex}/pp-core/bin/${_PP_SHIM_NAME}"; elif [ -f "${GEMINI_CONFIG_DIR:-$HOME/.gemini}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${GEMINI_CONFIG_DIR:-$HOME/.gemini}/pp-core/bin/${_PP_SHIM_NAME}"; elif [ -f "${COPILOT_CONFIG_DIR:-$HOME/.copilot}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${COPILOT_CONFIG_DIR:-$HOME/.copilot}/pp-core/bin/${_PP_SHIM_NAME}"; elif [ -f "${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/pp-core/bin/${_PP_SHIM_NAME}"; elif [ -f "${AUGMENT_CONFIG_DIR:-$HOME/.augment}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${AUGMENT_CONFIG_DIR:-$HOME/.augment}/pp-core/bin/${_PP_SHIM_NAME}"; elif [ -f "${TRAE_CONFIG_DIR:-$HOME/.trae}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${TRAE_CONFIG_DIR:-$HOME/.trae}/pp-core/bin/${_PP_SHIM_NAME}"; elif [ -f "${QWEN_CONFIG_DIR:-$HOME/.qwen}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${QWEN_CONFIG_DIR:-$HOME/.qwen}/pp-core/bin/${_PP_SHIM_NAME}"; elif [ -f "${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/pp-core/bin/${_PP_SHIM_NAME}"; elif [ -f "${CLINE_CONFIG_DIR:-$HOME/.cline}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${CLINE_CONFIG_DIR:-$HOME/.cline}/pp-core/bin/${_PP_SHIM_NAME}"; elif [ -f "${GROK_AGENTS_HOME:-$HOME/.agents}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${GROK_AGENTS_HOME:-$HOME/.agents}/pp-core/bin/${_PP_SHIM_NAME}"; elif [ -f "${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/pp-core/bin/${_PP_SHIM_NAME}"; elif [ -f "${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/pp-core/bin/${_PP_SHIM_NAME}"; elif [ -f "${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/pp-core/bin/${_PP_SHIM_NAME}"; elif command -v pp-tools >/dev/null 2>&1; then PP_TOOLS="$(command -v pp-tools)"; else echo "ERROR: pp-tools.cjs not found at $PP_TOOLS and pp-tools is not on PATH. Run: npx -y @pareto4/pp-core@latest --claude --local" >&2; exit 1; fi; if [ -n "${CLAUDE_ENV_FILE:-}" ] && [ -n "${PP_TOOLS:-}" ]; then printf "export PATH='%s':\"\$PATH\"\n" "${PP_TOOLS%/*}" >> "$CLAUDE_ENV_FILE" 2>/dev/null || true; fi
21
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
21
22
  PHASE_ARG="${1}"
22
23
  INIT=$(pp_run query init.phase-op "${PHASE_ARG}")
23
24
  if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
@@ -138,6 +139,7 @@ Three-tier scoping with explicit precedence:
138
139
 
139
140
  If FILES_OVERRIDE is set (from --files flag):
140
141
  ```bash
142
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
141
143
  if [ -n "$FILES_OVERRIDE" ]; then
142
144
  REVIEW_FILES=()
143
145
  REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null)
@@ -168,6 +170,7 @@ Skip SUMMARY/git scoping entirely when --files is provided.
168
170
 
169
171
  If --files NOT provided:
170
172
  ```bash
173
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
171
174
  if [ -z "$FILES_OVERRIDE" ]; then
172
175
  SUMMARIES=$(ls "${PHASE_DIR}"/*-SUMMARY.md 2>/dev/null)
173
176
  REVIEW_FILES=()
@@ -222,6 +225,7 @@ fi
222
225
 
223
226
  If no SUMMARY.md files found OR no files extracted from them:
224
227
  ```bash
228
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
225
229
  if [ ${#REVIEW_FILES[@]} -eq 0 ]; then
226
230
  # Compute diff base from phase commits — fail closed if no reliable base found
227
231
  PHASE_COMMITS=$(git log --oneline --all --grep="${PADDED_PHASE}" --format="%H" 2>/dev/null)
@@ -257,6 +261,7 @@ fi
257
261
 
258
262
  1. **Apply exclusions (per D-03):** Remove paths matching planning artifacts
259
263
  ```bash
264
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
260
265
  FILTERED_FILES=()
261
266
  for file in "${REVIEW_FILES[@]}"; do
262
267
  # Skip planning directory and specific artifacts
@@ -275,6 +280,7 @@ REVIEW_FILES=("${FILTERED_FILES[@]}")
275
280
 
276
281
  2. **Filter deleted files:** Remove paths that don't exist on disk
277
282
  ```bash
283
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
278
284
  EXISTING_FILES=()
279
285
  DELETED_COUNT=0
280
286
  for file in "${REVIEW_FILES[@]}"; do
@@ -293,6 +299,7 @@ fi
293
299
 
294
300
  3. **Deduplicate:** Remove duplicate paths (portable — bash 3.2+ compatible, handles spaces in paths)
295
301
  ```bash
302
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
296
303
  DEDUPED=()
297
304
  while IFS= read -r line; do
298
305
  [ -n "$line" ] && DEDUPED+=("$line")
@@ -304,6 +311,7 @@ REVIEW_FILES=("${DEDUPED[@]}")
304
311
 
305
312
  **Log final scope and warn if large:**
306
313
  ```bash
314
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
307
315
  if [ -n "$FILES_OVERRIDE" ]; then
308
316
  TIER="--files override"
309
317
  elif [ -n "$SUMMARIES" ] && [ ${#REVIEW_FILES[@]} -gt 0 ]; then
@@ -379,6 +387,7 @@ fi
379
387
 
380
388
  3) Execute structural pass and persist JSON (bounded at 120s). Note: `fallow audit` exits 0 when clean and 1 when issues are found — BOTH are successful runs. Only a timeout (124), usage error (2), or crash yields no usable JSON; success is decided by whether the output parses as a valid fallow report, not by exit code:
381
389
  ```bash
390
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
382
391
  FALLOW_JSON_PATH="${PHASE_DIR}/FALLOW.json"
383
392
  FALLOW_STDERR_TMP=$(mktemp)
384
393
 
@@ -459,6 +468,7 @@ fi
459
468
 
460
469
  Build files_to_read block for agent:
461
470
  ```bash
471
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
462
472
  FILES_TO_READ=""
463
473
  for file in "${REVIEW_FILES[@]}"; do
464
474
  FILES_TO_READ+="- ${file}\n"
@@ -467,6 +477,7 @@ done
467
477
 
468
478
  Build config block for agent:
469
479
  ```bash
480
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
470
481
  CONFIG_FILES=""
471
482
  for file in "${REVIEW_FILES[@]}"; do
472
483
  CONFIG_FILES+=" - ${file}\n"
@@ -475,6 +486,7 @@ done
475
486
 
476
487
  Build structural findings block for agent:
477
488
  ```bash
489
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
478
490
  STRUCTURAL_FINDINGS_BLOCK=""
479
491
  MAX_FINDINGS_SIZE=50000
480
492
  if [ -n "$FALLOW_JSON_PATH" ] && [ -f "$FALLOW_JSON_PATH" ]; then
@@ -542,6 +554,7 @@ Do NOT proceed to commit_review step. Do NOT create a partial or empty REVIEW.md
542
554
  After agent completes successfully, verify REVIEW.md was created and has valid structure:
543
555
 
544
556
  ```bash
557
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
545
558
  if [ -f "${REVIEW_PATH}" ]; then
546
559
  # Validate REVIEW.md has valid YAML frontmatter with status field
547
560
  HAS_STATUS=$(REVIEW_PATH="${REVIEW_PATH}" node -e "
@@ -556,7 +569,7 @@ if [ -f "${REVIEW_PATH}" ]; then
556
569
 
557
570
  if [ "$COMMIT_DOCS" = "true" ]; then
558
571
  pp_run query commit \
559
- "docs(${PADDED_PHASE}): add code review report" \
572
+ "docs(planning): add code review report" --phase "${PADDED_PHASE}" \
560
573
  --files "${REVIEW_PATH}"
561
574
  fi
562
575
  else
@@ -616,6 +629,7 @@ Read the REVIEW.md YAML frontmatter to extract finding counts.
616
629
  Extract frontmatter between `---` delimiters first to avoid matching values in the review body:
617
630
 
618
631
  ```bash
632
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
619
633
  # Extract only the YAML frontmatter block (between first two --- lines)
620
634
  FRONTMATTER=$(REVIEW_PATH="${REVIEW_PATH}" node -e "
621
635
  const fs = require('fs');
@@ -201,6 +201,7 @@ Milestone Stats:
201
201
  Extract one-liners from SUMMARY.md files using summary-extract:
202
202
 
203
203
  ```bash
204
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
204
205
  # For each phase in milestone, extract one-liner
205
206
  for summary in .planning/phases/*-*/*-SUMMARY.md; do
206
207
  [ -e "$summary" ] || continue
@@ -236,6 +237,7 @@ Full PROJECT.md evolution review at milestone completion.
236
237
  Read all phase summaries:
237
238
 
238
239
  ```bash
240
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
239
241
  cat .planning/phases/*-*/*-SUMMARY.md
240
242
  ```
241
243
 
@@ -385,11 +387,13 @@ AskUserQuestion(header="Archive Phases", question="Archive phase directories to
385
387
 
386
388
  If "Yes":
387
389
  ```bash
390
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
388
391
  ARCHIVE=$(pp_run query milestone.complete "v[X.Y]" --name "[Milestone Name]" --archive-phases ${GSD_WS})
389
392
  ```
390
393
 
391
394
  If "Skip":
392
395
  ```bash
396
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
393
397
  ARCHIVE=$(pp_run query milestone.complete "v[X.Y]" --name "[Milestone Name]" ${GSD_WS})
394
398
  ```
395
399
 
@@ -482,7 +486,8 @@ Append the extracted Backlog content verbatim to the end of the newly written RO
482
486
  **Safety commit — commit archive files BEFORE deleting any originals:**
483
487
 
484
488
  ```bash
485
- pp_run query commit "chore: archive v[X.Y] milestone files" --files .planning/milestones/v[X.Y]-ROADMAP.md .planning/milestones/v[X.Y]-REQUIREMENTS.md .planning/milestones/v[X.Y]-MILESTONE-AUDIT.md .planning/MILESTONES.md .planning/PROJECT.md .planning/STATE.md .planning/ROADMAP.md
489
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
490
+ pp_run query commit "chore(planning): archive v[X.Y] milestone files" --files .planning/milestones/v[X.Y]-ROADMAP.md .planning/milestones/v[X.Y]-REQUIREMENTS.md .planning/milestones/v[X.Y]-MILESTONE-AUDIT.md .planning/MILESTONES.md .planning/PROJECT.md .planning/STATE.md .planning/ROADMAP.md
486
491
  ```
487
492
 
488
493
  This creates a durable checkpoint in git history. If anything fails after this point, the working tree can be reconstructed from git.
@@ -551,7 +556,7 @@ If the "## Cross-Milestone Trends" section exists, update the tables with new da
551
556
 
552
557
  **Commit:**
553
558
  ```bash
554
- pp_run query commit "docs: update retrospective for v${VERSION}" --files .planning/RETROSPECTIVE.md
559
+ pp_run query commit "docs(planning): update retrospective for v${VERSION}" --files .planning/RETROSPECTIVE.md
555
560
  ```
556
561
 
557
562
  </step>
@@ -633,6 +638,7 @@ AskUserQuestion with options: Squash merge (Recommended), Merge with history, De
633
638
  **Squash merge:**
634
639
 
635
640
  ```bash
641
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
636
642
  CURRENT_BRANCH=$(git branch --show-current)
637
643
  git checkout ${BASE_BRANCH}
638
644
 
@@ -662,6 +668,7 @@ git checkout "$CURRENT_BRANCH"
662
668
  **Merge with history:**
663
669
 
664
670
  ```bash
671
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
665
672
  CURRENT_BRANCH=$(git branch --show-current)
666
673
  git checkout ${BASE_BRANCH}
667
674
 
@@ -691,6 +698,7 @@ git checkout "$CURRENT_BRANCH"
691
698
  **Delete without merging:**
692
699
 
693
700
  ```bash
701
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
694
702
  if [ "$BRANCHING_STRATEGY" = "phase" ]; then
695
703
  for branch in $PHASE_BRANCHES; do
696
704
  git branch -d "$branch" 2>/dev/null || git branch -D "$branch"
@@ -716,6 +724,7 @@ If the result is `false` → skip this step entirely and proceed to `git_commit_
716
724
  Create git tag:
717
725
 
718
726
  ```bash
727
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
719
728
  # Pre-check: skip if tag already exists (prevents silent failure on retry)
720
729
  if git rev-parse "v[X.Y]" >/dev/null 2>&1; then echo "Tag v[X.Y] already exists, skipping"; exit 0; fi
721
730
  git tag -a v[X.Y] -m "v[X.Y] [Name]
@@ -736,6 +745,7 @@ Ask: "Push tag to remote? (y/n)"
736
745
 
737
746
  If yes:
738
747
  ```bash
748
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
739
749
  git push origin v[X.Y]
740
750
  ```
741
751
 
@@ -746,7 +756,7 @@ git push origin v[X.Y]
746
756
  Commit the REQUIREMENTS.md deletion (archive files and ROADMAP.md were already committed in the safety commit in `reorganize_roadmap_and_delete_originals`).
747
757
 
748
758
  ```bash
749
- git commit -m "chore: remove REQUIREMENTS.md for v[X.Y] milestone"
759
+ git commit -m "chore(planning): remove REQUIREMENTS.md for v[X.Y] milestone"
750
760
  ```
751
761
 
752
762
  Confirm: "Committed: chore: remove REQUIREMENTS.md for v[X.Y] milestone"
@@ -51,6 +51,7 @@ non-Pareto or `vault.enabled=false` project debugs byte-identically to how it di
51
51
  `vault` capability (D-30):
52
52
 
53
53
  ```bash
54
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
54
55
  DEBUG_PLAN_PRE_HOOKS_JSON=$(pp_run loop render-hooks plan:pre --raw | node -e "const d=require('fs').readFileSync(0,'utf-8');try{const j=JSON.parse(d);j.activeHooks=(j.activeHooks||[]).filter((x)=>x&&x.capId==='vault');process.stdout.write(JSON.stringify(j));}catch{process.stdout.write('');}")
55
56
  printf '%s' "$DEBUG_PLAN_PRE_HOOKS_JSON" | node -e "let h=[];try{h=JSON.parse(require('fs').readFileSync(0,'utf-8')).activeHooks||[]}catch{}console.log('DEBUG_PLAN_PRE_HOOKS_JSON='+JSON.stringify({activeHooks:h}))"
56
57
  ```
@@ -68,6 +69,7 @@ It owns the halt: a required miss stops here with the gate's own message, before
68
69
  When SUBCMD=list:
69
70
 
70
71
  ```bash
72
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
71
73
  ls .planning/debug/*.md 2>/dev/null | grep -v resolved
72
74
  ```
73
75
 
@@ -184,7 +184,7 @@ Update status in frontmatter to "diagnosed".
184
184
 
185
185
  Commit the updated UAT.md:
186
186
  ```bash
187
- pp_run query commit "docs({phase_num}): add root causes from diagnosis" --files ".planning/phases/XX-name/{phase_num}-UAT.md"
187
+ pp_run query commit "docs(planning): add root causes from diagnosis" --phase "{phase_num}" --files ".planning/phases/XX-name/{phase_num}-UAT.md"
188
188
  ```
189
189
  </step>
190
190