@pareto4/pp-core 1.13.0 → 1.17.1
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 +3 -3
- package/README.md +26 -9
- package/agents/pp-code-reviewer.md +2 -1
- package/agents/pp-debug-session-manager.md +9 -6
- package/agents/pp-executor.md +10 -13
- package/agents/pp-plan-checker.md +4 -4
- package/agents/pp-planner.md +23 -9
- package/agents/pp-vault-reviewer.md +244 -21
- package/agents/pp-verifier.md +7 -3
- package/bin/install.js +10 -3
- package/commands/pp-execute-phase.md +1 -3
- package/commands/pp-ns-review.md +1 -1
- package/commands/pp-plan-phase.md +1 -2
- package/commands/pp-vault-review.md +5 -3
- package/commands/pp-verify-work.md +1 -2
- package/gemini-extension.json +1 -1
- package/hooks/dist/pp-check-update.js +0 -0
- package/hooks/dist/pp-cursor-session-start.js +1 -1
- package/hooks/dist/pp-statusline.js +1 -1
- package/hooks/dist/pp-update-banner.js +0 -0
- package/hooks/pp-check-update.js +0 -0
- package/hooks/pp-cursor-session-start.js +1 -1
- package/hooks/pp-statusline.js +1 -1
- package/hooks/pp-update-banner.js +0 -0
- package/package.json +14 -19
- package/pareto-skills/_shared/create-project-board.sh +0 -0
- package/pareto-skills/pp-project-setup/SKILL.md +1 -1
- package/pp-core/bin/check-latest-version.cjs +0 -0
- package/pp-core/bin/detect-build-commands.sh +2 -2
- package/pp-core/bin/lib/capability-activation.cjs +83 -9
- package/pp-core/bin/lib/capability-registry.cjs +396 -82
- package/pp-core/bin/lib/capability-state.cjs +160 -4
- package/pp-core/bin/lib/capability-writer.cjs +19 -5
- package/pp-core/bin/lib/check-command-router.cjs +3334 -946
- package/pp-core/bin/lib/clusters.cjs +3 -0
- package/pp-core/bin/lib/command-aliases.cjs +0 -35
- package/pp-core/bin/lib/commands.cjs +9 -4
- package/pp-core/bin/lib/compose-bindings.cjs +251 -88
- package/pp-core/bin/lib/config-loader.cjs +7 -103
- package/pp-core/bin/lib/config-schema.cjs +1 -1
- package/pp-core/bin/lib/config.cjs +154 -62
- package/pp-core/bin/lib/decisions.cjs +4 -4
- package/pp-core/bin/lib/discovery-vault-check.cjs +246 -0
- package/pp-core/bin/lib/frontmatter.cjs +1 -38
- package/pp-core/bin/lib/git-base-branch.cjs +13 -11
- package/pp-core/bin/lib/git-provider.cjs +4 -4
- package/pp-core/bin/lib/init-command-router.cjs +5 -8
- package/pp-core/bin/lib/init-contract.cjs +648 -738
- package/pp-core/bin/lib/init-interactive.cjs +76 -4
- package/pp-core/bin/lib/init.cjs +24 -51
- package/pp-core/bin/lib/install-profiles.cjs +1 -1
- package/pp-core/bin/lib/io.cjs +8 -0
- package/pp-core/bin/lib/loop-resolver.cjs +189 -129
- package/pp-core/bin/lib/org-profile.cjs +469 -152
- package/pp-core/bin/lib/package-identity.cjs +3 -3
- package/pp-core/bin/lib/phase-command-router.cjs +1 -29
- package/pp-core/bin/lib/phase-scope.cjs +1 -1
- package/pp-core/bin/lib/phase.cjs +11 -253
- package/pp-core/bin/lib/platform-bindings.cjs +40 -19
- package/pp-core/bin/lib/practices-review-check.cjs +15 -9
- package/pp-core/bin/lib/profile-output.cjs +1 -1
- package/pp-core/bin/lib/shell-command-projection.cjs +104 -1
- package/pp-core/bin/lib/state.cjs +11 -85
- package/pp-core/bin/lib/template.cjs +1 -1
- package/pp-core/bin/lib/vault-audit.cjs +650 -126
- package/pp-core/bin/lib/vault-command-router.cjs +2604 -367
- package/pp-core/bin/lib/vault-coordinates.cjs +13 -4
- package/pp-core/bin/lib/vault-index.cjs +699 -0
- package/pp-core/bin/lib/vault-mode.cjs +235 -0
- package/pp-core/bin/lib/vault-practices.cjs +139 -72
- package/pp-core/bin/lib/vault-review.cjs +194 -451
- package/pp-core/bin/lib/vault-seal.cjs +1936 -0
- package/pp-core/bin/lib/vault-standards.cjs +1505 -0
- package/pp-core/bin/lib/vault-trace.cjs +607 -254
- package/pp-core/bin/lib/vault-update.cjs +9 -33
- package/pp-core/bin/lib/vault-write-back.cjs +70 -42
- package/pp-core/bin/lib/vault.cjs +2734 -920
- package/pp-core/bin/lib/verify.cjs +0 -11
- package/pp-core/bin/portable-timeout.sh +1 -1
- package/pp-core/bin/pp-tools.cjs +184 -54
- package/pp-core/bin/shared/config-defaults.manifest.json +0 -7
- package/pp-core/bin/shared/config-schema.manifest.json +0 -3
- package/pp-core/bin/shared/model-catalog.json +2 -2
- package/pp-core/bin/verify-reapply-patches.cjs +0 -0
- package/pp-core/org-profile.json +26 -0
- package/pp-core/references/autonomous-best-effort.md +8 -7
- package/pp-core/references/loop-hook-dispatch.md +0 -25
- package/pp-core/references/planner-gap-closure.md +0 -1
- package/pp-core/references/planner-tdd.md +0 -1
- package/pp-core/references/planner-vault-practices.md +17 -34
- package/pp-core/references/planner-vault-standards.md +320 -0
- package/pp-core/references/planning-config.md +0 -8
- package/pp-core/references/practice-arithmetic-contract.md +121 -0
- package/pp-core/references/tdd.md +0 -1
- package/pp-core/references/verifier-practice-verdicts.md +263 -0
- package/pp-core/templates/README.md +1 -0
- package/pp-core/templates/VAULT-REVIEW.md +202 -0
- package/pp-core/templates/phase-prompt.md +2 -6
- package/pp-core/templates/practices/README.md +20 -23
- package/pp-core/workflows/_runtime-launcher.snippet.sh +0 -0
- package/pp-core/workflows/add-tests.md +55 -4
- package/pp-core/workflows/audit-fix.md +63 -2
- package/pp-core/workflows/audit-milestone.md +1 -1
- package/pp-core/workflows/autonomous.md +85 -11
- package/pp-core/workflows/check-todos.md +13 -2
- package/pp-core/workflows/code-review-fix.md +59 -3
- package/pp-core/workflows/code-review.md +10 -1
- package/pp-core/workflows/complete-milestone.md +1 -1
- package/pp-core/workflows/debug.md +54 -4
- package/pp-core/workflows/discovery-sprint/prefill.md +19 -7
- package/pp-core/workflows/discovery-sprint/prototype.md +46 -49
- package/pp-core/workflows/discovery-sprint/session-13-gates.md +2 -0
- package/pp-core/workflows/discovery-sprint/sessions/01-kick-off.md +1 -3
- package/pp-core/workflows/discovery-sprint/sessions/02-as-is.md +1 -3
- package/pp-core/workflows/discovery-sprint/sessions/03-to-be.md +1 -3
- package/pp-core/workflows/discovery-sprint/sessions/04-ux-design.md +20 -24
- package/pp-core/workflows/discovery-sprint/sessions/05-architecture.md +1 -3
- package/pp-core/workflows/discovery-sprint/sessions/06-security.md +1 -3
- package/pp-core/workflows/discovery-sprint/sessions/07-identity.md +1 -3
- package/pp-core/workflows/discovery-sprint/sessions/08-integration.md +1 -3
- package/pp-core/workflows/discovery-sprint/sessions/09-qa.md +1 -3
- package/pp-core/workflows/discovery-sprint/sessions/10-infrastructure.md +1 -6
- package/pp-core/workflows/discovery-sprint/sessions/11-roadmap.md +1 -3
- package/pp-core/workflows/discovery-sprint/sessions/12-delivery-model.md +1 -3
- package/pp-core/workflows/discovery-sprint/sessions/13-wrap-up.md +1 -3
- package/pp-core/workflows/discovery-sprint/templates/context-template.md +1 -1
- package/pp-core/workflows/discovery-sprint/vault-context.md +213 -0
- package/pp-core/workflows/discovery-sprint.md +7 -3
- package/pp-core/workflows/discovery-to-build/steps/architecture-deliverables.md +4 -4
- package/pp-core/workflows/discovery-to-build/templates/pp-handoff.md +43 -1
- package/pp-core/workflows/discovery-to-build.md +10 -2
- package/pp-core/workflows/discuss-phase.md +3 -10
- package/pp-core/workflows/execute-phase/steps/check-query-gate.md +329 -0
- package/pp-core/workflows/execute-phase/steps/client-context-gate.md +3 -2
- package/pp-core/workflows/execute-phase/steps/cross-ai-delegation.md +1 -1
- package/pp-core/workflows/execute-phase/steps/execute-pre-dispatch.md +98 -0
- package/pp-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +94 -0
- package/pp-core/workflows/execute-phase/steps/post-merge-gate.md +6 -8
- package/pp-core/workflows/execute-phase/steps/vault-fetch.md +115 -14
- package/pp-core/workflows/execute-phase/steps/vault-load-gate.md +322 -20
- package/pp-core/workflows/execute-phase/steps/verifier-practice-payload.md +165 -0
- package/pp-core/workflows/execute-phase/steps/verify-post-gate.md +163 -0
- package/pp-core/workflows/execute-phase.md +155 -128
- package/pp-core/workflows/execute-plan.md +56 -6
- package/pp-core/workflows/fast.md +53 -4
- package/pp-core/workflows/help/modes/full.md +3 -3
- package/pp-core/workflows/init/steps/client-context-capture.md +101 -0
- package/pp-core/workflows/init/steps/gitlab-provisioning.md +130 -0
- package/pp-core/workflows/init/steps/project-md-deferral-narration.md +66 -0
- package/pp-core/workflows/init/steps/reachability-outcome.md +70 -0
- package/pp-core/workflows/init.md +232 -272
- package/pp-core/workflows/new-project.md +31 -23
- package/pp-core/workflows/plan-phase.md +98 -45
- package/pp-core/workflows/quick.md +117 -3
- package/pp-core/workflows/secure-phase.md +1 -1
- package/pp-core/workflows/ship.md +57 -28
- package/pp-core/workflows/undo.md +1 -1
- package/pp-core/workflows/update.md +3 -3
- package/pp-core/workflows/validate-phase.md +58 -3
- package/pp-core/workflows/vault-review.md +282 -22
- package/pp-core/workflows/verify-work.md +12 -14
- package/scripts/changeset/cli.cjs +6 -5
- package/scripts/changeset/lint.cjs +0 -0
- package/scripts/changeset/new.cjs +33 -50
- package/scripts/dev-env.cjs +25 -85
- package/scripts/gen-capability-registry.cjs +199 -11
- package/scripts/gen-practice-arithmetic-contract.cjs +412 -0
- package/scripts/lib/allowlist-ratchet.cjs +1 -103
- package/scripts/lint-allow-test-rule-refs.allowlist.json +0 -2
- package/scripts/lint-docs-required.cjs +0 -0
- package/scripts/lint-pr-check-project-dir.cjs +1 -3
- package/scripts/lint-test-file-count.allowlist.json +12 -10
- package/scripts/practice-arithmetic-contract.allow.json +35 -0
- package/scripts/prompt-injection-scan.sh +22 -17
- package/scripts/record-vault-mode-golden.cjs +89 -0
- package/scripts/release-channel.cjs +0 -0
- package/scripts/sync-manifest-versions.cjs +5 -4
- package/scripts/sync-rulesets.sh +1 -1
- package/scripts/update-size-baseline.cjs +30 -274
- package/scripts/vault-calibrate.cjs +996 -0
- package/scripts/verify-opengsd-sweep.cjs +3 -5
- package/scripts/workflow-size.cjs +9 -61
- package/pp-core/bin/lib/dispatch-plan.cjs +0 -483
- package/pp-core/bin/lib/install-run.cjs +0 -536
- package/pp-core/bin/lib/loop-gates.cjs +0 -213
- package/pp-core/bin/lib/phase-manifest.cjs +0 -527
- package/pp-core/bin/lib/phase-tier.cjs +0 -480
- package/pp-core/bin/lib/plan-graph.cjs +0 -368
- package/pp-core/references/executor-vault-trace.md +0 -47
- package/pp-core/references/planner-plan-graph.md +0 -66
- package/pp-core/workflows/discovery-sprint/vault-fetch.md +0 -37
- package/pp-core/workflows/execute-phase/steps/checkpoint-handling.md +0 -45
- package/pp-core/workflows/execute-phase/steps/install-run.md +0 -29
- package/pp-core/workflows/execute-phase/steps/phase-close-rebaseline.md +0 -23
- package/pp-core/workflows/execute-phase/steps/serial-group-dispatch.md +0 -73
- package/pp-core/workflows/execute-phase/steps/vault-door-gate.md +0 -19
- package/pp-core/workflows/plan-phase/steps/phase-tier.md +0 -43
- package/scripts/lib/size-budget.cjs +0 -311
- package/scripts/lint-neutrality-names.cjs +0 -694
- package/scripts/lint-org-coordinates.allowlist.json +0 -35
- package/scripts/lint-org-coordinates.cjs +0 -426
|
@@ -29,14 +29,12 @@ Orchestrator coordinates, not executes. Each subagent loads the full execute-pla
|
|
|
29
29
|
Claude Code agent per #853, or a non-Claude runtime), use sequential inline execution as
|
|
30
30
|
the fallback for executor parallelization only. If `Agent` IS available (top-level Claude
|
|
31
31
|
Code), you MUST spawn pp-executor agents — inline execution is not authorized. Check for
|
|
32
|
-
actual tool availability, not runtime name.
|
|
32
|
+
actual tool availability, not runtime name. Every inline path follows `EXECUTOR_HOOK_FRAGMENTS` as in `check_interactive_mode`.
|
|
33
33
|
|
|
34
34
|
**Fallback rule:** If a spawned agent completes its work (commits visible, SUMMARY.md exists) but
|
|
35
35
|
the orchestrator never receives the completion signal, treat it as successful based on spot-checks
|
|
36
36
|
and continue to the next wave/plan. Never block indefinitely waiting for a signal — always verify
|
|
37
37
|
via filesystem and git state.
|
|
38
|
-
|
|
39
|
-
**Executor contributions (execute:pre `into: executor`):** every spawn injects its dispatch-plan `contributions[].fragment` verbatim after `${AGENT_SKILLS}`. Every inline path (interactive, Copilot, no `Agent`, a stalled executor switched to inline) follows `pp_run loop render-hooks execute:pre --into executor --phase "${PHASE_NUMBER}" ${TIER_FLAG}` the same way.
|
|
40
38
|
</runtime_compatibility>
|
|
41
39
|
|
|
42
40
|
<required_reading>
|
|
@@ -71,8 +69,7 @@ Parse `$ARGUMENTS` before loading any context:
|
|
|
71
69
|
|
|
72
70
|
- First positional token → `PHASE_ARG`
|
|
73
71
|
- Optional `--wave N` → `WAVE_FILTER`
|
|
74
|
-
- Optional `--gaps-only`
|
|
75
|
-
- Optional `--tier light|standard|heavy` → `TIER_FLAG="--tier=<value>"` (one word, so zsh passes it as one argument; the phase's ceremony tier for this run; passed to init, dispatch plan and render-hooks)
|
|
72
|
+
- Optional `--gaps-only` keeps its current meaning
|
|
76
73
|
- Optional `--cross-ai` → `CROSS_AI_FORCE=true` (force all plans through cross-AI execution)
|
|
77
74
|
- Optional `--no-cross-ai` → `CROSS_AI_DISABLED=true` (disable cross-AI for this run, overrides config and frontmatter)
|
|
78
75
|
- Optional `--unattended` → `UNATTENDED=true` — set by `/pp:autonomous`; prompt sites marked `U-En` apply the rules in `pp-core/references/autonomous-best-effort.md` (Read it at the first such site)
|
|
@@ -85,7 +82,7 @@ Load all context in one call:
|
|
|
85
82
|
|
|
86
83
|
```bash
|
|
87
84
|
_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
|
|
88
|
-
INIT=$(pp_run query init.execute-phase "${PHASE_ARG}"
|
|
85
|
+
INIT=$(pp_run query init.execute-phase "${PHASE_ARG}")
|
|
89
86
|
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
90
87
|
AGENT_SKILLS=$(pp_run query agent-skills pp-executor)
|
|
91
88
|
```
|
|
@@ -170,7 +167,7 @@ or absence of the `Agent()` subagent API. If running under Copilot, force sequen
|
|
|
170
167
|
execution regardless of the `parallelization` setting — Copilot's subagent completion
|
|
171
168
|
signals are unreliable (see `<runtime_compatibility>`). Set `COPILOT_SEQUENTIAL=true`
|
|
172
169
|
internally and skip the `execute_waves` step in favor of `check_interactive_mode`'s
|
|
173
|
-
inline path for each plan.
|
|
170
|
+
inline path for each plan. That inline path carries `EXECUTOR_HOOK_FRAGMENTS` as in `check_interactive_mode`.
|
|
174
171
|
|
|
175
172
|
**REQUIRED — Sync chain flag with intent.** If user invoked manually (no `--auto`), clear the ephemeral chain flag from any previous interrupted `--auto` chain. This prevents stale `_auto_chain_active: true` from causing unwanted auto-advance. This does NOT touch `workflow.auto_advance` (the user's persistent settings preference). You MUST execute this bash block before any config reads:
|
|
176
173
|
```bash
|
|
@@ -185,10 +182,21 @@ Resolve `MVP_MODE` once via the centralized `phase.mvp-mode` query verb (precede
|
|
|
185
182
|
MVP_FLAG_ARG=""
|
|
186
183
|
if [[ "$ARGUMENTS" =~ (^|[[:space:]])--mvp([[:space:]]|$) ]]; then MVP_FLAG_ARG="--cli-flag"; fi
|
|
187
184
|
MVP_MODE=$(pp_run query phase.mvp-mode "${PHASE_NUMBER}" $MVP_FLAG_ARG --pick active)
|
|
188
|
-
EXECUTE_POST_HOOKS_JSON=$(pp_run loop render-hooks execute:post --raw
|
|
189
|
-
TDD_MODE=$(pp_run loop render-hooks execute:post --active-cap tdd)
|
|
185
|
+
EXECUTE_POST_HOOKS_JSON=$(pp_run loop render-hooks execute:post --raw)
|
|
186
|
+
TDD_MODE=$(pp_run loop render-hooks execute:post --active-cap tdd)
|
|
187
|
+
EXECUTE_PRE_HOOKS_JSON=$(pp_run loop render-hooks execute:pre --raw)
|
|
188
|
+
EXECUTOR_HOOK_FRAGMENTS=$(pp_run loop render-hooks execute:pre --into executor)
|
|
189
|
+
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}))"
|
|
190
190
|
```
|
|
191
191
|
|
|
192
|
+
<step name="execute_pre_dispatch">
|
|
193
|
+
**`execute:pre` capability dispatch — fetch, then decide (GATE-03).**
|
|
194
|
+
|
|
195
|
+
Runs before `safe_resume_gate` — the first step that can spawn an executor — so the gate decides
|
|
196
|
+
before any code is written. Read and execute
|
|
197
|
+
`pp-core/workflows/execute-phase/steps/execute-pre-dispatch.md`.
|
|
198
|
+
</step>
|
|
199
|
+
|
|
192
200
|
<step name="safe_resume_gate">
|
|
193
201
|
Before trusting `STATE.md` or dispatching any executor, derive `CURRENT_PLAN_ID`
|
|
194
202
|
from the active incomplete plan in `INIT`, then search recent history:
|
|
@@ -277,6 +285,9 @@ checkpoints between tasks. The user can review, modify, or redirect work at any
|
|
|
277
285
|
|
|
278
286
|
c. **If "Execute":** Read and follow `~/.claude/pp-core/workflows/execute-plan.md` **inline**
|
|
279
287
|
(do NOT spawn a subagent). Execute tasks one at a time.
|
|
288
|
+
The inline executor follows `EXECUTOR_HOOK_FRAGMENTS` (computed in the hooks fence above) as
|
|
289
|
+
its contract exactly as a spawned executor would: in standards mode it is the vault's
|
|
290
|
+
execute:pre executor fragment; in practices mode it is empty.
|
|
280
291
|
|
|
281
292
|
d. **After each task:** Pause briefly. If the user intervenes (types anything), stop and address
|
|
282
293
|
their feedback before continuing. Otherwise proceed to next task.
|
|
@@ -348,12 +359,6 @@ This updates Status, Last Activity, Current focus, Current Position, and plan co
|
|
|
348
359
|
Read and execute `pp-core/workflows/execute-phase/steps/client-context-gate.md` — Pareto client-context gate (inert without `.platform-bindings.json`; confirms the Phase 9 CLAUDE.md block first).
|
|
349
360
|
</step>
|
|
350
361
|
|
|
351
|
-
<step name="execute_pre_vault">
|
|
352
|
-
Before any executor: `EXECUTE_PRE_HOOKS_JSON=$(pp_run loop render-hooks execute:pre --raw) || exit 1`. For an active `capId == "vault"` step, Read and execute `pp-core/workflows/execute-phase/steps/vault-fetch.md`; then, for an active `vault.status` gate, set `VAULT_GATE_POINT=execute` and Read and execute `pp-core/workflows/execute-phase/steps/vault-load-gate.md`. None active → skip.
|
|
353
|
-
|
|
354
|
-
Then anchor the phase for `/pp-undo --phase`: `pp_run phase manifest start "${PHASE_NUMBER}" --raw` — print its line and continue whatever it says (write-once; a refusal leaves undo on its git-log fallback).
|
|
355
|
-
</step>
|
|
356
|
-
|
|
357
362
|
<step name="discover_and_group_plans">
|
|
358
363
|
Load plan inventory with wave grouping in one call:
|
|
359
364
|
|
|
@@ -361,7 +366,7 @@ Load plan inventory with wave grouping in one call:
|
|
|
361
366
|
PLAN_INDEX=$(pp_run query phase-plan-index "${PHASE_NUMBER}")
|
|
362
367
|
```
|
|
363
368
|
|
|
364
|
-
Parse JSON for: `phase`, `plans[]` (each with `id`, `
|
|
369
|
+
Parse JSON for: `phase`, `plans[]` (each with `id`, `wave`, `autonomous`, `objective`, `files_modified`, `task_count`, `has_summary`), `waves` (map of wave number → plan IDs), `incomplete`, `has_checkpoints`.
|
|
365
370
|
|
|
366
371
|
**Filtering:** Skip plans where `has_summary: true`. If `--gaps-only`: also skip non-gap_closure plans. If `WAVE_FILTER` is set: also skip plans whose `wave` does not equal `WAVE_FILTER`.
|
|
367
372
|
|
|
@@ -379,7 +384,7 @@ Report:
|
|
|
379
384
|
|
|
380
385
|
| Wave | Plans | What it builds |
|
|
381
386
|
|------|-------|----------------|
|
|
382
|
-
| 1 | 01-01, 01-02 |
|
|
387
|
+
| 1 | 01-01, 01-02 | {from plan objectives, 3-8 words} |
|
|
383
388
|
| 2 | 01-03 | ... |
|
|
384
389
|
```
|
|
385
390
|
</step>
|
|
@@ -391,7 +396,7 @@ Read and execute `pp-core/workflows/execute-phase/steps/cross-ai-delegation.md`.
|
|
|
391
396
|
</step>
|
|
392
397
|
|
|
393
398
|
<step name="execute_waves">
|
|
394
|
-
Execute each selected wave in sequence. Within a wave
|
|
399
|
+
Execute each selected wave in sequence. Within a wave: parallel if `PARALLELIZATION=true`, sequential if `false`.
|
|
395
400
|
|
|
396
401
|
**Orchestrator cwd-drift guard (FIRST ACTION at execute_waves entry — #48):**
|
|
397
402
|
|
|
@@ -422,14 +427,6 @@ export ORCHESTRATOR_WT
|
|
|
422
427
|
cd "$ORCHESTRATOR_WT" || { echo "FATAL: cannot cd to orchestrator worktree '$ORCHESTRATOR_WT' (#48)." >&2; exit 1; }
|
|
423
428
|
```
|
|
424
429
|
|
|
425
|
-
**Dispatch plan (load once, after the cwd guard and cross-AI delegation):** what this run spawns, builds, tests and commits, computed by `phase.dispatch-plan`. Spawn exactly its spawns; never re-derive waves, serial groups, isolation or builds.
|
|
426
|
-
|
|
427
|
-
```bash
|
|
428
|
-
DISPATCH_PLAN=$(pp_run query phase.dispatch-plan "${PHASE_NUMBER}" --use-worktrees "${USE_WORKTREES:-true}" ${WAVE_FILTER:+--wave "$WAVE_FILTER"} ${GAPS_ONLY:+--gaps-only} ${TIER_FLAG})
|
|
429
|
-
```
|
|
430
|
-
|
|
431
|
-
`stages.execute.waves[]` in order, each with `spawns[]` (`kind` `serial-group`|`plan`, `plans[]` in run order with `id`, `title`, `build`, `touched_tests`; `isolation` `main-checkout`|`worktree`; `build`; `checkpoint`; `contributions`), `run`, `merge`, `build`, `suite_runs` (1), `tracking_commits` (1), `tracking.requirements`, `defects[]`. Report `totals` (spawns, suite runs, tracking commits). Non-empty `filters.lower_wave_incomplete` → STOP: finish the earlier waves first.
|
|
432
|
-
|
|
433
430
|
**Stream-idle-timeout prevention — checkpoint heartbeats (#2410):**
|
|
434
431
|
|
|
435
432
|
Multi-plan phases can accumulate enough subagent context that the Claude API
|
|
@@ -452,14 +449,39 @@ increases monotonically across waves. `{status}` is `complete` (success),
|
|
|
452
449
|
|
|
453
450
|
**For each wave:**
|
|
454
451
|
|
|
455
|
-
1. **Intra-wave files_modified overlap check (BEFORE spawning
|
|
452
|
+
1. **Intra-wave files_modified overlap check (BEFORE spawning):**
|
|
453
|
+
|
|
454
|
+
Before spawning any agents for this wave, inspect the `files_modified` list of all plans
|
|
455
|
+
in the wave. Check every pair of plans in the wave — if any two plans share even one file
|
|
456
|
+
in their `files_modified` lists, those plans have an implicit dependency and MUST NOT run
|
|
457
|
+
in parallel.
|
|
458
|
+
|
|
459
|
+
**Detection algorithm (pseudocode):**
|
|
460
|
+
```
|
|
461
|
+
seen_files = {}
|
|
462
|
+
overlapping_plans = []
|
|
463
|
+
for each plan in wave_plans:
|
|
464
|
+
for each file in plan.files_modified:
|
|
465
|
+
if file in seen_files:
|
|
466
|
+
overlapping_plans.add(plan, seen_files[file]) # both plans overlap on this file
|
|
467
|
+
else:
|
|
468
|
+
seen_files[file] = plan
|
|
469
|
+
```
|
|
456
470
|
|
|
457
|
-
**If
|
|
471
|
+
**If overlap is detected:**
|
|
472
|
+
- Warn the user:
|
|
458
473
|
```
|
|
459
474
|
⚠ Intra-wave files_modified overlap detected in Wave {N}:
|
|
460
|
-
{
|
|
475
|
+
Plan {A} and Plan {B} both modify {file}
|
|
476
|
+
Running these plans sequentially to avoid parallel worktree conflicts.
|
|
461
477
|
```
|
|
462
|
-
|
|
478
|
+
- Override `PARALLELIZATION` to `false` for this wave only — run all plans in the wave
|
|
479
|
+
sequentially regardless of the global parallelization setting.
|
|
480
|
+
- This is a safety net for plans that were incorrectly assigned to the same wave.
|
|
481
|
+
The planner should have caught this; flag it as a planning defect so the user can
|
|
482
|
+
replan the phase if desired.
|
|
483
|
+
|
|
484
|
+
**If no overlap:** proceed normally (parallel if `PARALLELIZATION=true`).
|
|
463
485
|
|
|
464
486
|
2. **Describe what's being built (BEFORE spawning):**
|
|
465
487
|
|
|
@@ -485,19 +507,21 @@ increases monotonically across waves. `{status}` is `complete` (success),
|
|
|
485
507
|
---
|
|
486
508
|
## Wave {N}
|
|
487
509
|
|
|
488
|
-
**{Plan ID}: {
|
|
510
|
+
**{Plan ID}: {Plan Name}**
|
|
489
511
|
{2-3 sentences: what this builds, technical approach, why it matters}
|
|
490
512
|
|
|
491
|
-
Spawning {count} agent(s)
|
|
513
|
+
Spawning {count} agent(s)... (runs in a subagent — no output until it returns, ~1–5 min; expected, not a freeze)
|
|
492
514
|
---
|
|
493
515
|
```
|
|
494
516
|
|
|
495
517
|
- Bad: "Executing terrain generation plan"
|
|
496
518
|
- Good: "Procedural terrain generator using Perlin noise — creates height maps, biome zones, and collision meshes. Required before vehicle physics can interact with ground."
|
|
497
519
|
|
|
498
|
-
2.5. **Per-plan worktree decision (
|
|
520
|
+
2.5. **Per-plan worktree decision (run for each plan in this wave BEFORE its dispatch):**
|
|
521
|
+
|
|
522
|
+
Read and execute `pp-core/workflows/execute-phase/steps/per-plan-worktree-gate.md` for each plan. It extracts `PLAN_FILES` from the plan's JSON, intersects against `SUBMODULE_PATHS` (with normalization, bidirectional matching, and glob-prefix handling), and sets `USE_WORKTREES_FOR_PLAN` to `false` when the plan touches a submodule path. Append `plan_id` to a `WAVE_WORKTREE_PLANS` accumulator when `USE_WORKTREES_FOR_PLAN != false`.
|
|
499
523
|
|
|
500
|
-
The dispatch branches in step 3 below MUST gate on `USE_WORKTREES_FOR_PLAN` for the current
|
|
524
|
+
The dispatch branches in step 3 below MUST gate on `USE_WORKTREES_FOR_PLAN` for the current plan, not on the project-level `USE_WORKTREES`.
|
|
501
525
|
|
|
502
526
|
3. **Spawn executor agents:**
|
|
503
527
|
|
|
@@ -506,8 +530,6 @@ increases monotonically across waves. `{status}` is `complete` (success),
|
|
|
506
530
|
|
|
507
531
|
`[checkpoint] phase {PHASE_NUMBER} wave {N}/{M} plan {plan_id} starting ({P}/{Q} plans done)`
|
|
508
532
|
|
|
509
|
-
**Serial-group spawn** (`kind: serial-group`): Read and execute `pp-core/workflows/execute-phase/steps/serial-group-dispatch.md` — ONE executor on the main checkout for the whole group. The rest of step 3 covers `kind: plan` spawns.
|
|
510
|
-
|
|
511
533
|
Pass paths only — executors read files themselves with their fresh context window.
|
|
512
534
|
For 200k models, this keeps orchestrator context lean (~10-15%).
|
|
513
535
|
For 1M+ models (Opus 4.6, Sonnet 4.6), richer context can be passed directly.
|
|
@@ -544,7 +566,7 @@ increases monotonically across waves. `{status}` is `complete` (success),
|
|
|
544
566
|
```text
|
|
545
567
|
Agent(
|
|
546
568
|
subagent_type="pp-executor",
|
|
547
|
-
description="Execute plan {plan_number} of phase {phase_number}
|
|
569
|
+
description="Execute plan {plan_number} of phase {phase_number}",
|
|
548
570
|
# Only include model= when executor_model is an explicit model name.
|
|
549
571
|
# When executor_model is "inherit", omit this parameter entirely so
|
|
550
572
|
# Claude Code inherits the orchestrator model automatically.
|
|
@@ -552,13 +574,11 @@ increases monotonically across waves. `{status}` is `complete` (success),
|
|
|
552
574
|
isolation="worktree",
|
|
553
575
|
prompt="
|
|
554
576
|
<objective>
|
|
555
|
-
Execute plan {plan_number}
|
|
577
|
+
Execute plan {plan_number} of phase {phase_number}-{phase_name}.
|
|
556
578
|
Commit each task atomically. Create SUMMARY.md.
|
|
557
579
|
Do NOT update STATE.md or ROADMAP.md — the orchestrator owns those writes after all worktree agents in the wave complete.
|
|
558
580
|
</objective>
|
|
559
581
|
|
|
560
|
-
<dispatch tracking="orchestrator" suite="orchestrator" build="{spawn.build}" />
|
|
561
|
-
|
|
562
582
|
<worktree_branch_check>
|
|
563
583
|
ORCHESTRATOR build-time embed (NOT a sub-agent runtime step): before this dispatch, read `pp-core/references/worktree-branch-check.md`, substitute `{EXPECTED_BASE}` with the base SHA captured above ({EXPECTED_BASE}), and replace this note with that fragment's `<worktree_branch_check>` block so the dispatched prompt carries the runnable guard verbatim — do not pass this instruction through in its place.
|
|
564
584
|
Per-commit HEAD/cwd-drift/path-guard: `agents/pp-executor.md` steps 0/0a/0b + `references/worktree-path-safety.md` (in <execution_context>).
|
|
@@ -611,7 +631,7 @@ increases monotonically across waves. `{status}` is `complete` (success),
|
|
|
611
631
|
</files_to_read>
|
|
612
632
|
|
|
613
633
|
${AGENT_SKILLS}
|
|
614
|
-
{
|
|
634
|
+
${EXECUTOR_HOOK_FRAGMENTS}
|
|
615
635
|
|
|
616
636
|
<mcp_tools>
|
|
617
637
|
If CLAUDE.md or project instructions reference MCP tools (e.g. jCodeMunch, context7,
|
|
@@ -648,14 +668,15 @@ increases monotonically across waves. `{status}` is `complete` (success),
|
|
|
648
668
|
</sequential_execution>
|
|
649
669
|
```
|
|
650
670
|
|
|
651
|
-
|
|
671
|
+
The sequential mode Agent prompt uses the same structure as worktree mode but with these differences in success_criteria — since there is only one agent writing at a time, there are no shared-file conflicts:
|
|
652
672
|
|
|
653
673
|
```
|
|
654
674
|
<success_criteria>
|
|
655
675
|
- [ ] All tasks executed
|
|
656
676
|
- [ ] Each task committed individually
|
|
657
677
|
- [ ] SUMMARY.md created in plan directory
|
|
658
|
-
- [ ]
|
|
678
|
+
- [ ] STATE.md updated with position and decisions
|
|
679
|
+
- [ ] ROADMAP.md updated with plan progress (via `roadmap update-plan-progress`)
|
|
659
680
|
</success_criteria>
|
|
660
681
|
```
|
|
661
682
|
|
|
@@ -698,7 +719,7 @@ increases monotonically across waves. `{status}` is `complete` (success),
|
|
|
698
719
|
for activity. If no completion signal, no SUMMARY.md, and no expected-branch
|
|
699
720
|
commits appear for `${EXECUTOR_STALL_THRESHOLD_MINUTES}` minutes, pause and
|
|
700
721
|
ask for one recovery path: `continue waiting`, `kill and retry`, or
|
|
701
|
-
`kill and switch to inline execution` (U-E7).
|
|
722
|
+
`kill and switch to inline execution` (U-E7). The inline switch follows `EXECUTOR_HOOK_FRAGMENTS` too.
|
|
702
723
|
|
|
703
724
|
If the stalled executor ran in an isolated worktree, `kill and switch to inline execution` edits the primary checkout — see worktree recovery policy (`execute-phase/steps/worktree-recovery-policy.md`). Prefer `kill and retry` in a fresh worktree; inline execution requires explicit confirmation, never the default.
|
|
704
725
|
|
|
@@ -796,7 +817,7 @@ increases monotonically across waves. `{status}` is `complete` (success),
|
|
|
796
817
|
|
|
797
818
|
**When to skip step 5.5:**
|
|
798
819
|
|
|
799
|
-
**If no
|
|
820
|
+
**If no plan in this wave used worktree isolation** (project-level `USE_WORKTREES=false` OR every plan in the wave had `USE_WORKTREES_FOR_PLAN=false` — i.e. `WAVE_WORKTREE_PLANS` from step 2.5 is empty): all agents ran on the main working tree — skip this step entirely.
|
|
800
821
|
|
|
801
822
|
**If the orchestrator merged via custom messages (cross-wave-dependency deviation):** the templated cleanup loop above was not triggered for those merges. Run the cleanup-tail snippet above instead. After the snippet completes, proceed to step 5.6.
|
|
802
823
|
|
|
@@ -808,12 +829,10 @@ increases monotonically across waves. `{status}` is `complete` (success),
|
|
|
808
829
|
|
|
809
830
|
5.6. **Post-merge build & test gate:**
|
|
810
831
|
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
issues that per-plan checks cannot detect (e.g., conflicting type definitions, removed
|
|
816
|
-
exports, import changes, link errors).
|
|
832
|
+
After merging all worktrees in a wave (parallel mode), or after the last plan completes
|
|
833
|
+
(serial mode), run a build and then the project's test suite to catch cross-plan
|
|
834
|
+
integration issues that individual worktree self-checks cannot detect (e.g., conflicting
|
|
835
|
+
type definitions, removed exports, import changes, link errors).
|
|
817
836
|
|
|
818
837
|
This addresses the Generator self-evaluation blind spot identified in Anthropic's
|
|
819
838
|
harness engineering research: agents reliably report Self-Check: PASSED even when
|
|
@@ -821,79 +840,62 @@ increases monotonically across waves. `{status}` is `complete` (success),
|
|
|
821
840
|
|
|
822
841
|
Read and execute `pp-core/workflows/execute-phase/steps/post-merge-gate.md`.
|
|
823
842
|
|
|
824
|
-
5.7. **Post-wave
|
|
843
|
+
5.7. **Post-wave shared artifact update (when at least one plan used worktrees, skip if tests failed):**
|
|
825
844
|
|
|
826
|
-
|
|
827
|
-
refreshes the plan rows and the Built state with `roadmap update-plan-progress`;
|
|
828
|
-
advances STATE, records the wave's `tracking.requirements` (`requirements.mark-complete`) and the `key-decisions` of its SUMMARY.md files (`state.add-decision`);
|
|
829
|
-
makes the wave's ONE tracking commit (`tracking_commits: 1`).
|
|
845
|
+
When **any** executor agent in this wave ran with `isolation="worktree"`, that agent skipped STATE.md and ROADMAP.md updates to avoid last-merge-wins overwrites. The orchestrator is the single writer for these files. After worktrees are merged back, update shared artifacts once for every completed plan in the wave (worktree-mode plans **and** sequential plans that ran on the main tree but deferred to the orchestrator for tracking writes).
|
|
830
846
|
|
|
831
847
|
**Only update tracking when tests passed (TEST_EXIT=0).**
|
|
832
848
|
If tests failed or timed out, skip the tracking update — plans should
|
|
833
849
|
not be marked as complete when integration tests are failing or inconclusive.
|
|
834
850
|
|
|
835
851
|
```bash
|
|
836
|
-
#
|
|
852
|
+
# Guard: only update tracking if post-merge tests passed
|
|
853
|
+
# Timeout (124) is treated as inconclusive — do NOT mark plans complete
|
|
837
854
|
if [ "${TEST_EXIT}" -eq 0 ]; then
|
|
838
|
-
#
|
|
855
|
+
# Refresh plan rows and the Built state from disk (D-08-12). Phase completion is NOT
|
|
856
|
+
# written here — phase.complete does that in update_roadmap, after the execute:post gate.
|
|
839
857
|
pp_run query roadmap.update-plan-progress "${PHASE_NUMBER}"
|
|
840
|
-
|
|
841
|
-
#
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
if ! git diff --quiet .planning/ROADMAP.md .planning/STATE.md .planning/REQUIREMENTS.md 2>/dev/null; then
|
|
845
|
-
pp_run query commit "docs(phase-${PHASE_NUMBER}): update tracking after wave ${N}" --files .planning/ROADMAP.md .planning/STATE.md .planning/REQUIREMENTS.md
|
|
858
|
+
|
|
859
|
+
# Only commit tracking files if they actually changed
|
|
860
|
+
if ! git diff --quiet .planning/ROADMAP.md .planning/STATE.md 2>/dev/null; then
|
|
861
|
+
pp_run query commit "docs(phase-${PHASE_NUMBER}): update tracking after wave ${N}" --files .planning/ROADMAP.md .planning/STATE.md
|
|
846
862
|
fi
|
|
847
863
|
elif [ "${TEST_EXIT}" -eq 124 ]; then
|
|
848
864
|
echo "⚠ Skipping tracking update — test suite timed out. Plans remain in-progress. Run tests manually to confirm."
|
|
849
865
|
else
|
|
850
866
|
echo "⚠ Skipping tracking update — post-merge tests failed (exit ${TEST_EXIT}). Plans remain in-progress until tests pass."
|
|
851
867
|
fi
|
|
852
|
-
pp_run phase manifest record "${PHASE_NUMBER}" --raw # .phase-manifest.json for /pp-undo --phase; never stops the run
|
|
853
868
|
```
|
|
854
869
|
|
|
870
|
+
**If no plan in this wave used worktrees** (project-level `USE_WORKTREES=false` OR `WAVE_WORKTREE_PLANS` is empty): sequential agents already updated STATE.md and ROADMAP.md themselves — skip this step.
|
|
871
|
+
|
|
855
872
|
5.75. **Execute:wave:post capability dispatch:**
|
|
856
873
|
|
|
857
874
|
After worktree merge, post-merge tests, and tracking updates, dispatch capability hooks registered at `execute:wave:post`. The primary hook is the `ui.safety-gate` gate from the UI capability — it verifies that any frontend files changed in this wave conform to the UI-SPEC contract.
|
|
858
875
|
|
|
859
876
|
```bash
|
|
860
|
-
WAVE_POST_HOOKS_JSON=$(pp_run loop render-hooks execute:wave:post --raw)
|
|
877
|
+
WAVE_POST_HOOKS_JSON=$(pp_run loop render-hooks execute:wave:post --raw)
|
|
878
|
+
printf '%s' "$WAVE_POST_HOOKS_JSON" | node -e "let h=[];try{h=JSON.parse(require('fs').readFileSync(0,'utf-8')).activeHooks||[]}catch{}console.log('WAVE_POST_HOOKS_JSON='+JSON.stringify({activeHooks:h}))"
|
|
861
879
|
```
|
|
862
880
|
|
|
863
|
-
Read the `activeHooks` array from `WAVE_POST_HOOKS_JSON
|
|
881
|
+
Read the `activeHooks` array from the printed `WAVE_POST_HOOKS_JSON=` line, in-context (do NOT pipe through a shell parser).
|
|
864
882
|
|
|
865
883
|
**If `activeHooks` is empty or absent:** Skip silently to step 5.8.
|
|
866
884
|
|
|
867
|
-
**
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
- **Blocking gate (`hook.blocking == true`) AND `GATE_RESULT.block == true`:** HALT — stop wave completion, do NOT proceed to step 5.8, and present:
|
|
883
|
-
|
|
884
|
-
```
|
|
885
|
-
⚠ Wave {N} blocked by capability gate ({hook.capId}): {GATE_RESULT.message}
|
|
886
|
-
Resolve before continuing to next wave.
|
|
887
|
-
```
|
|
888
|
-
|
|
889
|
-
This halt is **not** bypassed by `onError` — `onError` only covers command errors (step 1 above), not the gate's block decision.
|
|
890
|
-
|
|
891
|
-
- **Non-blocking gate (`hook.blocking == false`):** never halts. If `GATE_RESULT.block` is `true` (or non-empty `message`), print `⚠ {hook.capId} advisory (wave {N}): {GATE_RESULT.message}`, then:
|
|
892
|
-
- If `GATE_RESULT.spawn_mapper == true` OR `GATE_RESULT.directive == "auto-remap"`: spawn `pp-codebase-mapper` per `execute-phase/steps/codebase-drift-gate.md`; pass `--paths {GATE_RESULT.affected_paths}`. Continue regardless (wave NOT failed by remap failure).
|
|
893
|
-
- Otherwise: continue after advisory.
|
|
894
|
-
- If block `false` and no `message`: continue silently.
|
|
895
|
-
|
|
896
|
-
- **Blocking gate (`hook.blocking == true`) AND `GATE_RESULT.block == false`:** continue silently.
|
|
885
|
+
**Otherwise**, set `GATE_POINT=execute:wave:post`, `GATE_HOOKS_JSON=$WAVE_POST_HOOKS_JSON`,
|
|
886
|
+
`GATE_POSITIONAL_ARG="${PHASE_NUMBER}"` — preserving the positional phase-number argument this
|
|
887
|
+
call site has always passed — and `GATE_WS` to the active workstream name (empty in flat mode),
|
|
888
|
+
without which a phase-number positional cannot resolve on a partitioned project, then Read and follow
|
|
889
|
+
`pp-core/workflows/execute-phase/steps/check-query-gate.md`. That file is the single generic
|
|
890
|
+
`check.query` gate enforcer (GATE-02, D-VH-7): it owns the two-step contract (did the command
|
|
891
|
+
succeed? → then read the boolean `block`) and the halt. Do not restate its loop here.
|
|
892
|
+
|
|
893
|
+
**After the enforcer returns without halting**, perform this call site's own advisory follow-up
|
|
894
|
+
for each non-blocking entry it reported: if the verdict carried `spawn_mapper == true` OR
|
|
895
|
+
`directive == "auto-remap"`, spawn `pp-codebase-mapper` per
|
|
896
|
+
`execute-phase/steps/codebase-drift-gate.md`, passing `--paths {affected_paths}`. Continue
|
|
897
|
+
regardless — a remap failure never fails the wave. The enforcer owns the halt decision; this
|
|
898
|
+
directive handling is the host's, not the enforcer's.
|
|
897
899
|
|
|
898
900
|
**When all active gates are processed without a blocking halt:** continue to step 5.8.
|
|
899
901
|
|
|
@@ -949,7 +951,7 @@ increases monotonically across waves. `{status}` is `complete` (success),
|
|
|
949
951
|
---
|
|
950
952
|
## Wave {N} Complete
|
|
951
953
|
|
|
952
|
-
**{Plan ID}: {
|
|
954
|
+
**{Plan ID}: {Plan Name}**
|
|
953
955
|
{What was built — from SUMMARY.md}
|
|
954
956
|
{Notable deviations, if any}
|
|
955
957
|
|
|
@@ -995,7 +997,45 @@ increases monotonically across waves. `{status}` is `complete` (success),
|
|
|
995
997
|
9. **Proceed to next wave.**
|
|
996
998
|
</step>
|
|
997
999
|
<step name="checkpoint_handling">
|
|
998
|
-
Plans with `autonomous: false` require user interaction.
|
|
1000
|
+
Plans with `autonomous: false` require user interaction.
|
|
1001
|
+
**Auto-mode checkpoint handling:**
|
|
1002
|
+
Read auto-advance config (chain flag OR user preference — same boolean as `check.auto-mode`):
|
|
1003
|
+
```bash
|
|
1004
|
+
AUTO_MODE=$(pp_run query check auto-mode --pick active 2>/dev/null || echo "false")
|
|
1005
|
+
```
|
|
1006
|
+
|
|
1007
|
+
When executor returns a checkpoint AND (`UNATTENDED` or `AUTO_MODE`) is true (U-E1):
|
|
1008
|
+
- **human-action**, or package legitimacy — ANY of `**Gate:** blocking-human` in the return (the executor copies the task's `gate` attribute there), `gate="blocking-human"`, or `what-built` begins `Package`; the last two are the fallback for a return that predates the `Gate:` line → hard stop: present to user (below).
|
|
1009
|
+
- **human-verify** (other) → continuation with `{user_response}` = `"DEFERRED — not verified by a human (unattended run); record this checkpoint as not done in the SUMMARY and continue"`; log `⏭ Checkpoint deferred (recorded, not approved)`.
|
|
1010
|
+
- **decision** → continuation with the option marked recommended, else the first; log `⚡ Auto-selected: [option]`.
|
|
1011
|
+
|
|
1012
|
+
**Standard flow (neither flag, human-action, or blocking-human):**
|
|
1013
|
+
|
|
1014
|
+
1. Spawn agent for checkpoint plan
|
|
1015
|
+
2. Agent runs until checkpoint task or auth gate → returns structured state
|
|
1016
|
+
3. Agent return includes: completed tasks table, current task + blocker, checkpoint type/details, what's awaited
|
|
1017
|
+
4. **Present to user:**
|
|
1018
|
+
```
|
|
1019
|
+
## Checkpoint: [Type]
|
|
1020
|
+
|
|
1021
|
+
**Plan:** 03-03 Dashboard Layout
|
|
1022
|
+
**Progress:** 2/3 tasks complete
|
|
1023
|
+
|
|
1024
|
+
[Checkpoint Details from agent return]
|
|
1025
|
+
[Awaiting section from agent return]
|
|
1026
|
+
```
|
|
1027
|
+
5. User responds: "approved"/"done" | issue description | decision selection
|
|
1028
|
+
6. **Spawn continuation agent (NOT resume)** using continuation-prompt.md template:
|
|
1029
|
+
- `{completed_tasks_table}`: From checkpoint return
|
|
1030
|
+
- `{resume_task_number}` + `{resume_task_name}`: Current task
|
|
1031
|
+
- `{user_response}`: What user provided
|
|
1032
|
+
- `{resume_instructions}`: Based on checkpoint type
|
|
1033
|
+
7. Continuation agent verifies previous commits, continues from resume point
|
|
1034
|
+
8. Repeat until plan completes or user stops
|
|
1035
|
+
|
|
1036
|
+
**Fresh agent, not resume:** resume breaks with parallel tool calls.
|
|
1037
|
+
|
|
1038
|
+
**Checkpoints in parallel waves:** Agent pauses and returns while other parallel agents may complete. Present checkpoint, spawn continuation, wait for all before next wave.
|
|
999
1039
|
</step>
|
|
1000
1040
|
|
|
1001
1041
|
<step name="aggregate_results">
|
|
@@ -1022,10 +1062,13 @@ After all waves:
|
|
|
1022
1062
|
|
|
1023
1063
|
**Security gate check:**
|
|
1024
1064
|
```bash
|
|
1025
|
-
VERIFY_POST_HOOKS_JSON=$(pp_run loop render-hooks verify:post --raw
|
|
1065
|
+
VERIFY_POST_HOOKS_JSON=$(pp_run loop render-hooks verify:post --raw)
|
|
1066
|
+
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}))"
|
|
1026
1067
|
SECURITY_FILE=$(ls "${PHASE_DIR}"/*-SECURITY.md 2>/dev/null | head -1)
|
|
1027
1068
|
```
|
|
1028
1069
|
|
|
1070
|
+
**Trace gate.** Read `pp-core/workflows/execute-phase/steps/verify-post-gate.md`.
|
|
1071
|
+
|
|
1029
1072
|
Resolve active step hooks from `VERIFY_POST_HOOKS_JSON` where `kind == "step"` and `ref.skill == "secure-phase"`.
|
|
1030
1073
|
|
|
1031
1074
|
If no active secure-phase step hook exists: skip.
|
|
@@ -1073,20 +1116,15 @@ Selected wave finished successfully. This phase still has incomplete plans, so p
|
|
|
1073
1116
|
**If no incomplete plans remain after the selected wave finishes:**
|
|
1074
1117
|
- continue with the normal phase-level verification and completion flow below
|
|
1075
1118
|
- this means the selected wave happened to be the last remaining work in the phase
|
|
1076
|
-
|
|
1077
|
-
**verify:post gates** — every run that reaches this point (a partial run stopped above, so no planned plan is still waiting):
|
|
1078
|
-
```bash
|
|
1079
|
-
VERIFY_POST_GATES_JSON=$(pp_run loop run-gates verify:post --phase "${PHASE_NUMBER}" ${TIER_FLAG}) || exit 1
|
|
1080
|
-
```
|
|
1081
|
-
`loop run-gates` runs every active `verify:post` gate and owns the halt: exit 1 (a `⛔` line) stops the phase here — relay it; do not verify or mark the phase complete. `⚠` advisories: relay, continue.
|
|
1082
1119
|
</step>
|
|
1083
1120
|
|
|
1084
1121
|
<step name="code_review_gate" required="true">
|
|
1085
|
-
**This step is REQUIRED to evaluate the capability hook.** When the code-review capability is active, auto-invoke code review on the phase's source changes.
|
|
1122
|
+
**This step is REQUIRED to evaluate the capability hook.** When the code-review capability is active, auto-invoke code review on the phase's source changes. Advisory only — never blocks execution flow. Also dispatches advisory execute:post gate hooks (e.g. tdd.review-checkpoint).
|
|
1086
1123
|
|
|
1087
1124
|
**Capability gate:**
|
|
1088
1125
|
```bash
|
|
1089
|
-
EXECUTE_POST_HOOKS_JSON=${EXECUTE_POST_HOOKS_JSON:-$(pp_run loop render-hooks execute:post --raw
|
|
1126
|
+
EXECUTE_POST_HOOKS_JSON=${EXECUTE_POST_HOOKS_JSON:-$(pp_run loop render-hooks execute:post --raw)}
|
|
1127
|
+
printf '%s' "$EXECUTE_POST_HOOKS_JSON" | node -e "let h=[];try{h=JSON.parse(require('fs').readFileSync(0,'utf-8')).activeHooks||[]}catch{}console.log('EXECUTE_POST_HOOKS_JSON='+JSON.stringify({activeHooks:h}))"
|
|
1090
1128
|
```
|
|
1091
1129
|
|
|
1092
1130
|
Resolve active step hooks from `EXECUTE_POST_HOOKS_JSON` where `kind == "step"` and `ref.skill == "code-review"`.
|
|
@@ -1113,21 +1151,11 @@ Code review found issues. Consider running:
|
|
|
1113
1151
|
|
|
1114
1152
|
**Error handling:** If the Skill invocation fails or throws, catch the error, display "Code review encountered an error (non-blocking): {error}" and proceed to gate dispatch. Review failures must never block execution.
|
|
1115
1153
|
|
|
1116
|
-
**Execute:post gate hook dispatch.** After code review,
|
|
1117
|
-
```bash
|
|
1118
|
-
TRACE_GATE_JSON=$(pp_run loop run-gates execute:post --phase "${PHASE_NUMBER}" ${TIER_FLAG} --query vault.trace) || exit 1
|
|
1119
|
-
```
|
|
1120
|
-
Then dispatch every other active gate hook from `EXECUTE_POST_HOOKS_JSON` where `kind == "gate"` (skip `check.query == "vault.trace"`):
|
|
1121
|
-
|
|
1122
|
-
For each such gate hook:
|
|
1123
|
-
```bash
|
|
1124
|
-
GATE_RESULT=$(pp_run check ${hook.check.query} "${PHASE_NUMBER}" --raw)
|
|
1125
|
-
CHECK_EXIT=$?
|
|
1126
|
-
```
|
|
1154
|
+
**Execute:post gate hook dispatch.** After code review, dispatch all active gate hooks from `EXECUTE_POST_HOOKS_JSON` where `kind == "gate"`. If none are active, skip silently.
|
|
1127
1155
|
|
|
1128
|
-
|
|
1156
|
+
Set `GATE_POINT=execute:post`, `GATE_HOOKS_JSON=$EXECUTE_POST_HOOKS_JSON`, `GATE_POSITIONAL_ARG="${PHASE_NUMBER}"` and `GATE_WS` to the active workstream name (empty in flat mode) — without it the phase-number positional cannot resolve on a partitioned project, and this is the point where the blocking `vault.trace` gate is declared — then Read and follow `pp-core/workflows/execute-phase/steps/check-query-gate.md` — the same single generic `check.query` gate enforcer used at `execute:pre` and `execute:wave:post` (GATE-02, D-VH-7). It owns the two-step contract (did the command succeed? → then read the boolean `block`) and the halt. Do not restate its loop here.
|
|
1129
1157
|
|
|
1130
|
-
**TDD review escalation (overrides the advisory default for the `tdd.review-checkpoint` gate only).** The tdd `execute:post` gate is declared `blocking: false`, so
|
|
1158
|
+
**TDD review escalation (overrides the advisory default for the `tdd.review-checkpoint` gate only).** The tdd `execute:post` gate is declared `blocking: false`, so the enforcer displays its `message`/table and continues. There is ONE documented exception (see `~/.claude/pp-core/references/execute-mvp-tdd.md`), applied by this host workflow *after* the enforcer returns: when `MVP_MODE=true` AND `TDD_MODE=true` AND the enforcer reported a `true` block verdict for `tdd.review-checkpoint` (one or more TDD plans miss a RED or GREEN gate commit), the end-of-phase TDD review escalates from advisory to **blocking under MVP+TDD** — refuse to mark the phase complete and present:
|
|
1131
1159
|
|
|
1132
1160
|
```
|
|
1133
1161
|
Phase blocked: {N} TDD plan(s) violate the RED→GREEN gate sequence under MVP+TDD.
|
|
@@ -1136,7 +1164,7 @@ Resolve and re-run /pp:execute-phase, or override with /pp:execute-phase {phase}
|
|
|
1136
1164
|
|
|
1137
1165
|
(`--force-mvp-gate` is the documented, not-yet-implemented escape hatch.) Outside MVP+TDD, TDD-review violations remain advisory (table shown, execution continues).
|
|
1138
1166
|
|
|
1139
|
-
**Proceed rule:** If `MVP_MODE && TDD_MODE
|
|
1167
|
+
**Proceed rule:** If `MVP_MODE && TDD_MODE` and the enforcer's reported block verdict for `tdd.review-checkpoint` is `true`: STOP — do NOT proceed to `close_parent_artifacts`, `regression_gate`, `verify_phase_goal`, or `phase.complete`. Otherwise proceed normally.
|
|
1140
1168
|
</step>
|
|
1141
1169
|
|
|
1142
1170
|
<step name="close_parent_artifacts">
|
|
@@ -1259,12 +1287,12 @@ If `TEXT_MODE` is true, present as a plain-text numbered list and ask the user t
|
|
|
1259
1287
|
<step name="verify_phase_goal">
|
|
1260
1288
|
Verify phase achieved its GOAL, not just completed tasks.
|
|
1261
1289
|
|
|
1262
|
-
**Tier gate:** spawn the verifier only when `DISPATCH_PLAN.stages.verify` lists `pp-verifier` (= `verifier_enabled`). Otherwise print `Verifier skipped (tier {phase_tier.tier})`, treat the phase as `passed` and go to `update_roadmap`. When it lists `verify-install` (heavy tier), first Read and execute `pp-core/workflows/execute-phase/steps/install-run.md`: the installed-product run the verifier judges on. When it lists `verify-vault-review` (heavy tier, vault practices on), after the verifier returns, set `FORCE=1` and Read and execute `pp-core/workflows/vault-review.md` for this phase: it reports and never changes the route.
|
|
1263
|
-
|
|
1264
1290
|
```bash
|
|
1265
1291
|
VERIFIER_SKILLS=$(pp_run query agent-skills pp-verifier)
|
|
1266
1292
|
```
|
|
1267
1293
|
|
|
1294
|
+
Read and execute `execute-phase/steps/verifier-practice-payload.md` (sets `PRACTICE_VERDICT_INPUT`).
|
|
1295
|
+
|
|
1268
1296
|
```
|
|
1269
1297
|
Agent(
|
|
1270
1298
|
description="Verify phase {phase_number} goal achievement",
|
|
@@ -1283,11 +1311,11 @@ MANDATORY: load every file listed here with the Read tool before you start the w
|
|
|
1283
1311
|
- .planning/REQUIREMENTS.md (Requirement traceability)
|
|
1284
1312
|
- {phase_dir}/*-CONTEXT.md (User decisions — verify they were honored)
|
|
1285
1313
|
- {phase_dir}/*-RESEARCH.md (Known pitfalls — check for traps)
|
|
1286
|
-
${
|
|
1287
|
-
` : ''}${CONTEXT_WINDOW >= 500000 ? `- Prior VERIFICATION.md files from earlier phases (regression check)
|
|
1314
|
+
${CONTEXT_WINDOW >= 500000 ? `- Prior VERIFICATION.md files from earlier phases (regression check)
|
|
1288
1315
|
` : ''}
|
|
1289
1316
|
</files_to_read>
|
|
1290
1317
|
|
|
1318
|
+
${PRACTICE_VERDICT_INPUT}
|
|
1291
1319
|
${VERIFIER_SKILLS}",
|
|
1292
1320
|
subagent_type="pp-verifier",
|
|
1293
1321
|
model="{verifier_model}"
|
|
@@ -1405,7 +1433,7 @@ Gap closure cycle: `/pp:plan-phase {X} --gaps ${GSD_WS}` reads VERIFICATION.md
|
|
|
1405
1433
|
<step name="update_roadmap">
|
|
1406
1434
|
**Mark phase complete and update all tracking files:**
|
|
1407
1435
|
|
|
1408
|
-
|
|
1436
|
+
Reached only after the `execute:post` gate dispatch above returned without halting and `verify_phase_goal` reported `passed` — completion follows that outcome, never a plan or SUMMARY count (D-08-13). `phase.complete` writes ROADMAP.md, REQUIREMENTS.md and STATE.md in one transaction with rollback: both move or neither does (D-08-14). Until here the phase reads `Built` (D-08-15).
|
|
1409
1437
|
|
|
1410
1438
|
```bash
|
|
1411
1439
|
COMPLETION=$(pp_run query phase.complete "${PHASE_NUMBER}")
|
|
@@ -1432,7 +1460,6 @@ These items are tracked and will appear in `/pp:progress` and `/pp:audit-uat`.
|
|
|
1432
1460
|
|
|
1433
1461
|
```bash
|
|
1434
1462
|
pp_run query commit "docs(phase-{X}): complete phase execution" --files .planning/ROADMAP.md .planning/STATE.md .planning/REQUIREMENTS.md {phase_dir}/*-VERIFICATION.md
|
|
1435
|
-
pp_run phase manifest record "${PHASE_NUMBER}" --raw # the completion commit joins the /pp-undo --phase list
|
|
1436
1463
|
```
|
|
1437
1464
|
</step>
|
|
1438
1465
|
|