@pareto4/pp-core 1.17.1 → 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.
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +5 -3
- package/agents/pp-code-fixer.md +9 -16
- package/agents/pp-code-reviewer.md +2 -78
- package/agents/pp-codebase-mapper.md +3 -0
- package/agents/pp-debugger.md +3 -2
- package/agents/pp-executor.md +25 -30
- package/agents/pp-integration-checker.md +1 -0
- package/agents/pp-phase-researcher.md +3 -1
- package/agents/pp-plan-checker.md +3 -0
- package/agents/pp-planner.md +16 -12
- package/agents/pp-research-synthesizer.md +1 -1
- package/agents/pp-ui-auditor.md +1 -0
- package/agents/pp-ui-researcher.md +3 -1
- package/agents/pp-vault-reviewer.md +43 -189
- package/agents/pp-verifier.md +10 -8
- package/commands/pp-add-tests.md +1 -1
- package/commands/pp-debug.md +1 -0
- package/commands/pp-init.md +4 -3
- package/commands/pp-ns-manage.md +1 -1
- package/commands/pp-ns-review.md +1 -1
- package/commands/pp-quick.md +3 -0
- package/commands/pp-review-backlog.md +2 -1
- package/commands/pp-vault-promote.md +7 -8
- package/commands/pp-vault-review.md +6 -7
- package/gemini-extension.json +1 -1
- package/package.json +3 -6
- package/pp-core/bin/lib/capability-registry.cjs +15 -357
- package/pp-core/bin/lib/capability-state.cjs +15 -79
- package/pp-core/bin/lib/capability-writer.cjs +2 -16
- package/pp-core/bin/lib/check-command-router.cjs +342 -2298
- package/pp-core/bin/lib/clusters.cjs +2 -2
- package/pp-core/bin/lib/commands.cjs +79 -4
- package/pp-core/bin/lib/compose-bindings.cjs +99 -16
- package/pp-core/bin/lib/config.cjs +3 -6
- package/pp-core/bin/lib/discovery-rollup.cjs +9 -6
- package/pp-core/bin/lib/discovery-screens.cjs +20 -2
- package/pp-core/bin/lib/discovery-sweep.cjs +12 -3
- package/pp-core/bin/lib/discovery-vault-check.cjs +37 -3
- package/pp-core/bin/lib/git-base-branch.cjs +10 -13
- package/pp-core/bin/lib/git-provider.cjs +5 -6
- package/pp-core/bin/lib/init-contract.cjs +55 -42
- package/pp-core/bin/lib/init-interactive.cjs +6 -20
- package/pp-core/bin/lib/io.cjs +2 -8
- package/pp-core/bin/lib/loop-resolver.cjs +8 -32
- package/pp-core/bin/lib/org-profile.cjs +16 -92
- package/pp-core/bin/lib/vault-command-router.cjs +174 -1206
- package/pp-core/bin/lib/vault-coordinates.cjs +4 -4
- package/pp-core/bin/lib/vault-index.cjs +44 -74
- package/pp-core/bin/lib/vault-seal.cjs +37 -122
- package/pp-core/bin/lib/vault-standards-promote.cjs +577 -0
- package/pp-core/bin/lib/vault-standards-review.cjs +293 -0
- package/pp-core/bin/lib/vault-standards.cjs +15 -16
- package/pp-core/bin/lib/vault-trace.cjs +40 -3016
- package/pp-core/bin/lib/vault-update.cjs +5 -26
- package/pp-core/bin/lib/vault.cjs +122 -316
- package/pp-core/bin/pp-tools.cjs +15 -36
- package/pp-core/org-profile.json +1 -1
- package/pp-core/references/autonomous-best-effort.md +4 -3
- package/pp-core/references/autonomous-lifecycle.md +1 -0
- package/pp-core/references/autonomous-smart-discuss.md +5 -1
- package/pp-core/references/discovery-id-conventions.md +35 -2
- package/pp-core/references/execute-mvp-tdd.md +3 -3
- package/pp-core/references/git-integration.md +57 -33
- package/pp-core/references/git-planning-commit.md +31 -9
- package/pp-core/references/phase-argument-parsing.md +1 -0
- package/pp-core/references/planner-gap-closure.md +1 -0
- package/pp-core/references/planner-revision.md +3 -1
- package/pp-core/references/planner-tdd.md +4 -4
- package/pp-core/references/planner-vault-standards.md +16 -25
- package/pp-core/references/planning-config.md +3 -3
- package/pp-core/references/shell-portability.md +28 -0
- package/pp-core/references/tdd.md +20 -16
- package/pp-core/references/worktree-path-safety.md +1 -0
- package/pp-core/templates/README.md +1 -1
- package/pp-core/templates/VAULT-REVIEW.md +24 -170
- package/pp-core/templates/milestone.md +5 -5
- package/pp-core/workflows/add-backlog.md +1 -1
- package/pp-core/workflows/add-tests.md +8 -5
- package/pp-core/workflows/add-todo.md +3 -1
- package/pp-core/workflows/ai-integration-phase.md +2 -1
- package/pp-core/workflows/audit-fix.md +7 -6
- package/pp-core/workflows/audit-milestone.md +1 -0
- package/pp-core/workflows/autonomous.md +6 -0
- package/pp-core/workflows/check-todos.md +2 -1
- package/pp-core/workflows/cleanup.md +3 -1
- package/pp-core/workflows/code-review-fix.md +15 -8
- package/pp-core/workflows/code-review.md +16 -58
- package/pp-core/workflows/complete-milestone.md +13 -3
- package/pp-core/workflows/debug.md +4 -2
- package/pp-core/workflows/diagnose-issues.md +1 -1
- package/pp-core/workflows/discovery-sprint/prototype.md +2 -2
- package/pp-core/workflows/discovery-sprint/session-13-gates.md +1 -1
- package/pp-core/workflows/discovery-sprint/sessions/01-kick-off.md +51 -7
- package/pp-core/workflows/discovery-sprint/sessions/02-as-is.md +5 -3
- package/pp-core/workflows/discovery-sprint/sessions/03-to-be.md +10 -8
- package/pp-core/workflows/discovery-sprint/sessions/04-ux-design.md +11 -2
- package/pp-core/workflows/discovery-sprint/sessions/05-architecture.md +5 -5
- package/pp-core/workflows/discovery-sprint/sessions/06-security.md +3 -3
- package/pp-core/workflows/discovery-sprint/sessions/07-identity.md +2 -2
- package/pp-core/workflows/discovery-sprint/sessions/08-integration.md +14 -2
- package/pp-core/workflows/discovery-sprint/sessions/09-qa.md +2 -2
- package/pp-core/workflows/discovery-sprint/sessions/10-infrastructure.md +10 -10
- package/pp-core/workflows/discovery-sprint/sessions/11-roadmap.md +11 -8
- package/pp-core/workflows/discovery-sprint/sessions/12-delivery-model.md +21 -18
- package/pp-core/workflows/discovery-sprint/sessions/13-wrap-up.md +5 -3
- package/pp-core/workflows/discovery-sprint/templates/context-template.md +9 -3
- package/pp-core/workflows/discovery-sprint/vault-context.md +17 -12
- package/pp-core/workflows/discovery-sprint.md +11 -8
- package/pp-core/workflows/discovery-to-build/steps/architecture-deliverables.md +1 -0
- package/pp-core/workflows/discuss-phase-assumptions.md +5 -3
- package/pp-core/workflows/discuss-phase.md +8 -3
- package/pp-core/workflows/docs-update.md +1 -0
- package/pp-core/workflows/eval-review.md +2 -1
- package/pp-core/workflows/execute-phase/steps/check-query-gate.md +13 -14
- package/pp-core/workflows/execute-phase/steps/cross-ai-delegation.md +1 -0
- package/pp-core/workflows/execute-phase/steps/execute-pre-dispatch.md +5 -25
- package/pp-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +1 -0
- package/pp-core/workflows/execute-phase/steps/vault-fetch.md +18 -6
- package/pp-core/workflows/execute-phase/steps/vault-load-gate.md +6 -109
- package/pp-core/workflows/execute-phase/steps/verify-post-gate.md +1 -17
- package/pp-core/workflows/execute-phase.md +21 -12
- package/pp-core/workflows/execute-plan.md +24 -15
- package/pp-core/workflows/explore.md +1 -1
- package/pp-core/workflows/forensics.md +4 -2
- package/pp-core/workflows/health.md +1 -0
- package/pp-core/workflows/help/modes/full.md +1 -1
- package/pp-core/workflows/import.md +2 -1
- package/pp-core/workflows/ingest-docs.md +1 -0
- package/pp-core/workflows/init/steps/client-context-capture.md +1 -0
- package/pp-core/workflows/init/steps/github-provisioning.md +145 -0
- package/pp-core/workflows/init/steps/gitlab-provisioning.md +18 -4
- package/pp-core/workflows/init/steps/reachability-outcome.md +3 -1
- package/pp-core/workflows/init.md +56 -66
- package/pp-core/workflows/map-codebase.md +5 -1
- package/pp-core/workflows/milestone-summary.md +2 -1
- package/pp-core/workflows/mvp-phase.md +1 -0
- package/pp-core/workflows/new-milestone.md +9 -5
- package/pp-core/workflows/new-project.md +9 -8
- package/pp-core/workflows/new-workspace.md +1 -0
- package/pp-core/workflows/next.md +2 -1
- package/pp-core/workflows/pause-work.md +6 -4
- package/pp-core/workflows/plan-milestone-gaps.md +3 -1
- package/pp-core/workflows/plan-phase/steps/chunked-planning.md +1 -1
- package/pp-core/workflows/plan-phase.md +21 -6
- package/pp-core/workflows/plan-review-convergence.md +2 -0
- package/pp-core/workflows/plant-seed.md +4 -2
- package/pp-core/workflows/pr-branch.md +2 -0
- package/pp-core/workflows/progress.md +5 -0
- package/pp-core/workflows/quick.md +19 -12
- package/pp-core/workflows/reapply-patches.md +3 -0
- package/pp-core/workflows/remove-phase.md +1 -1
- package/pp-core/workflows/resume-project.md +3 -0
- package/pp-core/workflows/review.md +7 -1
- package/pp-core/workflows/secure-phase.md +2 -1
- package/pp-core/workflows/session-report.md +1 -0
- package/pp-core/workflows/ship.md +8 -1
- package/pp-core/workflows/sketch-wrap-up.md +1 -1
- package/pp-core/workflows/sketch.md +3 -2
- package/pp-core/workflows/spec-phase.md +2 -1
- package/pp-core/workflows/spike-wrap-up.md +1 -1
- package/pp-core/workflows/spike.md +4 -3
- package/pp-core/workflows/sync-skills.md +5 -2
- package/pp-core/workflows/thread.md +3 -2
- package/pp-core/workflows/transition.md +6 -0
- package/pp-core/workflows/ui-phase.md +3 -1
- package/pp-core/workflows/ui-review.md +2 -1
- package/pp-core/workflows/ultraplan-phase.md +1 -0
- package/pp-core/workflows/undo.md +14 -10
- package/pp-core/workflows/update.md +5 -0
- package/pp-core/workflows/validate-phase.md +9 -6
- package/pp-core/workflows/vault-review.md +65 -186
- package/pp-core/workflows/vault-write-back.md +78 -110
- package/pp-core/workflows/verify-phase.md +5 -0
- package/pp-core/workflows/verify-work.md +9 -2
- package/scripts/gen-capability-registry.cjs +12 -93
- package/scripts/lint-test-file-count.allowlist.json +1 -19
- package/scripts/lint-test-file-count.cjs +5 -6
- package/scripts/prompt-injection-scan.sh +1 -4
- package/scripts/sync-runtime-launcher.cjs +115 -5
- package/pp-core/bin/lib/practices-review-check.cjs +0 -944
- package/pp-core/bin/lib/vault-audit.cjs +0 -2594
- package/pp-core/bin/lib/vault-mode.cjs +0 -235
- package/pp-core/bin/lib/vault-practices.cjs +0 -2057
- package/pp-core/bin/lib/vault-review.cjs +0 -2102
- package/pp-core/bin/lib/vault-write-back.cjs +0 -905
- package/pp-core/references/planner-vault-practices.md +0 -95
- package/pp-core/references/practice-arithmetic-contract.md +0 -121
- package/pp-core/references/verifier-practice-verdicts.md +0 -263
- package/pp-core/templates/practices/README.md +0 -248
- package/pp-core/templates/practices/error-handling.md +0 -18
- package/pp-core/templates/practices/minimal-comments.md +0 -14
- package/pp-core/templates/practices/naming-convention.md +0 -18
- package/pp-core/templates/practices/practice-template.md +0 -23
- package/pp-core/workflows/execute-phase/steps/verifier-practice-payload.md +0 -165
- package/scripts/gen-practice-arithmetic-contract.cjs +0 -412
- package/scripts/practice-arithmetic-contract.allow.json +0 -35
- package/scripts/record-vault-mode-golden.cjs +0 -89
- package/scripts/vault-calibrate.cjs +0 -996
|
@@ -75,13 +75,6 @@ fi
|
|
|
75
75
|
# STRICT-03: the enforcement policy. Read once, here, through the same resolver
|
|
76
76
|
# every other read path uses. With it off this file behaves exactly as it always has.
|
|
77
77
|
VAULT_REQUIRED=$(pp_run query config-get vault.required --raw --default false 2>/dev/null || echo false)
|
|
78
|
-
# STRICT-04: practice matching is separately activated. "Not enabled" and "zero
|
|
79
|
-
# matched" are different facts and must never be rendered the same way.
|
|
80
|
-
# Phase 15 D-25: asked of the SAME resolver the vault-practices gates use, at verify:post, where an
|
|
81
|
-
# UNFILTERED vault-practices gate (vault.audit) is declared in both vault modes, so this prints true
|
|
82
|
-
# exactly when the capability's gates render. A config-get read disagreed with the gates on the flat,
|
|
83
|
-
# string and root-true + workstream-empty shapes (15-RESEARCH C-1).
|
|
84
|
-
VAULT_PRACTICES_ENABLED=$(pp_run loop render-hooks verify:post --active-cap vault-practices 2>/dev/null || echo false)
|
|
85
78
|
# Detect --auto / --chain in host $ARGUMENTS. SURFACING ONLY — see below.
|
|
86
79
|
AUTO_MODE=false
|
|
87
80
|
if echo "${ARGUMENTS:-}" | grep -qE -- '--auto|--chain'; then AUTO_MODE=true; fi
|
|
@@ -116,109 +109,13 @@ hole this phase closes, so it is stated here rather than left to be re-derived.
|
|
|
116
109
|
|
|
117
110
|
---
|
|
118
111
|
|
|
119
|
-
## Practice clause (STRICT-04)
|
|
120
|
-
|
|
121
|
-
Appended to the **success** messages below when `VAULT_REQUIRED` is `true`. It is part of the
|
|
122
|
-
enforced gate's success line; with the policy off the messages are unchanged, which is what keeps
|
|
123
|
-
the byte-identical promise.
|
|
124
|
-
|
|
125
|
-
Compute it as follows, then substitute it as `${VAULT_PRACTICE_CLAUSE}`:
|
|
126
|
-
|
|
127
|
-
**Standards mode is decided first** (Phase 15 D-22). Ask the matcher once, before reading
|
|
128
|
-
`VAULT_PRACTICES_ENABLED`:
|
|
129
|
-
|
|
130
|
-
```bash
|
|
131
|
-
VAULT_PRACTICE_NA_JSON=$(pp_run vault practices match --raw 2>/dev/null || echo '{}')
|
|
132
|
-
VAULT_PRACTICE_NA_LINE=$(printf '%s' "$VAULT_PRACTICE_NA_JSON" | node -e "const d=require('fs').readFileSync(0,'utf-8');try{const r=JSON.parse(d);process.stdout.write(r.status==='not_applicable'&&typeof r.message==='string'?r.message:'');}catch{process.stdout.write('');}")
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
**If `VAULT_PRACTICE_NA_LINE` is non-empty** (standards mode: `vault practices match` answers
|
|
136
|
-
not-applicable whenever the vault gate is active, whatever `VAULT_PRACTICES_ENABLED` holds): print
|
|
137
|
-
`${VAULT_PRACTICE_NA_LINE}` verbatim as the card line, print NO number, and skip the rest of this
|
|
138
|
-
clause. The line comes from the engine and names the standards record and the gate that checks it.
|
|
139
|
-
"Practice matching is not enabled" would be a practices-mode sentence on a standards project, which
|
|
140
|
-
is the default standards shape (`vault.practices_enabled` off).
|
|
141
|
-
|
|
142
|
-
Otherwise (practices mode) continue below.
|
|
143
|
-
|
|
144
|
-
**If `VAULT_PRACTICES_ENABLED` != `true`:**
|
|
145
|
-
|
|
146
|
-
> practice matching is not enabled for this project
|
|
147
|
-
|
|
148
|
-
Emit no number on this branch. Zero-matched and matching-not-running are different facts, and
|
|
149
|
-
reporting `0` for the second is the reassuring-but-false signal this phase removes.
|
|
150
|
-
|
|
151
|
-
**Otherwise, at `VAULT_GATE_POINT` == `execute`** — the phase's plans exist, so the count is
|
|
152
|
-
phase-scoped, which is what STRICT-04 asks for:
|
|
153
|
-
|
|
154
|
-
```bash
|
|
155
|
-
VAULT_PRACTICE_PATHS=$(pp_run query phase-plan-index "${PHASE_NUMBER}" --raw 2>/dev/null | node -e "const d=require('fs').readFileSync(0,'utf-8');try{const s=new Set();for(const p of (JSON.parse(d).plans||[]))for(const f of (p.files_modified||[]))s.add(f);process.stdout.write(Array.from(s).slice(0,200).join('\n'));}catch{process.stdout.write('');}")
|
|
156
|
-
VAULT_PRACTICE_PATH_COUNT=$(printf '%s' "$VAULT_PRACTICE_PATHS" | grep -c . || echo 0)
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
Pass those paths **positionally** to the match arm — never `--changed`, which would scope to the
|
|
160
|
-
working tree rather than to the phase:
|
|
161
|
-
|
|
162
|
-
`pp_run` is a shell FUNCTION, and `xargs` execs a binary — it can never invoke one. The previous
|
|
163
|
-
form here piped into `xargs -r pp_run …`, whose failure was swallowed by `2>/dev/null` and answered
|
|
164
|
-
by the `|| echo '{}'` fallback, so this clause reported **`0` practices matched on every run**, in
|
|
165
|
-
bash and zsh alike, with nothing to indicate it had not looked. That is the reassuring-but-false
|
|
166
|
-
signal the branch above exists to remove, arriving by a different door: STRICT-04 asks how many
|
|
167
|
-
practices applied to this phase, and a false zero answers it wrongly. The paths therefore go
|
|
168
|
-
straight to the function as positionals, the way `code-review.md` already calls the same arm
|
|
169
|
-
(02-SECURITY T-02-36).
|
|
170
|
-
|
|
171
|
-
```bash
|
|
172
|
-
VAULT_PRACTICE_ARGS=()
|
|
173
|
-
while IFS= read -r _p; do [ -n "$_p" ] && VAULT_PRACTICE_ARGS+=("$_p"); done <<< "$VAULT_PRACTICE_PATHS"
|
|
174
|
-
if [ ${#VAULT_PRACTICE_ARGS[@]} -gt 0 ]; then
|
|
175
|
-
VAULT_PRACTICE_JSON=$(pp_run vault practices match "${VAULT_PRACTICE_ARGS[@]}" --raw 2>/dev/null || echo '{}')
|
|
176
|
-
else
|
|
177
|
-
VAULT_PRACTICE_JSON=$(pp_run vault practices match --raw 2>/dev/null | node -e "const d=require('fs').readFileSync(0,'utf-8');try{process.stdout.write(JSON.parse(d).status==='not_applicable'?d:'{}');}catch{process.stdout.write('{}');}")
|
|
178
|
-
fi
|
|
179
|
-
VAULT_PRACTICE_MATCHED=$(printf '%s' "$VAULT_PRACTICE_JSON" | node -e "const d=require('fs').readFileSync(0,'utf-8');try{const r=JSON.parse(d);process.stdout.write(r.status==='not_applicable'?'NA':String((r.matched||[]).length+(r.global||[]).length));}catch{process.stdout.write('0');}")
|
|
180
|
-
VAULT_PRACTICE_NA_LINE=$(printf '%s' "$VAULT_PRACTICE_JSON" | node -e "const d=require('fs').readFileSync(0,'utf-8');try{const r=JSON.parse(d);process.stdout.write(r.status==='not_applicable'&&typeof r.message==='string'?r.message:'');}catch{process.stdout.write('');}")
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
The path list is capped at **200** entries. When `VAULT_PRACTICE_PATH_COUNT` is `200`, the phase is
|
|
184
|
-
wider than the bound and the clause must say so rather than present a truncated number as complete:
|
|
185
|
-
|
|
186
|
-
> more than 200 files in scope — practice count not computed for this phase
|
|
187
|
-
|
|
188
|
-
Otherwise:
|
|
189
|
-
|
|
190
|
-
> `${VAULT_PRACTICE_MATCHED}` client practices apply to this phase
|
|
191
|
-
|
|
192
|
-
**Otherwise, at `VAULT_GATE_POINT` == `plan`** — no phase scope exists yet, because the plans this
|
|
193
|
-
count would be scoped to are the ones about to be written. Report what is true at this point and
|
|
194
|
-
name when the scoped number arrives; do not fake a phase-scoped count and do not silently omit it:
|
|
195
|
-
|
|
196
|
-
```bash
|
|
197
|
-
VAULT_PRACTICE_JSON=$(pp_run vault practices match --raw 2>/dev/null || echo '{}')
|
|
198
|
-
VAULT_PRACTICE_TOTAL=$(printf '%s' "$VAULT_PRACTICE_JSON" | node -e "const d=require('fs').readFileSync(0,'utf-8');try{const r=JSON.parse(d);process.stdout.write(r.status==='not_applicable'?'NA':String(r.practicesProcessed??0));}catch{process.stdout.write('0');}")
|
|
199
|
-
VAULT_PRACTICE_NA_LINE=$(printf '%s' "$VAULT_PRACTICE_JSON" | node -e "const d=require('fs').readFileSync(0,'utf-8');try{const r=JSON.parse(d);process.stdout.write(r.status==='not_applicable'&&typeof r.message==='string'?r.message:'');}catch{process.stdout.write('');}")
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
> the vault carries `` `${VAULT_PRACTICE_TOTAL}` `` practices at this ref; the phase-scoped matched count is reported at execute:pre once plans exist
|
|
203
|
-
|
|
204
|
-
Each fence above assigns `VAULT_PRACTICE_JSON` itself before reading it — the two points never run
|
|
205
|
-
in one gate, so neither fence reads the other's envelope. With no phase paths the execute fence
|
|
206
|
-
still asks the matcher but keeps only a `not_applicable` answer, so practices mode still counts `0`.
|
|
207
|
-
|
|
208
|
-
**If `VAULT_PRACTICE_MATCHED` (at execute) or `VAULT_PRACTICE_TOTAL` (at plan) is `NA`:** print
|
|
209
|
-
`${VAULT_PRACTICE_NA_LINE}` verbatim as the card line, instead of the count line or the 200-file
|
|
210
|
-
line, and print NO number — the envelope names the mode (`vault.mode = standards`); a count here would be the false
|
|
211
|
-
"0 client practices apply" STRICT-04 forbids.
|
|
212
|
-
|
|
213
|
-
---
|
|
214
|
-
|
|
215
112
|
## §8 Message table — plan:pre column (`VAULT_GATE_POINT` == `plan`)
|
|
216
113
|
|
|
217
114
|
**`fetched` + `tier: client`:**
|
|
218
115
|
|
|
219
116
|
> Client vault loaded from `` `${VAULT_REPO}@${VAULT_REF}` `` (`` `${VAULT_FILE_COUNT}` `` files, sha `` `${VAULT_SHA}` ``). Planning will apply client standards.
|
|
220
117
|
|
|
221
|
-
When `VAULT_REQUIRED` is `true`,
|
|
118
|
+
When `VAULT_REQUIRED` is `true`, skip the confirmation.
|
|
222
119
|
Otherwise surface this message and require an explicit `confirmed` acknowledgment
|
|
223
120
|
(`AskUserQuestion`, or a typed `confirmed` in TEXT_MODE).
|
|
224
121
|
|
|
@@ -240,9 +137,9 @@ Surface this warning and require an explicit `confirmed` acknowledgment (`AskUse
|
|
|
240
137
|
|
|
241
138
|
Surface this warning and require an explicit `confirmed` acknowledgment (`AskUserQuestion`, or a typed `confirmed` in TEXT_MODE). With `VAULT_REQUIRED` on, this state has already been stopped by the enforcer and is unreachable here.
|
|
242
139
|
|
|
243
|
-
**`degraded`** (
|
|
140
|
+
**`degraded`** (the vault loaded but its `INDEX.md` is missing, unparseable, empty or names no file in the fetched tree, or the engine could not check it at all (`vault_index_unchecked`: the cached manifest records no file list, or the check faulted — this says nothing about `INDEX.md` itself); `check vault.status` sets `status: degraded` and a `reason` of the form `vault_index_*`):
|
|
244
141
|
|
|
245
|
-
Print `${VAULT_MESSAGE}` verbatim — the engine built it; do not restate or paraphrase it here. With `VAULT_REQUIRED` false it is the degraded-index warning, naming `INDEX.md`, what was measured and the repair: surface it and require an explicit `confirmed` acknowledgment (`AskUserQuestion`, or a typed `confirmed` in TEXT_MODE). With `VAULT_REQUIRED` true this row is reachable only after an accepted attributed override (`PP_VAULT_OVERRIDE_REASON`) suppressed the block at the enforcer (D-25), and the message is the override notice naming the suppressed `vault_index_*` reason (or the block text naming `INDEX.md`, if the override reached only the enforcer's own call): print it and the envelope's `override` record when present, and continue without a prompt — the override is the acknowledgment and is already recorded in the envelope the enforcer acted on.
|
|
142
|
+
Print `${VAULT_MESSAGE}` verbatim — the engine built it; do not restate or paraphrase it here. With `VAULT_REQUIRED` false it is the degraded-index warning, naming `INDEX.md`, what was measured and the repair: surface it and require an explicit `confirmed` acknowledgment (`AskUserQuestion`, or a typed `confirmed` in TEXT_MODE). With `VAULT_REQUIRED` true this row is reachable only after an accepted attributed override (`PP_VAULT_OVERRIDE_REASON`) suppressed the block at the enforcer (D-25), and the message is the override notice naming the suppressed `vault_index_*` reason (or the block text naming `INDEX.md`, if the override reached only the enforcer's own call): print it and the envelope's `override` record when present, and continue without a prompt — the override is the acknowledgment and is already recorded in the envelope the enforcer acted on. Planning proceeds without a usable index; the `## INDEX` section of `.planning/vault/SUMMARY.md` names the degradation.
|
|
246
143
|
|
|
247
144
|
---
|
|
248
145
|
|
|
@@ -255,7 +152,7 @@ Until this phase, nothing dispatched this column at all — it was written and n
|
|
|
255
152
|
|
|
256
153
|
> Client vault present from `` `${VAULT_REPO}@${VAULT_REF}` `` (`` `${VAULT_FILE_COUNT}` `` files, sha `` `${VAULT_SHA}` ``). Build will apply client patterns.
|
|
257
154
|
|
|
258
|
-
When `VAULT_REQUIRED` is `true`,
|
|
155
|
+
When `VAULT_REQUIRED` is `true`, skip the confirmation.
|
|
259
156
|
Otherwise surface this message and require an explicit `confirmed` acknowledgment
|
|
260
157
|
(`AskUserQuestion`, or a typed `confirmed` in TEXT_MODE).
|
|
261
158
|
|
|
@@ -277,9 +174,9 @@ Surface this warning and require an explicit `confirmed` acknowledgment (`AskUse
|
|
|
277
174
|
|
|
278
175
|
Surface this warning and require an explicit `confirmed` acknowledgment (`AskUserQuestion`, or a typed `confirmed` in TEXT_MODE). With `VAULT_REQUIRED` on, this state has already been stopped by the enforcer and is unreachable here.
|
|
279
176
|
|
|
280
|
-
**`degraded`** (
|
|
177
|
+
**`degraded`** (the vault loaded but its `INDEX.md` is missing, unparseable, empty or names no file in the fetched tree, or the engine could not check it at all (`vault_index_unchecked`: the cached manifest records no file list, or the check faulted — this says nothing about `INDEX.md` itself); `check vault.status` sets `status: degraded` and a `reason` of the form `vault_index_*`):
|
|
281
178
|
|
|
282
|
-
Print `${VAULT_MESSAGE}` verbatim — the engine built it; do not restate or paraphrase it here. With `VAULT_REQUIRED` false it is the degraded-index warning, naming `INDEX.md`, what was measured and the repair: surface it and require an explicit `confirmed` acknowledgment (`AskUserQuestion`, or a typed `confirmed` in TEXT_MODE). With `VAULT_REQUIRED` true this row is reachable only after an accepted attributed override (`PP_VAULT_OVERRIDE_REASON`) suppressed the block at the enforcer (D-25), and the message is the override notice naming the suppressed `vault_index_*` reason (or the block text naming `INDEX.md`, if the override reached only the enforcer's own call): print it and the envelope's `override` record when present, and continue without a prompt — the override is the acknowledgment and is already recorded in the envelope the enforcer acted on.
|
|
179
|
+
Print `${VAULT_MESSAGE}` verbatim — the engine built it; do not restate or paraphrase it here. With `VAULT_REQUIRED` false it is the degraded-index warning, naming `INDEX.md`, what was measured and the repair: surface it and require an explicit `confirmed` acknowledgment (`AskUserQuestion`, or a typed `confirmed` in TEXT_MODE). With `VAULT_REQUIRED` true this row is reachable only after an accepted attributed override (`PP_VAULT_OVERRIDE_REASON`) suppressed the block at the enforcer (D-25), and the message is the override notice naming the suppressed `vault_index_*` reason (or the block text naming `INDEX.md`, if the override reached only the enforcer's own call): print it and the envelope's `override` record when present, and continue without a prompt — the override is the acknowledgment and is already recorded in the envelope the enforcer acted on. Build proceeds without a usable index; the `## INDEX` section of `.planning/vault/SUMMARY.md` names the degradation.
|
|
283
180
|
|
|
284
181
|
---
|
|
285
182
|
|
|
@@ -124,22 +124,6 @@ mid-lifecycle state it is at `plan:post` and `execute:wave:post`. The obligation
|
|
|
124
124
|
next caller: if one ever grows a partial-execution mode, it owes this condition the same two tests
|
|
125
125
|
the host already answers, written here rather than assumed at the call site.
|
|
126
126
|
|
|
127
|
-
**Before the enforcer runs, close the phase's range.** Run
|
|
128
|
-
`pp_run vault manifest record "${PHASE_DIR}" --raw`, print its one-line result, and continue
|
|
129
|
-
regardless. It writes `phases[<phase>].commits` = `git rev-list --reverse --no-merges
|
|
130
|
-
<startCommit>..HEAD` beside the anchor item 4 of `execute-pre-dispatch.md` recorded, so the
|
|
131
|
-
`vault.audit` gate dispatched next and `/pp-undo` read one list. A phase with no anchor (built
|
|
132
|
-
before the anchor existed) answers `start-not-recorded`, which is exactly the case the audit's
|
|
133
|
-
trace-digest fallback covers. `/pp-verify-work` reaches this file with `${PHASE_DIR}` bound too.
|
|
134
|
-
|
|
135
|
-
**Then commit the recorded manifest.** Only when that result's `ok` is `true`, run
|
|
136
|
-
`pp_run query commit "docs(phase-<phase>): record phase manifest" --files "<manifestPath>"`, with
|
|
137
|
-
`<phase>` and `<manifestPath>` taken from the same result (`manifestPath` is root-relative). Print the
|
|
138
|
-
outcome and continue on every path. Without this, a project that commits `.planning/` keeps the
|
|
139
|
-
manifest untracked and `/pp-ship`'s clean-tree preflight asks about it every time. The commit verb
|
|
140
|
-
itself skips on `commit_docs: false` and on a gitignored `.planning/`, so no guard is added here. A
|
|
141
|
-
`nothing_to_commit` or failed commit is printed, never retried with raw `git`, and never halts.
|
|
142
|
-
|
|
143
127
|
Then Read and follow `pp-core/workflows/execute-phase/steps/check-query-gate.md` — the single
|
|
144
128
|
generic `check.query` gate enforcer (GATE-02, D-VH-7). **It owns the halt decision**, the two-step
|
|
145
129
|
contract and the `message` passthrough. Do not restate its loop here, and do not interpret its
|
|
@@ -160,4 +144,4 @@ certifies nothing, which only widens the next phase's SEAL-01 reach and never hi
|
|
|
160
144
|
The verb prints nothing unless `vault admission` answers `on` (no `.platform-bindings.json`, or the
|
|
161
145
|
vault off), so print nothing yourself then either. Every result (a certificate, `kept`, or a
|
|
162
146
|
refusal such as `not-clean` or `overridden`) is printed, never retried, and never halts. No bash fence: this file carries one
|
|
163
|
-
launcher preamble, in the admission fence, and this step
|
|
147
|
+
launcher preamble, in the admission fence, and this step needs no second one.
|
|
@@ -179,6 +179,7 @@ fi
|
|
|
179
179
|
|
|
180
180
|
Resolve `MVP_MODE` once via the centralized `phase.mvp-mode` query verb (precedence chain: CLI flag → ROADMAP `**Mode:** mvp` → `workflow.mvp_mode` config → false):
|
|
181
181
|
```bash
|
|
182
|
+
[ -z "${ZSH_VERSION:-}" ] || emulate -R sh
|
|
182
183
|
MVP_FLAG_ARG=""
|
|
183
184
|
if [[ "$ARGUMENTS" =~ (^|[[:space:]])--mvp([[:space:]]|$) ]]; then MVP_FLAG_ARG="--cli-flag"; fi
|
|
184
185
|
MVP_MODE=$(pp_run query phase.mvp-mode "${PHASE_NUMBER}" $MVP_FLAG_ARG --pick active)
|
|
@@ -218,7 +219,10 @@ Offer these recovery options:
|
|
|
218
219
|
if [ "$MVP_MODE" = "true" ] && [ "$TDD_MODE" = "true" ]; then
|
|
219
220
|
IS_BEHAVIOR_ADDING=$(pp_run query task.is-behavior-adding "$TASK_FILE" --pick is_behavior_adding)
|
|
220
221
|
if [ "$IS_BEHAVIOR_ADDING" = "true" ]; then
|
|
221
|
-
|
|
222
|
+
# A `test` commit (any scope) whose `Phase:` trailer is this plan; a `test(<plan>):`
|
|
223
|
+
# subject from before the trailer convention still counts.
|
|
224
|
+
RED_COMMIT=$(git log --format='%h%x09%s%x09%(trailers:key=Phase,valueonly,separator=%x2C)' -- "**/*.test.*" "**/*.spec.*" "tests/" \
|
|
225
|
+
| awk -F'\t' -v id="${PHASE_NUMBER}-${PLAN_ID}" '$2 ~ /^test(\([^)]*\))?!?:/ && ($3 == id || index($2, "(" id "):") > 0) { print; exit }')
|
|
222
226
|
if [ -z "$RED_COMMIT" ]; then
|
|
223
227
|
pp_run query state.update last_gate_trip "${PLAN_ID}/${TASK_ID}" || true
|
|
224
228
|
echo "MVP+TDD GATE TRIPPED: missing RED commit for ${PLAN_ID}/${TASK_ID}"
|
|
@@ -236,6 +240,7 @@ Pure doc-only / config-only / test-only tasks return `is_behavior_adding=false`
|
|
|
236
240
|
Look for a `.continue-here.md` in the current phase directory:
|
|
237
241
|
|
|
238
242
|
```bash
|
|
243
|
+
[ -z "${ZSH_VERSION:-}" ] || emulate -R sh
|
|
239
244
|
ls ${phase_dir}/.continue-here.md 2>/dev/null || true
|
|
240
245
|
```
|
|
241
246
|
|
|
@@ -286,8 +291,8 @@ checkpoints between tasks. The user can review, modify, or redirect work at any
|
|
|
286
291
|
c. **If "Execute":** Read and follow `~/.claude/pp-core/workflows/execute-plan.md` **inline**
|
|
287
292
|
(do NOT spawn a subagent). Execute tasks one at a time.
|
|
288
293
|
The inline executor follows `EXECUTOR_HOOK_FRAGMENTS` (computed in the hooks fence above) as
|
|
289
|
-
its contract exactly as a spawned executor would:
|
|
290
|
-
|
|
294
|
+
its contract exactly as a spawned executor would: it is the vault's execute:pre executor
|
|
295
|
+
fragment.
|
|
291
296
|
|
|
292
297
|
d. **After each task:** Pause briefly. If the user intervenes (types anything), stop and address
|
|
293
298
|
their feedback before continuing. Otherwise proceed to next task.
|
|
@@ -755,6 +760,7 @@ increases monotonically across waves. `{status}` is `complete` (success),
|
|
|
755
760
|
rerun the same command. Do not fall back to broad worktree discovery.
|
|
756
761
|
|
|
757
762
|
```bash
|
|
763
|
+
[ -z "${ZSH_VERSION:-}" ] || emulate -R sh
|
|
758
764
|
[ -n "${WAVE_WORKTREE_MANIFEST:-}" ] && [ -f "$WAVE_WORKTREE_MANIFEST" ] || {
|
|
759
765
|
echo "BLOCKED: missing WAVE_WORKTREE_MANIFEST; refusing broad worktree cleanup (#3384)." >&2
|
|
760
766
|
exit 1
|
|
@@ -784,6 +790,7 @@ increases monotonically across waves. `{status}` is `complete` (success),
|
|
|
784
790
|
If the orchestrator deviated from the standard wave merge path (e.g., custom inter-worktree base-update merges with `merge: bring …` style messages), run this snippet after the custom merges are complete. It reads only `WAVE_WORKTREE_MANIFEST`; do not discover unrelated `worktree-agent-*` worktrees.
|
|
785
791
|
|
|
786
792
|
```bash
|
|
793
|
+
[ -z "${ZSH_VERSION:-}" ] || emulate -R sh
|
|
787
794
|
# Cleanup-tail: pin orchestrator CWD to its OWN worktree before cleanup-tail (#3174, #630).
|
|
788
795
|
# Same fix as the templated path: resolve the dispatch-time orchestrator root from the manifest,
|
|
789
796
|
# not `git worktree list`'s first entry (always the main checkout — wrong for a lane orchestrator).
|
|
@@ -858,7 +865,7 @@ increases monotonically across waves. `{status}` is `complete` (success),
|
|
|
858
865
|
|
|
859
866
|
# Only commit tracking files if they actually changed
|
|
860
867
|
if ! git diff --quiet .planning/ROADMAP.md .planning/STATE.md 2>/dev/null; then
|
|
861
|
-
pp_run query commit "docs(
|
|
868
|
+
pp_run query commit "docs(planning): update tracking after wave ${N}" --phase "${PHASE_NUMBER}" --files .planning/ROADMAP.md .planning/STATE.md
|
|
862
869
|
fi
|
|
863
870
|
elif [ "${TEST_EXIT}" -eq 124 ]; then
|
|
864
871
|
echo "⚠ Skipping tracking update — test suite timed out. Plans remain in-progress. Run tests manually to confirm."
|
|
@@ -1062,6 +1069,7 @@ After all waves:
|
|
|
1062
1069
|
|
|
1063
1070
|
**Security gate check:**
|
|
1064
1071
|
```bash
|
|
1072
|
+
[ -z "${ZSH_VERSION:-}" ] || emulate -R sh
|
|
1065
1073
|
VERIFY_POST_HOOKS_JSON=$(pp_run loop render-hooks verify:post --raw)
|
|
1066
1074
|
printf '%s' "$VERIFY_POST_HOOKS_JSON" | node -e "let h=[];try{h=JSON.parse(require('fs').readFileSync(0,'utf-8')).activeHooks||[]}catch{}console.log('VERIFY_POST_HOOKS_JSON='+JSON.stringify({activeHooks:h}))"
|
|
1067
1075
|
SECURITY_FILE=$(ls "${PHASE_DIR}"/*-SECURITY.md 2>/dev/null | head -1)
|
|
@@ -1213,7 +1221,8 @@ mv .planning/debug/{slug}.md .planning/debug/resolved/
|
|
|
1213
1221
|
|
|
1214
1222
|
**6. Commit updated artifacts:**
|
|
1215
1223
|
```bash
|
|
1216
|
-
|
|
1224
|
+
[ -z "${ZSH_VERSION:-}" ] || emulate -R sh
|
|
1225
|
+
pp_run query commit "docs(planning): resolve UAT gaps and debug sessions after ${PHASE_NUMBER} gap closure" --phase "${PARENT_PHASE}" --files .planning/phases/*${PARENT_PHASE}*/*-UAT.md .planning/debug/resolved/*.md
|
|
1217
1226
|
```
|
|
1218
1227
|
</step>
|
|
1219
1228
|
|
|
@@ -1291,8 +1300,6 @@ Verify phase achieved its GOAL, not just completed tasks.
|
|
|
1291
1300
|
VERIFIER_SKILLS=$(pp_run query agent-skills pp-verifier)
|
|
1292
1301
|
```
|
|
1293
1302
|
|
|
1294
|
-
Read and execute `execute-phase/steps/verifier-practice-payload.md` (sets `PRACTICE_VERDICT_INPUT`).
|
|
1295
|
-
|
|
1296
1303
|
```
|
|
1297
1304
|
Agent(
|
|
1298
1305
|
description="Verify phase {phase_number} goal achievement",
|
|
@@ -1315,7 +1322,6 @@ ${CONTEXT_WINDOW >= 500000 ? `- Prior VERIFICATION.md files from earlier phases
|
|
|
1315
1322
|
` : ''}
|
|
1316
1323
|
</files_to_read>
|
|
1317
1324
|
|
|
1318
|
-
${PRACTICE_VERDICT_INPUT}
|
|
1319
1325
|
${VERIFIER_SKILLS}",
|
|
1320
1326
|
subagent_type="pp-verifier",
|
|
1321
1327
|
model="{verifier_model}"
|
|
@@ -1379,7 +1385,7 @@ blocked: 0
|
|
|
1379
1385
|
|
|
1380
1386
|
Commit the file:
|
|
1381
1387
|
```bash
|
|
1382
|
-
pp_run query commit "
|
|
1388
|
+
pp_run query commit "docs(planning): persist human verification items as UAT" --phase "{phase_num}" --files "{phase_dir}/{phase_num}-UAT.md"
|
|
1383
1389
|
```
|
|
1384
1390
|
|
|
1385
1391
|
**Step B: Present to user:**
|
|
@@ -1459,7 +1465,8 @@ These items are tracked and will appear in `/pp:progress` and `/pp:audit-uat`.
|
|
|
1459
1465
|
```
|
|
1460
1466
|
|
|
1461
1467
|
```bash
|
|
1462
|
-
|
|
1468
|
+
[ -z "${ZSH_VERSION:-}" ] || emulate -R sh
|
|
1469
|
+
pp_run query commit "docs(planning): complete phase execution" --phase "{X}" --files .planning/ROADMAP.md .planning/STATE.md .planning/REQUIREMENTS.md {phase_dir}/*-VERIFICATION.md
|
|
1463
1470
|
```
|
|
1464
1471
|
</step>
|
|
1465
1472
|
|
|
@@ -1492,6 +1499,7 @@ Copy failure must NOT block phase completion.
|
|
|
1492
1499
|
This step runs AFTER `update_roadmap` marks the phase complete. It moves any pending todos that carry `resolves_phase: <current-phase-number>` to the completed directory.
|
|
1493
1500
|
|
|
1494
1501
|
```bash
|
|
1502
|
+
[ -z "${ZSH_VERSION:-}" ] || emulate -R sh
|
|
1495
1503
|
PHASE_NUM="${PHASE_NUMBER}"
|
|
1496
1504
|
PENDING_DIR=".planning/todos/pending"
|
|
1497
1505
|
COMPLETED_DIR=".planning/todos/completed"
|
|
@@ -1509,7 +1517,7 @@ for TODO_FILE in "$PENDING_DIR"/*.md; do
|
|
|
1509
1517
|
done
|
|
1510
1518
|
|
|
1511
1519
|
if [ ${#CLOSED[@]} -gt 0 ]; then
|
|
1512
|
-
pp_run query commit "docs(
|
|
1520
|
+
pp_run query commit "docs(planning): auto-close ${#CLOSED[@]} todo(s) resolved by this phase" --phase "${PHASE_NUMBER}" --files .planning/todos/completed/ .planning/STATE.md|| true
|
|
1513
1521
|
echo "◆ Closed ${#CLOSED[@]} todo(s) resolved by Phase ${PHASE_NUMBER}:"
|
|
1514
1522
|
for f in "${CLOSED[@]}"; do echo " ✓ $f"; done
|
|
1515
1523
|
fi
|
|
@@ -1534,7 +1542,7 @@ PROJECT.md falls behind silently over multiple phases.
|
|
|
1534
1542
|
5. Commit the change:
|
|
1535
1543
|
|
|
1536
1544
|
```bash
|
|
1537
|
-
pp_run query commit "docs(
|
|
1545
|
+
pp_run query commit "docs(planning): evolve PROJECT.md after phase completion" --phase "{X}" --files .planning/PROJECT.md
|
|
1538
1546
|
```
|
|
1539
1547
|
|
|
1540
1548
|
**Skip this step if** `.planning/PROJECT.md` does not exist.
|
|
@@ -1597,6 +1605,7 @@ Read and follow `~/.claude/pp-core/workflows/transition.md`, passing through the
|
|
|
1597
1605
|
Check whether CONTEXT.md already exists for the next phase:
|
|
1598
1606
|
|
|
1599
1607
|
```bash
|
|
1608
|
+
[ -z "${ZSH_VERSION:-}" ] || emulate -R sh
|
|
1600
1609
|
ls .planning/phases/*{next}*/{next}-CONTEXT.md 2>/dev/null || echo "no-context"
|
|
1601
1610
|
```
|
|
1602
1611
|
|
|
@@ -72,12 +72,13 @@ case "$VAULT_ADMIT" in on) echo "VAULT_ADMIT=on" ;; off|inert) : ;; *) pp_run va
|
|
|
72
72
|
step silently and continue. Print nothing: a non-Pareto or `vault.enabled=false` project runs this
|
|
73
73
|
workflow byte-identically to how it ran before this gate existed (GATE-04).
|
|
74
74
|
|
|
75
|
-
**Otherwise, the load gate, in hook mode.** Render `execute:pre` and keep only the `vault`
|
|
76
|
-
|
|
75
|
+
**Otherwise, the load gate, in hook mode.** Render `execute:pre` and keep only the `vault`
|
|
76
|
+
hooks, mechanically in the fence (D-30): no other capability's hook is run or
|
|
77
77
|
injected here, because execute-phase's dispatcher owns those for its own run.
|
|
78
78
|
|
|
79
79
|
```bash
|
|
80
|
-
|
|
80
|
+
[ -z "${ZSH_VERSION:-}" ] || emulate -R sh
|
|
81
|
+
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('');}")
|
|
81
82
|
printf '%s' "$EXECUTE_PRE_HOOKS_JSON" | node -e "let h=[];try{h=JSON.parse(require('fs').readFileSync(0,'utf-8')).activeHooks||[]}catch{}console.log('EXECUTE_PRE_HOOKS_JSON='+JSON.stringify({activeHooks:h}))"
|
|
82
83
|
```
|
|
83
84
|
|
|
@@ -91,6 +92,7 @@ the two-step contract, the halt and the message passthrough; none of them are re
|
|
|
91
92
|
|
|
92
93
|
<step name="identify_plan">
|
|
93
94
|
```bash
|
|
95
|
+
[ -z "${ZSH_VERSION:-}" ] || emulate -R sh
|
|
94
96
|
# Use plans/summaries from INIT JSON, or list files
|
|
95
97
|
(ls .planning/phases/XX-name/*-PLAN.md 2>/dev/null || true) | sort
|
|
96
98
|
(ls .planning/phases/XX-name/*-SUMMARY.md 2>/dev/null || true) | sort
|
|
@@ -115,14 +117,15 @@ Present plan identification, wait for confirmation.
|
|
|
115
117
|
</step>
|
|
116
118
|
|
|
117
119
|
<step name="vault_trace_gate">
|
|
118
|
-
This gate judges the ONE plan this run executes (D-06, D-38): a plan with no
|
|
119
|
-
`<vault_standards>` record is blocked (`
|
|
120
|
+
This gate judges the ONE plan this run executes (D-06, D-38): a plan with no
|
|
121
|
+
`<vault_standards>` record is blocked (`standards_block_absent`), never
|
|
120
122
|
rendered as nothing. Skip this step silently unless the admission step printed `VAULT_ADMIT=on`. The
|
|
121
123
|
positional is the plan file, not its phase directory: sibling plans mid-wave are not this run's
|
|
122
124
|
business, and `check vault.trace <plan file> --stage plan` by hand gives this gate's verdict.
|
|
123
125
|
|
|
124
126
|
```bash
|
|
125
|
-
|
|
127
|
+
[ -z "${ZSH_VERSION:-}" ] || emulate -R sh
|
|
128
|
+
PLAN_POST_HOOKS_JSON=$(pp_run loop render-hooks plan:post --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('');}")
|
|
126
129
|
printf '%s' "$PLAN_POST_HOOKS_JSON" | node -e "let h=[];try{h=JSON.parse(require('fs').readFileSync(0,'utf-8')).activeHooks||[]}catch{}console.log('PLAN_POST_HOOKS_JSON='+JSON.stringify({activeHooks:h}))"
|
|
127
130
|
```
|
|
128
131
|
|
|
@@ -312,9 +315,11 @@ End with: **Total deviations:** N auto-fixed (breakdown). **Impact:** assessment
|
|
|
312
315
|
For `type: tdd` plans — RED-GREEN-REFACTOR:
|
|
313
316
|
|
|
314
317
|
1. **Infrastructure** (first TDD plan only): detect project, install framework, config, verify empty suite
|
|
315
|
-
2. **RED:** Read `<behavior>` → failing test(s) → run (MUST fail) → commit: `test({
|
|
316
|
-
3. **GREEN:** Read `<implementation>` → minimal code → run (MUST pass) → commit: `feat({
|
|
317
|
-
4. **REFACTOR:** Clean up → tests MUST pass → commit: `refactor({
|
|
318
|
+
2. **RED:** Read `<behavior>` → failing test(s) → run (MUST fail) → commit: `test({area}): add failing test for [feature]`
|
|
319
|
+
3. **GREEN:** Read `<implementation>` → minimal code → run (MUST pass) → commit: `feat({area}): implement [feature]`
|
|
320
|
+
4. **REFACTOR:** Clean up → tests MUST pass → commit: `refactor({area}): clean up [feature]`
|
|
321
|
+
|
|
322
|
+
`{area}` names the part of the codebase (`auth`, `billing`), never the plan; every one of these commits ends with the trailer `Phase: {phase}-{plan}` after a blank line.
|
|
318
323
|
|
|
319
324
|
Errors: RED doesn't fail → investigate test/existing feature. GREEN doesn't pass → debug, iterate. REFACTOR breaks → undo.
|
|
320
325
|
|
|
@@ -348,7 +353,7 @@ If a commit is BLOCKED by a hook:
|
|
|
348
353
|
<task_commit>
|
|
349
354
|
## Task Commit Protocol
|
|
350
355
|
|
|
351
|
-
Canonical per-task commit rules live in **`agents/pp-executor.md`** (`<task_commit_protocol>`). Follow that section for staging, `{type}({phase}-{plan}
|
|
356
|
+
Canonical per-task commit rules live in **`agents/pp-executor.md`** (`<task_commit_protocol>`). Follow that section for staging, `{type}({area}): …` messages with the `Phase: {phase}-{plan}` trailer, `commit-to-subrepo` when `sub_repos` is set, post-commit checks, and untracked-file handling — do not duplicate or paraphrase the full protocol here (single source of truth).
|
|
352
357
|
|
|
353
358
|
**Orchestrator note:** After each task, the spawned executor reports commit hashes; this workflow does not re-specify commit semantics beyond pointing at the executor.
|
|
354
359
|
|
|
@@ -440,8 +445,6 @@ One-liner SUBSTANTIVE: "JWT auth with refresh rotation using jose library" not "
|
|
|
440
445
|
Include: duration, start/end times, task count, file count.
|
|
441
446
|
|
|
442
447
|
Next: more plans → "Ready for {next-plan}" | last → "Phase complete, ready for next step".
|
|
443
|
-
|
|
444
|
-
**Practices Applied (only when the plan carried a `<vault_practices>` block):** inside the atomic block above and BEFORE the Write, run `pp_run vault trace render` against the execute-stage ledger and include the returned section in that same single Write — no narrative between the render and the Write, for the reason the critical-ordering note already gives. It belongs here and not in the end-of-phase gate: the code reviewer reads this section from every summary in the phase and runs first inside that gate step, so a section produced there would never be visible to it.
|
|
445
448
|
</step>
|
|
446
449
|
|
|
447
450
|
<step name="update_current_position">
|
|
@@ -525,6 +528,7 @@ Counts PLAN vs SUMMARY files on disk and updates the progress-table row with the
|
|
|
525
528
|
Mark completed requirements from the PLAN.md frontmatter `requirements:` field:
|
|
526
529
|
|
|
527
530
|
```bash
|
|
531
|
+
[ -z "${ZSH_VERSION:-}" ] || emulate -R sh
|
|
528
532
|
pp_run query requirements.mark-complete ${REQ_IDS}
|
|
529
533
|
```
|
|
530
534
|
|
|
@@ -545,9 +549,9 @@ IS_WORKTREE=$([ -f .git ] && echo "true" || echo "false")
|
|
|
545
549
|
|
|
546
550
|
# In parallel mode: exclude STATE.md and ROADMAP.md (orchestrator commits these)
|
|
547
551
|
if [ "$IS_WORKTREE" = "true" ]; then
|
|
548
|
-
pp_run query commit "docs(
|
|
552
|
+
pp_run query commit "docs(planning): complete [plan-name] plan" --phase "{phase}-{plan}" --files .planning/phases/XX-name/{phase}-{plan}-SUMMARY.md .planning/REQUIREMENTS.md
|
|
549
553
|
else
|
|
550
|
-
pp_run query commit "docs(
|
|
554
|
+
pp_run query commit "docs(planning): complete [plan-name] plan" --phase "{phase}-{plan}" --files .planning/phases/XX-name/{phase}-{plan}-SUMMARY.md .planning/STATE.md .planning/ROADMAP.md .planning/REQUIREMENTS.md
|
|
551
555
|
fi
|
|
552
556
|
```
|
|
553
557
|
</step>
|
|
@@ -556,13 +560,17 @@ fi
|
|
|
556
560
|
If .planning/codebase/ doesn't exist: skip.
|
|
557
561
|
|
|
558
562
|
```bash
|
|
559
|
-
|
|
563
|
+
[ -z "${ZSH_VERSION:-}" ] || emulate -R sh
|
|
564
|
+
# Oldest feat/fix/test commit carrying the plan's `Phase:` trailer (or, from before the trailer, its scope)
|
|
565
|
+
FIRST_TASK=$(git log --reverse --format='%h%x09%s%x09%(trailers:key=Phase,valueonly,separator=%x2C)' \
|
|
566
|
+
| awk -F'\t' -v id="{phase}-{plan}" '$2 ~ /^(feat|fix|test)(\([^)]*\))?!?:/ && ($3 == id || index($2, "(" id "):") > 0) { print $1; exit }')
|
|
560
567
|
git diff --name-only ${FIRST_TASK}^..HEAD 2>/dev/null || true
|
|
561
568
|
```
|
|
562
569
|
|
|
563
570
|
Update only structural changes: new src/ dir → STRUCTURE.md | deps → STACK.md | file pattern → CONVENTIONS.md | API client → INTEGRATIONS.md | config → STACK.md | renamed → update paths. Skip code-only/bugfix/content changes.
|
|
564
571
|
|
|
565
572
|
```bash
|
|
573
|
+
[ -z "${ZSH_VERSION:-}" ] || emulate -R sh
|
|
566
574
|
pp_run query commit "" --files .planning/codebase/*.md --amend
|
|
567
575
|
```
|
|
568
576
|
</step>
|
|
@@ -571,6 +579,7 @@ pp_run query commit "" --files .planning/codebase/*.md --amend
|
|
|
571
579
|
If `USER_SETUP_CREATED=true`: display `⚠️ USER SETUP REQUIRED` with path + env/config tasks at TOP.
|
|
572
580
|
|
|
573
581
|
```bash
|
|
582
|
+
[ -z "${ZSH_VERSION:-}" ] || emulate -R sh
|
|
574
583
|
(ls -1 .planning/phases/[current-phase-dir]/*-PLAN.md 2>/dev/null || true) | wc -l
|
|
575
584
|
(ls -1 .planning/phases/[current-phase-dir]/*-SUMMARY.md 2>/dev/null || true) | wc -l
|
|
576
585
|
```
|
|
@@ -118,7 +118,7 @@ For each selected output, write the file:
|
|
|
118
118
|
Commit if `commit_docs` is enabled:
|
|
119
119
|
```bash
|
|
120
120
|
_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
|
|
121
|
-
pp_run query commit "docs: capture exploration — {topic_slug}" --files {file_list}
|
|
121
|
+
pp_run query commit "docs(planning): capture exploration — {topic_slug}" --files {file_list}
|
|
122
122
|
```
|
|
123
123
|
|
|
124
124
|
## Step 6: Close
|
|
@@ -64,6 +64,7 @@ Extract:
|
|
|
64
64
|
For each phase directory in `.planning/phases/*/`:
|
|
65
65
|
|
|
66
66
|
```bash
|
|
67
|
+
[ -z "${ZSH_VERSION:-}" ] || emulate -R sh
|
|
67
68
|
ls .planning/phases/*/
|
|
68
69
|
```
|
|
69
70
|
|
|
@@ -255,15 +256,16 @@ If actionable anomalies were found (HIGH or MEDIUM confidence):
|
|
|
255
256
|
|
|
256
257
|
If confirmed:
|
|
257
258
|
```bash
|
|
259
|
+
[ -z "${ZSH_VERSION:-}" ] || emulate -R sh
|
|
258
260
|
# Check if "bug" label exists before using it
|
|
259
|
-
BUG_LABEL=$(gh label list --repo
|
|
261
|
+
BUG_LABEL=$(gh label list --repo pareto000/pp-core --search "bug" --json name -q '.[0].name' 2>/dev/null)
|
|
260
262
|
LABEL_FLAG=""
|
|
261
263
|
if [ -n "$BUG_LABEL" ]; then
|
|
262
264
|
LABEL_FLAG="--label bug"
|
|
263
265
|
fi
|
|
264
266
|
|
|
265
267
|
gh issue create \
|
|
266
|
-
--repo
|
|
268
|
+
--repo pareto000/pp-core \
|
|
267
269
|
--title "bug: {concise description from anomaly}" \
|
|
268
270
|
$LABEL_FLAG \
|
|
269
271
|
--body "{formatted findings from report}"
|
|
@@ -601,7 +601,7 @@ The commands above cover the most common day-to-day flows. Every command listed
|
|
|
601
601
|
- **`/pp:secure-phase [phase]`** — Retroactively verify threat mitigations for a completed phase.
|
|
602
602
|
- **`/pp:validate-phase [phase]`** — Retroactively audit and fill Nyquist validation gaps for a completed phase.
|
|
603
603
|
- **`/pp:ui-review [phase]`** — Retroactive 6-pillar visual audit of implemented frontend code.
|
|
604
|
-
- **`/pp:vault-review [phase]`** — Retroactive
|
|
604
|
+
- **`/pp:vault-review [phase]`** — Retroactive client-vault review of a phase (reports, never gates).
|
|
605
605
|
- **`/pp:eval-review [phase]`** — Audit an executed AI phase's evaluation coverage and produce an EVAL-REVIEW.md remediation plan.
|
|
606
606
|
- **`/pp:audit-fix --source <audit-uat> [--severity medium|high|all] [--max N] [--dry-run]`** — Autonomous audit-to-fix pipeline: find issues, classify, fix, test, commit.
|
|
607
607
|
- **`/pp:add-tests <phase> [additional instructions]`** — Generate tests for a completed phase based on UAT criteria and implementation.
|
|
@@ -42,6 +42,7 @@ Usage: /pp:import --from <path>
|
|
|
42
42
|
Verify the path does not contain traversal sequences and the file exists:
|
|
43
43
|
|
|
44
44
|
```bash
|
|
45
|
+
[ -z "${ZSH_VERSION:-}" ] || emulate -R sh
|
|
45
46
|
case "{FILEPATH}" in
|
|
46
47
|
*..* ) echo "SECURITY_ERROR: path contains traversal sequence"; exit 1 ;;
|
|
47
48
|
esac
|
|
@@ -228,7 +229,7 @@ Update `.planning/STATE.md` if appropriate (e.g., increment total plan count).
|
|
|
228
229
|
|
|
229
230
|
Commit the imported plan and updated files:
|
|
230
231
|
```bash
|
|
231
|
-
pp_run query commit "docs(
|
|
232
|
+
pp_run query commit "docs(planning): import plan from {basename FILEPATH}" --phase "{phase}" --files .planning/phases/{phase}/{plan}-PLAN.md .planning/ROADMAP.md
|
|
232
233
|
```
|
|
233
234
|
|
|
234
235
|
Display completion:
|
|
@@ -33,6 +33,7 @@ Parse `$ARGUMENTS`:
|
|
|
33
33
|
**Validate paths:**
|
|
34
34
|
|
|
35
35
|
```bash
|
|
36
|
+
[ -z "${ZSH_VERSION:-}" ] || emulate -R sh
|
|
36
37
|
case "{SCAN_PATH}" in *..*) echo "SECURITY_ERROR: path contains traversal sequence"; exit 1 ;; esac
|
|
37
38
|
test -d "{SCAN_PATH}" || echo "PATH_NOT_FOUND"
|
|
38
39
|
if [ -n "{MANIFEST_PATH}" ]; then
|
|
@@ -61,6 +61,7 @@ Capture these fields, in this order:
|
|
|
61
61
|
managed-block writer:
|
|
62
62
|
|
|
63
63
|
```bash
|
|
64
|
+
[ -z "${ZSH_VERSION:-}" ] || emulate -R sh
|
|
64
65
|
if [ "$(pp_run query platform-bindings --pick present 2>/dev/null)" = "true" ]; then
|
|
65
66
|
# Write collected values to a temp JSON file using node + JSON.stringify so that
|
|
66
67
|
# multi-line values, embedded quotes, backslashes, and $(...) sequences are encoded
|