@pareto4/pp-core 1.18.0 → 1.19.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 (147) 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 +3 -1
  9. package/agents/pp-plan-checker.md +3 -0
  10. package/agents/pp-planner.md +5 -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-verifier.md +10 -2
  15. package/commands/pp-add-tests.md +1 -1
  16. package/commands/pp-debug.md +1 -0
  17. package/commands/pp-init.md +4 -3
  18. package/commands/pp-quick.md +3 -0
  19. package/commands/pp-review-backlog.md +2 -1
  20. package/gemini-extension.json +1 -1
  21. package/package.json +1 -1
  22. package/pp-core/bin/lib/capability-registry.cjs +2 -2
  23. package/pp-core/bin/lib/check-command-router.cjs +60 -20
  24. package/pp-core/bin/lib/commands.cjs +79 -4
  25. package/pp-core/bin/lib/compose-bindings.cjs +97 -14
  26. package/pp-core/bin/lib/discovery-rollup.cjs +9 -6
  27. package/pp-core/bin/lib/discovery-screens.cjs +20 -2
  28. package/pp-core/bin/lib/discovery-sweep.cjs +12 -3
  29. package/pp-core/bin/lib/discovery-vault-check.cjs +37 -3
  30. package/pp-core/bin/lib/init-contract.cjs +48 -7
  31. package/pp-core/bin/lib/vault-coordinates.cjs +1 -1
  32. package/pp-core/bin/lib/vault-index.cjs +18 -5
  33. package/pp-core/bin/lib/vault-update.cjs +4 -0
  34. package/pp-core/bin/lib/vault.cjs +2 -2
  35. package/pp-core/bin/pp-tools.cjs +10 -4
  36. package/pp-core/org-profile.json +1 -1
  37. package/pp-core/references/autonomous-best-effort.md +3 -2
  38. package/pp-core/references/autonomous-lifecycle.md +1 -0
  39. package/pp-core/references/autonomous-smart-discuss.md +5 -1
  40. package/pp-core/references/discovery-id-conventions.md +35 -2
  41. package/pp-core/references/execute-mvp-tdd.md +3 -3
  42. package/pp-core/references/git-integration.md +57 -33
  43. package/pp-core/references/git-planning-commit.md +31 -9
  44. package/pp-core/references/phase-argument-parsing.md +1 -0
  45. package/pp-core/references/planner-gap-closure.md +1 -0
  46. package/pp-core/references/planner-revision.md +3 -1
  47. package/pp-core/references/planner-tdd.md +4 -4
  48. package/pp-core/references/planning-config.md +3 -3
  49. package/pp-core/references/shell-portability.md +28 -0
  50. package/pp-core/references/tdd.md +20 -16
  51. package/pp-core/references/worktree-path-safety.md +1 -0
  52. package/pp-core/templates/milestone.md +5 -5
  53. package/pp-core/workflows/add-backlog.md +1 -1
  54. package/pp-core/workflows/add-tests.md +5 -2
  55. package/pp-core/workflows/add-todo.md +3 -1
  56. package/pp-core/workflows/ai-integration-phase.md +2 -1
  57. package/pp-core/workflows/audit-fix.md +4 -3
  58. package/pp-core/workflows/audit-milestone.md +1 -0
  59. package/pp-core/workflows/autonomous.md +6 -0
  60. package/pp-core/workflows/check-todos.md +2 -1
  61. package/pp-core/workflows/cleanup.md +3 -1
  62. package/pp-core/workflows/code-review-fix.md +12 -5
  63. package/pp-core/workflows/code-review.md +15 -1
  64. package/pp-core/workflows/complete-milestone.md +13 -3
  65. package/pp-core/workflows/debug.md +2 -0
  66. package/pp-core/workflows/diagnose-issues.md +1 -1
  67. package/pp-core/workflows/discovery-sprint/session-13-gates.md +1 -1
  68. package/pp-core/workflows/discovery-sprint/sessions/01-kick-off.md +51 -7
  69. package/pp-core/workflows/discovery-sprint/sessions/02-as-is.md +5 -3
  70. package/pp-core/workflows/discovery-sprint/sessions/03-to-be.md +10 -8
  71. package/pp-core/workflows/discovery-sprint/sessions/04-ux-design.md +11 -2
  72. package/pp-core/workflows/discovery-sprint/sessions/05-architecture.md +5 -5
  73. package/pp-core/workflows/discovery-sprint/sessions/06-security.md +3 -3
  74. package/pp-core/workflows/discovery-sprint/sessions/07-identity.md +2 -2
  75. package/pp-core/workflows/discovery-sprint/sessions/08-integration.md +14 -2
  76. package/pp-core/workflows/discovery-sprint/sessions/09-qa.md +2 -2
  77. package/pp-core/workflows/discovery-sprint/sessions/10-infrastructure.md +10 -10
  78. package/pp-core/workflows/discovery-sprint/sessions/11-roadmap.md +11 -8
  79. package/pp-core/workflows/discovery-sprint/sessions/12-delivery-model.md +21 -18
  80. package/pp-core/workflows/discovery-sprint/sessions/13-wrap-up.md +5 -3
  81. package/pp-core/workflows/discovery-sprint/templates/context-template.md +9 -3
  82. package/pp-core/workflows/discovery-sprint/vault-context.md +14 -3
  83. package/pp-core/workflows/discovery-sprint.md +11 -8
  84. package/pp-core/workflows/discovery-to-build/steps/architecture-deliverables.md +1 -0
  85. package/pp-core/workflows/discuss-phase-assumptions.md +5 -3
  86. package/pp-core/workflows/discuss-phase.md +8 -3
  87. package/pp-core/workflows/docs-update.md +1 -0
  88. package/pp-core/workflows/eval-review.md +2 -1
  89. package/pp-core/workflows/execute-phase/steps/check-query-gate.md +7 -6
  90. package/pp-core/workflows/execute-phase/steps/cross-ai-delegation.md +1 -0
  91. package/pp-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +1 -0
  92. package/pp-core/workflows/execute-phase/steps/vault-fetch.md +12 -0
  93. package/pp-core/workflows/execute-phase.md +19 -7
  94. package/pp-core/workflows/execute-plan.md +18 -7
  95. package/pp-core/workflows/explore.md +1 -1
  96. package/pp-core/workflows/forensics.md +4 -2
  97. package/pp-core/workflows/health.md +1 -0
  98. package/pp-core/workflows/import.md +2 -1
  99. package/pp-core/workflows/ingest-docs.md +1 -0
  100. package/pp-core/workflows/init/steps/client-context-capture.md +1 -0
  101. package/pp-core/workflows/init/steps/github-provisioning.md +145 -0
  102. package/pp-core/workflows/init/steps/gitlab-provisioning.md +18 -4
  103. package/pp-core/workflows/init/steps/reachability-outcome.md +3 -1
  104. package/pp-core/workflows/init.md +56 -66
  105. package/pp-core/workflows/map-codebase.md +5 -1
  106. package/pp-core/workflows/milestone-summary.md +2 -1
  107. package/pp-core/workflows/mvp-phase.md +1 -0
  108. package/pp-core/workflows/new-milestone.md +9 -5
  109. package/pp-core/workflows/new-project.md +9 -8
  110. package/pp-core/workflows/new-workspace.md +1 -0
  111. package/pp-core/workflows/next.md +2 -1
  112. package/pp-core/workflows/pause-work.md +6 -4
  113. package/pp-core/workflows/plan-milestone-gaps.md +3 -1
  114. package/pp-core/workflows/plan-phase/steps/chunked-planning.md +1 -1
  115. package/pp-core/workflows/plan-phase.md +21 -6
  116. package/pp-core/workflows/plan-review-convergence.md +2 -0
  117. package/pp-core/workflows/plant-seed.md +4 -2
  118. package/pp-core/workflows/pr-branch.md +2 -0
  119. package/pp-core/workflows/progress.md +5 -0
  120. package/pp-core/workflows/quick.md +11 -4
  121. package/pp-core/workflows/reapply-patches.md +3 -0
  122. package/pp-core/workflows/remove-phase.md +1 -1
  123. package/pp-core/workflows/resume-project.md +3 -0
  124. package/pp-core/workflows/review.md +7 -1
  125. package/pp-core/workflows/secure-phase.md +2 -1
  126. package/pp-core/workflows/session-report.md +1 -0
  127. package/pp-core/workflows/ship.md +8 -1
  128. package/pp-core/workflows/sketch-wrap-up.md +1 -1
  129. package/pp-core/workflows/sketch.md +3 -2
  130. package/pp-core/workflows/spec-phase.md +2 -1
  131. package/pp-core/workflows/spike-wrap-up.md +1 -1
  132. package/pp-core/workflows/spike.md +4 -3
  133. package/pp-core/workflows/sync-skills.md +5 -2
  134. package/pp-core/workflows/thread.md +3 -2
  135. package/pp-core/workflows/transition.md +6 -0
  136. package/pp-core/workflows/ui-phase.md +3 -1
  137. package/pp-core/workflows/ui-review.md +2 -1
  138. package/pp-core/workflows/ultraplan-phase.md +1 -0
  139. package/pp-core/workflows/undo.md +14 -10
  140. package/pp-core/workflows/update.md +5 -0
  141. package/pp-core/workflows/validate-phase.md +6 -3
  142. package/pp-core/workflows/vault-review.md +2 -1
  143. package/pp-core/workflows/vault-write-back.md +5 -0
  144. package/pp-core/workflows/verify-phase.md +5 -0
  145. package/pp-core/workflows/verify-work.md +8 -1
  146. package/scripts/prompt-injection-scan.sh +1 -1
  147. package/scripts/sync-runtime-launcher.cjs +115 -5
@@ -34,11 +34,23 @@ If NO_GIT: Run `git init` silently. pp-core projects always get their own repo.
34
34
 
35
35
  <commit_formats>
36
36
 
37
+ <format name="scope-and-trailer">
38
+ ## Scope and Phase Trailer
39
+
40
+ Every commit follows Conventional Commits: `{type}({scope}): {description}`, an optional body, then trailers.
41
+
42
+ - **The scope names the part of the codebase**, never a phase, plan or quick-task id: `feat(auth)`, `fix(billing)`, `test(api)`. Pick it from the files the commit touches; leave it out (`chore: ...`) when no single area fits. Commits of `.planning/` artifacts use `docs(planning)` (or `chore(planning)`).
43
+ - **The phase or plan goes in a git trailer**, the last paragraph of the message after a blank line: `Phase: 02-03` for a plan, `Phase: 02` for a phase-level commit, `Quick: <id>` for a quick task. `pp_run query commit` and `pp_run query commit-to-subrepo` add it with `--phase <id>` / `--quick <id>`; a raw `git commit` adds it as a second `-m "Phase: <id>"` or as the last paragraph of the message.
44
+
45
+ Why: a scope that is a phase number tells a reviewer nothing about what changed and breaks the client standard that the scope is a noun naming the part of the codebase. The trailer keeps every commit traceable to its phase and plan, and git parses it (`%(trailers:key=Phase)`, `git log --grep="^Phase: 02-03$"`), so tools no longer parse subjects.
46
+
47
+ </format>
48
+
37
49
  <format name="initialization">
38
50
  ## Project Initialization (brief + roadmap together)
39
51
 
40
52
  ```
41
- docs: initialize [project-name] ([N] phases)
53
+ docs(planning): initialize [project-name] ([N] phases)
42
54
 
43
55
  [One-liner from PROJECT.md]
44
56
 
@@ -51,7 +63,7 @@ Phases:
51
63
  What to commit:
52
64
 
53
65
  ```bash
54
- pp-tools query commit "docs: initialize [project-name] ([N] phases)" --files .planning/
66
+ pp_run query commit "docs(planning): initialize [project-name] ([N] phases)" --files .planning/
55
67
  ```
56
68
 
57
69
  </format>
@@ -69,11 +81,13 @@ Each task gets its own commit immediately after completion.
69
81
  > executor prompt; absent that signal, hooks run normally.
70
82
 
71
83
  ```
72
- {type}({phase}-{plan}): {task-name}
84
+ {type}({area}): {task-name}
73
85
 
74
86
  - [Key change 1]
75
87
  - [Key change 2]
76
88
  - [Key change 3]
89
+
90
+ Phase: {phase}-{plan}
77
91
  ```
78
92
 
79
93
  **Commit types:**
@@ -89,29 +103,35 @@ Each task gets its own commit immediately after completion.
89
103
  ```bash
90
104
  # Standard task
91
105
  git add src/api/auth.ts src/types/user.ts
92
- git commit -m "feat(08-02): create user registration endpoint
106
+ git commit -m "feat(auth): create user registration endpoint
93
107
 
94
108
  - POST /auth/register validates email and password
95
109
  - Checks for duplicate users
96
110
  - Returns JWT token on success
111
+
112
+ Phase: 08-02
97
113
  "
98
114
 
99
115
  # TDD task - RED phase
100
116
  git add src/__tests__/jwt.test.ts
101
- git commit -m "test(07-02): add failing test for JWT generation
117
+ git commit -m "test(auth): add failing test for JWT generation
102
118
 
103
119
  - Tests token contains user ID claim
104
120
  - Tests token expires in 1 hour
105
121
  - Tests signature verification
122
+
123
+ Phase: 07-02
106
124
  "
107
125
 
108
126
  # TDD task - GREEN phase
109
127
  git add src/utils/jwt.ts
110
- git commit -m "feat(07-02): implement JWT generation
128
+ git commit -m "feat(auth): implement JWT generation
111
129
 
112
130
  - Uses jose library for signing
113
131
  - Includes user ID and expiry claims
114
132
  - Signs with HS256 algorithm
133
+
134
+ Phase: 07-02
115
135
  "
116
136
  ```
117
137
 
@@ -123,7 +143,7 @@ git commit -m "feat(07-02): implement JWT generation
123
143
  After all tasks committed, one final metadata commit captures plan completion.
124
144
 
125
145
  ```
126
- docs({phase}-{plan}): complete [plan-name] plan
146
+ docs(planning): complete [plan-name] plan
127
147
 
128
148
  Tasks completed: [N]/[N]
129
149
  - [Task 1 name]
@@ -131,12 +151,14 @@ Tasks completed: [N]/[N]
131
151
  - [Task 3 name]
132
152
 
133
153
  SUMMARY: .planning/phases/XX-name/{phase}-{plan}-SUMMARY.md
154
+
155
+ Phase: {phase}-{plan}
134
156
  ```
135
157
 
136
158
  What to commit:
137
159
 
138
160
  ```bash
139
- pp-tools query commit "docs({phase}-{plan}): complete [plan-name] plan" --files .planning/phases/XX-name/{phase}-{plan}-PLAN.md .planning/phases/XX-name/{phase}-{plan}-SUMMARY.md .planning/STATE.md .planning/ROADMAP.md
161
+ pp_run query commit "docs(planning): complete [plan-name] plan" --phase "{phase}-{plan}" --files .planning/phases/XX-name/{phase}-{plan}-PLAN.md .planning/phases/XX-name/{phase}-{plan}-SUMMARY.md .planning/STATE.md .planning/ROADMAP.md
140
162
  ```
141
163
 
142
164
  **Note:** Code files NOT included - already committed per-task.
@@ -147,7 +169,7 @@ pp-tools query commit "docs({phase}-{plan}): complete [plan-name] plan" --files
147
169
  ## Handoff (WIP)
148
170
 
149
171
  ```
150
- wip: [phase-name] paused at task [X]/[Y]
172
+ docs(planning): pause [phase-name] at task [X]/[Y]
151
173
 
152
174
  Current: [task name]
153
175
  [If blocked:] Blocked: [reason]
@@ -156,7 +178,7 @@ Current: [task name]
156
178
  What to commit:
157
179
 
158
180
  ```bash
159
- pp-tools query commit "wip: [phase-name] paused at task [X]/[Y]" --files .planning/
181
+ pp_run query commit "docs(planning): pause [phase-name] at task [X]/[Y]" --files .planning/
160
182
  ```
161
183
 
162
184
  </format>
@@ -173,36 +195,38 @@ a7f2d1 feat(checkout): Stripe payments with webhook verification
173
195
  2f4a8d docs: initialize ecommerce-app (5 phases)
174
196
  ```
175
197
 
176
- **New approach (per-task commits):**
198
+ **New approach (per-task commits, phase in the trailer):**
199
+
200
+ `git log --format='%h %s [%(trailers:key=Phase,valueonly)]'` reads:
177
201
  ```
178
202
  # Phase 04 - Checkout
179
- 1a2b3c docs(04-01): complete checkout flow plan
180
- 4d5e6f feat(04-01): add webhook signature verification
181
- 7g8h9i feat(04-01): implement payment session creation
182
- 0j1k2l feat(04-01): create checkout page component
203
+ 1a2b3c docs(planning): complete checkout flow plan [04-01]
204
+ 4d5e6f feat(checkout): add webhook signature verification [04-01]
205
+ 7g8h9i feat(checkout): implement payment session creation [04-01]
206
+ 0j1k2l feat(checkout): create checkout page component [04-01]
183
207
 
184
208
  # Phase 03 - Products
185
- 3m4n5o docs(03-02): complete product listing plan
186
- 6p7q8r feat(03-02): add pagination controls
187
- 9s0t1u feat(03-02): implement search and filters
188
- 2v3w4x feat(03-01): create product catalog schema
209
+ 3m4n5o docs(planning): complete product listing plan [03-02]
210
+ 6p7q8r feat(products): add pagination controls [03-02]
211
+ 9s0t1u feat(products): implement search and filters [03-02]
212
+ 2v3w4x feat(products): create product catalog schema [03-01]
189
213
 
190
214
  # Phase 02 - Auth
191
- 5y6z7a docs(02-02): complete token refresh plan
192
- 8b9c0d feat(02-02): implement refresh token rotation
193
- 1e2f3g test(02-02): add failing test for token refresh
194
- 4h5i6j docs(02-01): complete JWT setup plan
195
- 7k8l9m feat(02-01): add JWT generation and validation
196
- 0n1o2p chore(02-01): install jose library
215
+ 5y6z7a docs(planning): complete token refresh plan [02-02]
216
+ 8b9c0d feat(auth): implement refresh token rotation [02-02]
217
+ 1e2f3g test(auth): add failing test for token refresh [02-02]
218
+ 4h5i6j docs(planning): complete JWT setup plan [02-01]
219
+ 7k8l9m feat(auth): add JWT generation and validation [02-01]
220
+ 0n1o2p build(deps): install jose library [02-01]
197
221
 
198
222
  # Phase 01 - Foundation
199
- 3q4r5s docs(01-01): complete scaffold plan
200
- 6t7u8v feat(01-01): configure Tailwind and globals
201
- 9w0x1y feat(01-01): set up Prisma with database
202
- 2z3a4b feat(01-01): create Next.js 15 project
223
+ 3q4r5s docs(planning): complete scaffold plan [01-01]
224
+ 6t7u8v feat(ui): configure Tailwind and globals [01-01]
225
+ 9w0x1y feat(db): set up Prisma with database [01-01]
226
+ 2z3a4b feat: create Next.js 15 project [01-01]
203
227
 
204
228
  # Initialization
205
- 5c6d7e docs: initialize ecommerce-app (5 phases)
229
+ 5c6d7e docs(planning): initialize ecommerce-app (5 phases) []
206
230
  ```
207
231
 
208
232
  Each plan produces 2-4 commits (tasks + metadata). Clear, granular, bisectable.
@@ -233,7 +257,7 @@ Each plan produces 2-4 commits (tasks + metadata). Clear, granular, bisectable.
233
257
 
234
258
  **Context engineering for AI:**
235
259
  - Git history becomes primary context source for future Claude sessions
236
- - `git log --grep="{phase}-{plan}"` shows all work for a plan
260
+ - `git log --grep="^Phase: {phase}-{plan}$"` shows all work for a plan
237
261
  - `git diff <hash>^..<hash>` shows exact changes per task
238
262
  - Less reliance on parsing SUMMARY.md = more context for actual work
239
263
 
@@ -287,11 +311,11 @@ Set `commit_docs: false` so planning docs stay local and are not committed to an
287
311
  Instead of the standard `commit` command, use `commit-to-subrepo` when `sub_repos` is configured:
288
312
 
289
313
  ```bash
290
- pp-tools query commit-to-subrepo "feat(02-01): add user API" \
314
+ pp_run query commit-to-subrepo "feat(users): add user API" --phase "02-01" \
291
315
  --files backend/src/api/users.ts backend/src/types/user.ts frontend/src/components/UserForm.tsx
292
316
  ```
293
317
 
294
- This stages `src/api/users.ts` and `src/types/user.ts` in the `backend/` repo, and `src/components/UserForm.tsx` in the `frontend/` repo, then commits each independently with the same message.
318
+ This stages `src/api/users.ts` and `src/types/user.ts` in the `backend/` repo, and `src/components/UserForm.tsx` in the `frontend/` repo, then commits each independently with the same message and `Phase: 02-01` trailer.
295
319
 
296
320
  Files that don't match any configured sub-repo are reported as unmatched.
297
321
 
@@ -9,29 +9,51 @@ Pass the message first, then file paths via `--files`. Both `commit` and `commit
9
9
  Always use this for `.planning/` files — it handles `commit_docs` and gitignore checks automatically:
10
10
 
11
11
  ```bash
12
- pp-tools query commit "docs({scope}): {description}" --files .planning/STATE.md .planning/ROADMAP.md
12
+ pp_run query commit "docs(planning): {description}" --phase "{phase-or-plan-id}" --files .planning/STATE.md .planning/ROADMAP.md
13
13
  ```
14
14
 
15
15
  The CLI will return `skipped` (with reason) if `commit_docs` is `false` or `.planning/` is gitignored. No manual conditional checks needed.
16
16
 
17
+ ## Scope and the Phase trailer
18
+
19
+ The Conventional Commit scope names the part of the codebase a commit changes, as in `fix(billing): round vat per line`. Planning artifacts are one such part, so every commit of `.planning/` files uses `docs(planning)` (or `chore(planning)` when the type is chore). A phase number, plan number, quick-task id or phase slug never goes in the scope.
20
+
21
+ To keep commits traceable to their phase, the phase or plan id goes in a git trailer instead:
22
+
23
+ - `--phase <id>` adds `Phase: <id>`: a plan id such as `02-03`, or a phase id such as `02` for phase-level commits. Use the same padded ids the phase directory uses.
24
+ - `--quick <id>` adds `Quick: <id>` for a quick task.
25
+
26
+ The trailer is the last paragraph of the message, after a blank line:
27
+
28
+ ```
29
+ docs(planning): complete token refresh plan
30
+
31
+ Phase: 02-03
32
+ ```
33
+
34
+ Readers find a phase's commits with `git log --grep="^Phase: 02-03$"`, or list each commit's trailer with `git log --format='%h %s %(trailers:key=Phase,valueonly)'`. An id may hold letters, digits, dots, dashes and underscores only; anything else (a space, a newline) is rejected before anything is staged. `--phase` and `--quick` are ignored with `--amend`, which keeps the previous message.
35
+
17
36
  ## Amend previous commit
18
37
 
19
38
  To fold `.planning/` file changes into the previous commit:
20
39
 
21
40
  ```bash
41
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
22
42
  pp-tools query commit "" --files .planning/codebase/*.md --amend
23
43
  ```
24
44
 
25
45
  ## Commit Message Patterns
26
46
 
27
- | Command | Scope | Example |
28
- |---------|-------|---------|
29
- | plan-phase | phase | `docs(phase-03): create authentication plans` |
30
- | execute-phase | phase | `docs(phase-03): complete authentication phase` |
31
- | new-milestone | milestone | `docs: start milestone v1.1` |
32
- | remove-phase | chore | `chore: remove phase 17 (dashboard)` |
33
- | insert-phase | phase | `docs: insert phase 16.1 (critical fix)` |
34
- | add-phase | phase | `docs: add phase 07 (settings page)` |
47
+ | Command | Message | Trailer |
48
+ |---------|---------|---------|
49
+ | plan-phase | `docs(planning): create phase plan` | `Phase: 03` |
50
+ | execute-plan | `docs(planning): complete authentication plan` | `Phase: 03-02` |
51
+ | execute-phase | `docs(planning): complete phase execution` | `Phase: 03` |
52
+ | quick | `docs(planning): record quick task — fix login typo` | `Quick: 260422-abc` |
53
+ | new-milestone | `docs(planning): start milestone v1.1` | — |
54
+ | remove-phase | `chore(planning): remove phase 17 (dashboard)` | — |
55
+ | insert-phase | `docs(planning): insert phase 16.1 (critical fix)` | — |
56
+ | add-phase | `docs(planning): add phase 07 (settings page)` | — |
35
57
 
36
58
  ## When to Skip
37
59
 
@@ -30,6 +30,7 @@ Returns JSON with:
30
30
  Zero-pad integer phases to 2 digits. Preserve decimal suffixes.
31
31
 
32
32
  ```bash
33
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
33
34
  # Normalize phase number
34
35
  if [[ "$PHASE" =~ ^[0-9]+$ ]]; then
35
36
  # Integer: 8 → 08
@@ -9,6 +9,7 @@ Triggered by `--gaps` flag. Creates plans to address verification or UAT failure
9
9
  Use init context (from load_project_state) which provides `phase_dir`:
10
10
 
11
11
  ```bash
12
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
12
13
  # Check for VERIFICATION.md (code verification gaps)
13
14
  ls "$phase_dir"/*-VERIFICATION.md 2>/dev/null
14
15
 
@@ -7,6 +7,7 @@ Triggered when orchestrator provides `<revision_context>` with checker issues. N
7
7
  ### Step 1: Load Existing Plans
8
8
 
9
9
  ```bash
10
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
10
11
  cat .planning/phases/$PHASE-*/$PHASE-*-PLAN.md
11
12
  ```
12
13
 
@@ -55,7 +56,8 @@ Group by plan, dimension, severity.
55
56
  ### Step 6: Commit
56
57
 
57
58
  ```bash
58
- pp-tools query commit "fix($PHASE): revise plans based on checker feedback" --files .planning/phases/$PHASE-*/$PHASE-*-PLAN.md
59
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
60
+ pp_run query commit "docs(planning): revise plans based on checker feedback" --phase "$PHASE" --files .planning/phases/$PHASE-*/$PHASE-*-PLAN.md
59
61
  ```
60
62
 
61
63
  ### Step 7: Return Revision Summary
@@ -40,13 +40,13 @@ Output: [Working, tested feature]
40
40
 
41
41
  ## Red-Green-Refactor Cycle
42
42
 
43
- **RED:** Create test file → write test describing expected behavior → run test (MUST fail) → commit: `test({phase}-{plan}): add failing test for [feature]`
43
+ **RED:** Create test file → write test describing expected behavior → run test (MUST fail) → commit: `test({area}): add failing test for [feature]`
44
44
 
45
- **GREEN:** Write minimal code to pass → run test (MUST pass) → commit: `feat({phase}-{plan}): implement [feature]`
45
+ **GREEN:** Write minimal code to pass → run test (MUST pass) → commit: `feat({area}): implement [feature]`
46
46
 
47
- **REFACTOR (if needed):** Clean up → run tests (MUST pass) → commit: `refactor({phase}-{plan}): clean up [feature]`
47
+ **REFACTOR (if needed):** Clean up → run tests (MUST pass) → commit: `refactor({area}): clean up [feature]`
48
48
 
49
- Each TDD plan produces 2-3 atomic commits.
49
+ `{area}` names the part of the codebase under test (`auth`, `billing`); each commit ends with the trailer `Phase: {phase}-{plan}`. Each TDD plan produces 2-3 atomic commits.
50
50
 
51
51
  ## Context Budget for TDD
52
52
 
@@ -61,7 +61,7 @@ Configuration options for `.planning/` directory behavior.
61
61
 
62
62
  ```bash
63
63
  # Commit with automatic commit_docs + gitignore checks:
64
- pp-tools query commit "docs: update state" --files .planning/STATE.md
64
+ pp_run query commit "docs(planning): update state" --files .planning/STATE.md
65
65
 
66
66
  # Load config via state load (returns JSON):
67
67
  INIT=$(pp-tools query state.load)
@@ -79,7 +79,7 @@ if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
79
79
  **Commit via CLI (handles checks automatically):**
80
80
 
81
81
  ```bash
82
- pp-tools query commit "docs: update state" --files .planning/STATE.md
82
+ pp_run query commit "docs(planning): update state" --files .planning/STATE.md
83
83
  ```
84
84
 
85
85
  The CLI checks `commit_docs` config and gitignore status internally — no manual conditionals needed.
@@ -121,7 +121,7 @@ To use uncommitted mode:
121
121
  3. **Existing tracked files:** If `.planning/` was previously tracked:
122
122
  ```bash
123
123
  git rm -r --cached .planning/
124
- git commit -m "chore: stop tracking planning docs"
124
+ git commit -m "chore(planning): stop tracking planning docs"
125
125
  ```
126
126
 
127
127
  4. **Branch merges:** When using `branching_strategy: phase` or `milestone`, the `complete-milestone` workflow automatically strips `.planning/` files from staging before merge commits when `commit_docs: false`.
@@ -0,0 +1,28 @@
1
+ # Shell portability — commands you write yourself
2
+
3
+ The Bash tool runs the user's login shell, which is zsh on macOS. Workflow fences already
4
+ start with the guard line below; shell you compose yourself does not, so add it.
5
+
6
+ **Start every multi-line command with:**
7
+
8
+ ```text
9
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
10
+ ```
11
+
12
+ It is a no-op under bash. Under zsh it makes the rest of the command behave like bash does:
13
+
14
+ | Without the guard, zsh… | Example that breaks |
15
+ |---|---|
16
+ | aborts the whole command on a glob that matches nothing (`nomatch`), even with `2>/dev/null \|\| true` | `for f in .planning/phases/*/*-PLAN.md; do …` |
17
+ | expands a word starting with `=` to a command path | `echo ====` → `==== not found` |
18
+ | does not split an unquoted `$var` into words | `set -- $LIST` gives one argument |
19
+ | indexes arrays from 1 | `${a[0]}` is empty |
20
+
21
+ For a one-line command, prefer the portable form instead:
22
+
23
+ - **No GNU-only flags.** macOS ships BSD tools: no `grep -P`, no `sed -i` without a suffix
24
+ argument, no `readlink -f`. Use `grep -E`, `sed -n 's/…/\1/p'`, `sed -i ''` only where you know
25
+ the platform.
26
+ - **Quote patterns and globs you don't want expanded**, and use `find … -name '*.md'` to list
27
+ files that may not exist.
28
+ - **Never begin a word with `=`.** Print separators with `printf '%s\n' '===='`.
@@ -96,18 +96,18 @@ After completion, create SUMMARY.md with:
96
96
  2. Write test describing expected behavior (from `<behavior>` element)
97
97
  3. Run test - it MUST fail
98
98
  4. If test passes: feature exists or test is wrong. Investigate.
99
- 5. Commit: `test({phase}-{plan}): add failing test for [feature]`
99
+ 5. Commit: `test({area}): add failing test for [feature]` with the trailer `Phase: {phase}-{plan}`
100
100
 
101
101
  **GREEN - Implement to pass:**
102
102
  1. Write minimal code to make test pass
103
103
  2. No cleverness, no optimization - just make it work
104
104
  3. Run test - it MUST pass
105
- 4. Commit: `feat({phase}-{plan}): implement [feature]`
105
+ 4. Commit: `feat({area}): implement [feature]` with the trailer `Phase: {phase}-{plan}`
106
106
 
107
107
  **REFACTOR (if needed):**
108
108
  1. Clean up implementation if obvious improvements exist
109
109
  2. Run tests - MUST still pass
110
- 3. Only commit if changes made: `refactor({phase}-{plan}): clean up [feature]`
110
+ 3. Only commit if changes made: `refactor({area}): clean up [feature]` with the trailer `Phase: {phase}-{plan}`
111
111
 
112
112
  **Result:** Each TDD plan produces 2-3 atomic commits.
113
113
  </execution_flow>
@@ -215,30 +215,36 @@ Framework setup is a one-time cost included in the first TDD plan's RED phase.
215
215
  TDD plans produce 2-3 atomic commits (one per phase):
216
216
 
217
217
  ```
218
- test(08-02): add failing test for email validation
218
+ test(validation): add failing test for email validation
219
219
 
220
220
  - Tests valid email formats accepted
221
221
  - Tests invalid formats rejected
222
222
  - Tests empty input handling
223
223
 
224
- feat(08-02): implement email validation
224
+ Phase: 08-02
225
+
226
+ feat(validation): implement email validation
225
227
 
226
228
  - Regex pattern matches RFC 5322
227
229
  - Returns boolean for validity
228
230
  - Handles edge cases (empty, null)
229
231
 
230
- refactor(08-02): extract regex to constant (optional)
232
+ Phase: 08-02
233
+
234
+ refactor(validation): extract regex to constant (optional)
231
235
 
232
236
  - Moved pattern to EMAIL_REGEX constant
233
237
  - No behavior changes
234
238
  - Tests still pass
239
+
240
+ Phase: 08-02
235
241
  ```
236
242
 
237
243
  **Comparison with standard plans:**
238
244
  - Standard plans: 1 commit per task, 2-4 commits per plan
239
245
  - TDD plans: 2-3 commits for single feature
240
246
 
241
- Both follow same format: `{type}({phase}-{plan}): {description}`
247
+ Both follow same format: `{type}({area}): {description}`, where `{area}` names the part of the codebase, plus the trailer `Phase: {phase}-{plan}`
242
248
 
243
249
  **Benefits:**
244
250
  - Each commit independently revertable
@@ -256,9 +262,9 @@ When `workflow.tdd_mode` is enabled in config, the RED/GREEN/REFACTOR gate seque
256
262
 
257
263
  | Gate | Required | Commit Pattern | Validation |
258
264
  |------|----------|---------------|------------|
259
- | RED | Yes | `test({phase}-{plan}): ...` | Test exists AND fails before implementation |
260
- | GREEN | Yes | `feat({phase}-{plan}): ...` | Test passes after implementation |
261
- | REFACTOR | No | `refactor({phase}-{plan}): ...` | Tests still pass after cleanup |
265
+ | RED | Yes | `test({area}): ...` + `Phase: {phase}-{plan}` | Test exists AND fails before implementation |
266
+ | GREEN | Yes | `feat({area}): ...` + `Phase: {phase}-{plan}` | Test passes after implementation |
267
+ | REFACTOR | No | `refactor({area}): ...` + `Phase: {phase}-{plan}` | Tests still pass after cleanup |
262
268
 
263
269
  ### Fail-Fast Rules
264
270
 
@@ -270,12 +276,10 @@ When `workflow.tdd_mode` is enabled in config, the RED/GREEN/REFACTOR gate seque
270
276
 
271
277
  After completing a `type: tdd` plan, the executor validates the git log:
272
278
  ```bash
273
- # Check for RED gate commit
274
- git log --oneline --grep="^test(${PHASE}-${PLAN})" | head -1
275
- # Check for GREEN gate commit
276
- git log --oneline --grep="^feat(${PHASE}-${PLAN})" | head -1
277
- # Check for optional REFACTOR gate commit
278
- git log --oneline --grep="^refactor(${PHASE}-${PLAN})" | head -1
279
+ # Gate commits for this plan: type from the subject, plan from the Phase trailer.
280
+ # Expect a test commit (RED), a feat commit (GREEN) and optionally a refactor commit.
281
+ git log --format='%h%x09%s%x09%(trailers:key=Phase,valueonly,separator=%x2C)' \
282
+ | awk -F'\t' -v id="${PHASE}-${PLAN}" '$2 ~ /^(test|feat|refactor)(\([^)]*\))?!?:/ && ($3 == id || index($2, "(" id "):") > 0)'
279
283
  ```
280
284
 
281
285
  If RED or GREEN gate commits are missing, add a `## TDD Gate Compliance` section to SUMMARY.md with the violation details.
@@ -22,6 +22,7 @@ skipping all worktree guards. The sentinel captures the spawn-time toplevel and
22
22
  detects drift before every commit.
23
23
 
24
24
  ```bash
25
+ [ -z "${ZSH_VERSION:-}" ] || emulate -R sh
25
26
  if [ -f .git ]; then # we are in a worktree
26
27
  WT_GIT_DIR=$(git rev-parse --git-dir 2>/dev/null)
27
28
  case "$WT_GIT_DIR" in
@@ -51,14 +51,14 @@ If MILESTONES.md doesn't exist, create it with header:
51
51
  - Minor bug fixes that don't constitute a release
52
52
 
53
53
  **Stats to include:**
54
- - Count modified files: `git diff --stat feat(XX-XX)..feat(YY-YY) | tail -1`
54
+ - Count modified files: `git diff --stat FIRST_SHA^..LAST_SHA | tail -1` (find a plan's commits with `git log --format=%h --grep="^Phase: XX-XX$"`)
55
55
  - Count LOC: `find . -name "*.swift" -o -name "*.ts" | xargs wc -l` (or relevant extension)
56
56
  - Phase/plan/task counts from ROADMAP
57
57
  - Timeline from first phase commit to last phase commit
58
58
 
59
59
  **Git range format:**
60
- - First commit of milestone → last commit of milestone
61
- - Example: `feat(01-01)` → `feat(04-01)` for phases 1-4
60
+ - First commit of milestone → last commit of milestone, each named by short sha and its `Phase:` trailer
61
+ - Example: `a1b2c3d` (Phase: 01-01) → `e4f5a6b` (Phase: 04-01) for phases 1-4
62
62
  </guidelines>
63
63
 
64
64
  <example>
@@ -83,7 +83,7 @@ If MILESTONES.md doesn't exist, create it with header:
83
83
  - 2 phases, 3 plans, 12 tasks
84
84
  - 8 days from v1.0 to v1.1
85
85
 
86
- **Git range:** `feat(05-01)` → `feat(06-02)`
86
+ **Git range:** `3c9d2e1` (Phase: 05-01) → `7f0a4b8` (Phase: 06-02)
87
87
 
88
88
  **What's next:** v2.0 SwiftUI redesign with widget support
89
89
 
@@ -108,7 +108,7 @@ If MILESTONES.md doesn't exist, create it with header:
108
108
  - 4 phases, 7 plans, 28 tasks
109
109
  - 12 days from start to ship
110
110
 
111
- **Git range:** `feat(01-01)` → `feat(04-01)`
111
+ **Git range:** `a1b2c3d` (Phase: 01-01) → `e4f5a6b` (Phase: 04-01)
112
112
 
113
113
  **What's next:** Security audit and hardening for v1.1
114
114
  ```
@@ -64,7 +64,7 @@ touch "${PHASE_DIR}/.gitkeep"
64
64
  ## Step 5: Commit
65
65
 
66
66
  ```bash
67
- pp_run query commit "docs: add backlog item ${NEXT} — ${ARGUMENTS}" --files .planning/ROADMAP.md "${PHASE_DIR}/.gitkeep"
67
+ pp_run query commit "docs(planning): add backlog item ${NEXT} — ${ARGUMENTS}" --files .planning/ROADMAP.md "${PHASE_DIR}/.gitkeep"
68
68
  ```
69
69
 
70
70
  ## Step 6: Report
@@ -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