@pareto4/pp-core 1.20.0 → 1.21.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 +1 -1
- package/agents/pp-nyquist-auditor.md +19 -14
- package/agents/pp-plan-checker.md +59 -36
- package/agents/pp-planner.md +34 -53
- package/agents/pp-verifier.md +3 -52
- package/commands/pp-autonomous.md +2 -1
- package/commands/pp-plan-phase.md +2 -1
- package/commands/pp-plan-review-convergence.md +2 -1
- package/gemini-extension.json +1 -1
- package/package.json +1 -1
- package/pp-core/bin/lib/capability-activation.cjs +77 -0
- package/pp-core/bin/lib/capability-registry.cjs +14 -14
- package/pp-core/bin/lib/capability-state.cjs +8 -18
- package/pp-core/bin/lib/ceremony.cjs +1342 -0
- package/pp-core/bin/lib/check-command-router.cjs +62 -1
- package/pp-core/bin/lib/commands.cjs +29 -3
- package/pp-core/bin/lib/config.cjs +5 -0
- package/pp-core/bin/lib/init.cjs +50 -1
- package/pp-core/bin/lib/io.cjs +2 -0
- package/pp-core/bin/lib/loop-resolver.cjs +26 -12
- package/pp-core/bin/lib/phase.cjs +50 -8
- package/pp-core/bin/lib/plan-sizing.cjs +346 -0
- package/pp-core/bin/lib/state.cjs +1 -0
- package/pp-core/bin/lib/test-substance.cjs +3190 -0
- package/pp-core/bin/lib/timeline.cjs +605 -0
- package/pp-core/bin/pp-tools.cjs +71 -4
- package/pp-core/bin/shared/ceremony-gates.json +17 -0
- package/pp-core/bin/shared/config-schema.manifest.json +1 -0
- package/pp-core/references/ceremony.md +81 -0
- package/pp-core/references/few-shot-examples/plan-checker.md +8 -8
- package/pp-core/references/phase-timeline.md +107 -0
- package/pp-core/references/planner-antipatterns.md +32 -0
- package/pp-core/references/planner-guidance.md +17 -14
- package/pp-core/references/planner-revision.md +1 -1
- package/pp-core/references/planning-config.md +3 -2
- package/pp-core/references/test-substance.md +324 -0
- package/pp-core/references/verifier-stub-patterns.md +51 -0
- package/pp-core/templates/VALIDATION.md +1 -0
- package/pp-core/templates/phase-prompt.md +19 -7
- package/pp-core/templates/roadmap.md +1 -1
- package/pp-core/templates/verification-report.md +1 -1
- package/pp-core/workflows/audit-milestone.md +4 -1
- package/pp-core/workflows/autonomous.md +11 -8
- package/pp-core/workflows/code-review.md +21 -9
- package/pp-core/workflows/execute-phase/steps/check-query-gate.md +7 -7
- package/pp-core/workflows/execute-phase/steps/codebase-drift-gate.md +3 -2
- package/pp-core/workflows/execute-phase.md +15 -4
- package/pp-core/workflows/init/steps/client-context-capture.md +1 -1
- package/pp-core/workflows/plan-phase/steps/chunked-planning.md +7 -3
- package/pp-core/workflows/plan-phase/steps/prd-express.md +104 -0
- package/pp-core/workflows/plan-phase.md +47 -114
- package/pp-core/workflows/plan-review-convergence.md +6 -3
- package/pp-core/workflows/profile-user.md +2 -2
- package/pp-core/workflows/quick.md +1 -1
- package/pp-core/workflows/ship.md +3 -3
- package/pp-core/workflows/spec-phase.md +2 -2
- package/pp-core/workflows/stats.md +19 -4
- package/pp-core/workflows/validate-phase.md +19 -4
- package/pp-core/workflows/verify-phase.md +1 -1
- package/pp-core/workflows/verify-work.md +1 -1
- package/scripts/gen-capability-registry.cjs +43 -45
- package/scripts/run-tests.cjs +54 -30
|
@@ -53,8 +53,9 @@ Parse optional flags from $ARGUMENTS using the typed flag parser:
|
|
|
53
53
|
# This is the canonical flag-parsing surface — do not replicate inline bash parsing
|
|
54
54
|
# for --fix/--all/--auto here; the module handles all flag extraction and implication
|
|
55
55
|
# logic (e.g., --all and --auto imply --fix).
|
|
56
|
+
PP_LIB=$(printf '%s\n' "${PP_TOOLS:+${PP_TOOLS%/*}:}$PATH" | tr : '\n' | while IFS= read -r d; do if [ -r "$d/lib/code-review-flags.cjs" ]; then printf %s "$d/lib"; break; fi; done); export PP_LIB="${PP_LIB:-$PWD/pp-core/bin/lib}"
|
|
56
57
|
FLAGS_JSON=$(node -e "
|
|
57
|
-
const { parseCodeReviewFlags } = require('
|
|
58
|
+
const { parseCodeReviewFlags } = require(require('path').resolve(process.env.PP_LIB, 'code-review-flags.cjs'));
|
|
58
59
|
const flags = parseCodeReviewFlags(process.argv.slice(1));
|
|
59
60
|
process.stdout.write(JSON.stringify(flags));
|
|
60
61
|
" -- "$@" 2>/dev/null)
|
|
@@ -106,15 +107,19 @@ Default is active through the Capability Registry schema — only skip when the
|
|
|
106
107
|
Determine review depth with priority order:
|
|
107
108
|
|
|
108
109
|
1. DEPTH_OVERRIDE from --depth flag (highest priority)
|
|
109
|
-
2.
|
|
110
|
-
3.
|
|
110
|
+
2. Phase verdict: `pp_run ceremony get "${PHASE_ARG}" --pick code_review_depth` (the configured depth when no verdict is recorded)
|
|
111
|
+
3. Config value: `pp-tools.cjs query config-get workflow.code_review_depth 2>/dev/null`
|
|
112
|
+
4. Default: "standard"
|
|
111
113
|
|
|
112
114
|
```bash
|
|
113
115
|
if [ -n "$DEPTH_OVERRIDE" ]; then
|
|
114
116
|
REVIEW_DEPTH="$DEPTH_OVERRIDE"
|
|
115
117
|
else
|
|
116
|
-
|
|
117
|
-
|
|
118
|
+
REVIEW_DEPTH=$(pp_run ceremony get "${PHASE_ARG}" --pick code_review_depth 2>/dev/null || echo "")
|
|
119
|
+
if [ -z "$REVIEW_DEPTH" ]; then
|
|
120
|
+
CONFIG_DEPTH=$(pp_run query config-get workflow.code_review_depth --raw 2>/dev/null || echo "")
|
|
121
|
+
REVIEW_DEPTH="${CONFIG_DEPTH:-standard}"
|
|
122
|
+
fi
|
|
118
123
|
fi
|
|
119
124
|
```
|
|
120
125
|
|
|
@@ -369,8 +374,9 @@ When `FALLOW_ENABLED=true`:
|
|
|
369
374
|
|
|
370
375
|
1) Resolve binary via PATH first, then `node_modules/.bin/fallow`.
|
|
371
376
|
```bash
|
|
377
|
+
PP_LIB=$(printf '%s\n' "${PP_TOOLS:+${PP_TOOLS%/*}:}$PATH" | tr : '\n' | while IFS= read -r d; do if [ -r "$d/lib/fallow-runner.cjs" ]; then printf %s "$d/lib"; break; fi; done); export PP_LIB="${PP_LIB:-$PWD/pp-core/bin/lib}"
|
|
372
378
|
FALLOW_BIN=$(FALLOW_CWD="$(pwd)" node -e "
|
|
373
|
-
const { resolveFallowBinary } = require('
|
|
379
|
+
const { resolveFallowBinary } = require(require('path').resolve(process.env.PP_LIB, 'fallow-runner.cjs'));
|
|
374
380
|
const resolved = resolveFallowBinary({ cwd: process.env.FALLOW_CWD });
|
|
375
381
|
if (resolved) process.stdout.write(resolved);
|
|
376
382
|
")
|
|
@@ -493,9 +499,10 @@ if [ -n "$FALLOW_JSON_PATH" ] && [ -f "$FALLOW_JSON_PATH" ]; then
|
|
|
493
499
|
# Normalize fallow's raw report into the compact {summary, findings[]} contract
|
|
494
500
|
# the reviewer consumes (real fallow schema -> normalized findings).
|
|
495
501
|
FALLOW_NORMALIZED_PATH="${PHASE_DIR}/FALLOW-normalized.json"
|
|
502
|
+
PP_LIB=$(printf '%s\n' "${PP_TOOLS:+${PP_TOOLS%/*}:}$PATH" | tr : '\n' | while IFS= read -r d; do if [ -r "$d/lib/fallow-runner.cjs" ]; then printf %s "$d/lib"; break; fi; done); export PP_LIB="${PP_LIB:-$PWD/pp-core/bin/lib}"
|
|
496
503
|
FALLOW_SRC="$FALLOW_JSON_PATH" FALLOW_OUT="$FALLOW_NORMALIZED_PATH" node -e "
|
|
497
504
|
const fs = require('fs');
|
|
498
|
-
const { normalizeFallowReportFile } = require('
|
|
505
|
+
const { normalizeFallowReportFile } = require(require('path').resolve(process.env.PP_LIB, 'fallow-runner.cjs'));
|
|
499
506
|
const n = normalizeFallowReportFile(process.env.FALLOW_SRC);
|
|
500
507
|
fs.writeFileSync(process.env.FALLOW_OUT, JSON.stringify(n, null, 2));
|
|
501
508
|
" 2>/dev/null && FALLOW_EMBED_PATH="$FALLOW_NORMALIZED_PATH" || FALLOW_EMBED_PATH="$FALLOW_JSON_PATH"
|
|
@@ -514,6 +521,8 @@ Spawn the pp-code-reviewer agent:
|
|
|
514
521
|
|
|
515
522
|
Print: `◆ Spawning code reviewer... (runs in a subagent — no output until it returns, ~1–5 min; expected, not a freeze)`
|
|
516
523
|
|
|
524
|
+
`pp_run timeline start code-reviewer "${PHASE_ARG}" --model inherit || true` — rules: `pp-core/references/phase-timeline.md`
|
|
525
|
+
|
|
517
526
|
```
|
|
518
527
|
Agent(subagent_type="pp-code-reviewer", prompt="
|
|
519
528
|
<files_to_read>
|
|
@@ -540,7 +549,7 @@ ${AGENT_SKILLS_REVIEWER}")
|
|
|
540
549
|
|
|
541
550
|
**Agent failure handling:**
|
|
542
551
|
|
|
543
|
-
If the Agent() call fails (agent error, timeout, or exception):
|
|
552
|
+
If the Agent() call fails (agent error, timeout, or exception): first run `pp_run timeline end code-reviewer "${PHASE_ARG}" failed || true`, then show:
|
|
544
553
|
```
|
|
545
554
|
Error: Code review agent failed: ${error_message}
|
|
546
555
|
|
|
@@ -555,6 +564,7 @@ After agent completes successfully, verify REVIEW.md was created and has valid s
|
|
|
555
564
|
|
|
556
565
|
```bash
|
|
557
566
|
[ -z "${ZSH_VERSION:-}" ] || emulate -R sh
|
|
567
|
+
TL_OUTCOME=failed
|
|
558
568
|
if [ -f "${REVIEW_PATH}" ]; then
|
|
559
569
|
# Validate REVIEW.md has valid YAML frontmatter with status field
|
|
560
570
|
HAS_STATUS=$(REVIEW_PATH="${REVIEW_PATH}" node -e "
|
|
@@ -565,12 +575,13 @@ if [ -f "${REVIEW_PATH}" ]; then
|
|
|
565
575
|
" 2>/dev/null)
|
|
566
576
|
|
|
567
577
|
if [ "$HAS_STATUS" = "valid" ]; then
|
|
578
|
+
TL_OUTCOME=complete
|
|
568
579
|
echo "REVIEW.md created at ${REVIEW_PATH}"
|
|
569
580
|
|
|
570
581
|
if [ "$COMMIT_DOCS" = "true" ]; then
|
|
571
582
|
pp_run query commit \
|
|
572
583
|
"docs(planning): add code review report" --phase "${PADDED_PHASE}" \
|
|
573
|
-
--files "${REVIEW_PATH}"
|
|
584
|
+
--files "${REVIEW_PATH}" "${PHASE_DIR}"/*-TIMELINE.jsonl
|
|
574
585
|
fi
|
|
575
586
|
else
|
|
576
587
|
echo "Warning: REVIEW.md exists but has invalid or missing frontmatter (no status field)."
|
|
@@ -580,6 +591,7 @@ else
|
|
|
580
591
|
echo "Warning: Agent completed but REVIEW.md not found at ${REVIEW_PATH}. This may indicate an agent issue."
|
|
581
592
|
echo "No REVIEW.md to commit. Please retry with /pp:code-review ${PHASE_ARG}"
|
|
582
593
|
fi
|
|
594
|
+
pp_run timeline end code-reviewer "${PHASE_ARG}" "${TL_OUTCOME}" || true
|
|
583
595
|
```
|
|
584
596
|
</step>
|
|
585
597
|
|
|
@@ -54,13 +54,13 @@ old numbers, which is how 05-13 shifted three rows ~200 lines into a different f
|
|
|
54
54
|
|
|
55
55
|
| Query | Handler branch / function | Emits boolean `block` on every path? | Emission site(s) |
|
|
56
56
|
|-------|---------------------------|--------------------------------------|------------------|
|
|
57
|
-
| `gap-analysis.plan-post` | `gap-analysis-plan-post` branch (`cmdGapAnalysisPlanPost`) | yes — always `false` (advisory by design) | `src/check-command-router.cts:
|
|
58
|
-
| `ship.platform-drift` | `ship-platform-drift` branch (`cmdShipPlatformDrift`) | yes — the only producer that can emit `block: true` from a threshold comparison | `src/check-command-router.cts:
|
|
59
|
-
| `tdd.review-checkpoint` | `tdd-review-checkpoint` branch | yes — `block = violations > 0`, advisory in the capability | `src/check-command-router.cts:
|
|
60
|
-
| `ui.plan-gate` | `ui-plan-gate` branch (`computeUiPlanGate`) | yes — `block = frontend && !hasUiSpec` | `src/check-command-router.cts:
|
|
61
|
-
| `ui.safety-gate` | `ui-safety-gate` branch (`computeUiSafetyGate`) | yes — `block = frontend && hasUiFiles && !hasUiSpec` | `src/check-command-router.cts:
|
|
62
|
-
| `vault.status` | `vault-status` branch (`cmdVaultStatus`) | yes — COMPUTED, not constant: `block` is the `vault.required` policy applied to the shared tier-keyed verdict leaf (`computeVaultVerdict`, GATE-01 / D-VH-4). It is `false` with the policy off (STRICT-01's byte-identical promise), on the inert path (`.platform-bindings.json` absent — that branch runs FIRST by requirement, T-02-28, because `tier !== 'client'` is true of `undefined` and would otherwise block every non-Pareto project), and for a present, fresh, client-tier vault; it is `true` on a required miss, on a fallback-tier load, on a stale client vault whatever its source (D-08-01; the block skips staleness only when `vault.cache_ttl_hours` is 0, D-08-28), and on a client cache fetched from a ref the project no longer configures (D-08-23). The attributed override (`applyVaultOverride`, GATE-07) then gets the last word on every blocking path, and that overwrite is the last emission site cited; and on a passing required-on verdict the envelope now carries a `message` (the success line, D-08-20) — the enforcer's every-run passthrough prints it. | `src/check-command-router.cts:
|
|
63
|
-
| `vault.trace` | `vault-trace` branch (`cmdVaultTrace`) — declared by the `vault` capability (`when: vault.enabled`) at **four** points, `plan:post`, `execute:post`, `ship:pre` and `verify:post`, all `blocking: true` / `onError: halt`, and once more at `ship:pre` as a seal gate (`onRecordedArtifacts: true`) that renders with `vault.enabled` off over a phase holding vault records (16-08). It judges each PLAN's `<vault_standards>` block and each SUMMARY's `## Standards Consulted` section through `src/vault-standards.cts` and fails closed on the `standards_*` kinds (`standards_block_absent`, `standards_block_duplicate`, `standards_block_unterminated`, `standards_block_malformed`, `standards_reason_invalid`, `standards_document_duplicate`, `standards_degraded_mixed`, `standards_none_without_reason`, `standards_path_not_resolved`, `standards_pin_mismatch`, `standards_cache_unreadable`, `standards_degraded_untrue`, `standards_consulted_absent`, `standards_consulted_mismatch`, `standards_plan_id_mismatch`, `standards_pair_missing`, `standards_orphan_summary`, `standards_anchor_malformed`). Reads `--stage` (04-03) and `--unpaired` (04-07, D-10); `ship:pre` sets `GATE_UNPAIRED=strict` unconditionally, `verify:post` sets it only on a full-phase run and leaves it unset when **either** partial-execution mode is active — the host's `WAVE_FILTER` set, or `--gaps-only` (04-12, CR-04; 04-18, WR-01) — and the other two leave the tolerant default | yes — `false` before any policy is read (inert), `false` with status `inactive` when `vault.enabled` is off and the phase holds no vault records, `true` once a standards record fails to validate; an agreeing degraded record with `vault.required` off is `false` with a message (D-29), and a recorded override is `false` at the tolerant points and `true` at the strict ones; `true` with status `disabled_with_artifacts` when `vault.enabled` is off and the positional's phase (or plan file) holds engine-written vault records (16-09, SEAL-02, D-21) — the answer the `ship:pre` seal gate dispatches for | `src/check-command-router.cts:
|
|
57
|
+
| `gap-analysis.plan-post` | `gap-analysis-plan-post` branch (`cmdGapAnalysisPlanPost`) | yes — always `false` (advisory by design) | `src/check-command-router.cts:1151` |
|
|
58
|
+
| `ship.platform-drift` | `ship-platform-drift` branch (`cmdShipPlatformDrift`) | yes — the only producer that can emit `block: true` from a threshold comparison | `src/check-command-router.cts:1253,1263,1272,1289,1331,1340,1354` |
|
|
59
|
+
| `tdd.review-checkpoint` | `tdd-review-checkpoint` branch | yes — `block = violations > 0`, advisory in the capability | `src/check-command-router.cts:1032,1106` |
|
|
60
|
+
| `ui.plan-gate` | `ui-plan-gate` branch (`computeUiPlanGate`) | yes — `block = frontend && !hasUiSpec` | `src/check-command-router.cts:705` (emitted at `:729`) |
|
|
61
|
+
| `ui.safety-gate` | `ui-safety-gate` branch (`computeUiSafetyGate`) | yes — `block = frontend && hasUiFiles && !hasUiSpec` | `src/check-command-router.cts:885` (emitted at `:911`) |
|
|
62
|
+
| `vault.status` | `vault-status` branch (`cmdVaultStatus`) | yes — COMPUTED, not constant: `block` is the `vault.required` policy applied to the shared tier-keyed verdict leaf (`computeVaultVerdict`, GATE-01 / D-VH-4). It is `false` with the policy off (STRICT-01's byte-identical promise), on the inert path (`.platform-bindings.json` absent — that branch runs FIRST by requirement, T-02-28, because `tier !== 'client'` is true of `undefined` and would otherwise block every non-Pareto project), and for a present, fresh, client-tier vault; it is `true` on a required miss, on a fallback-tier load, on a stale client vault whatever its source (D-08-01; the block skips staleness only when `vault.cache_ttl_hours` is 0, D-08-28), and on a client cache fetched from a ref the project no longer configures (D-08-23). The attributed override (`applyVaultOverride`, GATE-07) then gets the last word on every blocking path, and that overwrite is the last emission site cited; and on a passing required-on verdict the envelope now carries a `message` (the success line, D-08-20) — the enforcer's every-run passthrough prints it. | `src/check-command-router.cts:1710,1725,1764,1791,1852` (02-11: CHECKED by the same two-directional probe as the other rows — every cited line lies inside `cmdVaultStatus` and emits a block, and every emission site is cited. This was the one row the probe did NOT cover, so it is the row that rotted: wave 1 wrote the claim before 02-06 computed the block, and 05-13 shifted the citations arithmetically into the manifest-sanitiser, ~200 lines outside the handler) 14-06: + the envelope always carries `reason`, `status` may be `degraded` (index missing / unparseable / empty / unresolvable / unchecked, D-12), the flat index fields follow the override keys, and the healthy message is the one-line standards card (D-15); a degraded index blocks exactly when `vault.required` is on, through the same override (D-13), so it adds no emission site of its own. |
|
|
63
|
+
| `vault.trace` | `vault-trace` branch (`cmdVaultTrace`) — declared by the `vault` capability (`when: vault.enabled`) at **four** points, `plan:post`, `execute:post`, `ship:pre` and `verify:post`, all `blocking: true` / `onError: halt`, and once more at `ship:pre` as a seal gate (`onRecordedArtifacts: true`) that renders with `vault.enabled` off over a phase holding vault records (16-08). It judges each PLAN's `<vault_standards>` block and each SUMMARY's `## Standards Consulted` section through `src/vault-standards.cts` and fails closed on the `standards_*` kinds (`standards_block_absent`, `standards_block_duplicate`, `standards_block_unterminated`, `standards_block_malformed`, `standards_reason_invalid`, `standards_document_duplicate`, `standards_degraded_mixed`, `standards_none_without_reason`, `standards_path_not_resolved`, `standards_pin_mismatch`, `standards_cache_unreadable`, `standards_degraded_untrue`, `standards_consulted_absent`, `standards_consulted_mismatch`, `standards_plan_id_mismatch`, `standards_pair_missing`, `standards_orphan_summary`, `standards_anchor_malformed`). Reads `--stage` (04-03) and `--unpaired` (04-07, D-10); `ship:pre` sets `GATE_UNPAIRED=strict` unconditionally, `verify:post` sets it only on a full-phase run and leaves it unset when **either** partial-execution mode is active — the host's `WAVE_FILTER` set, or `--gaps-only` (04-12, CR-04; 04-18, WR-01) — and the other two leave the tolerant default | yes — `false` before any policy is read (inert), `false` with status `inactive` when `vault.enabled` is off and the phase holds no vault records, `true` once a standards record fails to validate; an agreeing degraded record with `vault.required` off is `false` with a message (D-29), and a recorded override is `false` at the tolerant points and `true` at the strict ones; `true` with status `disabled_with_artifacts` when `vault.enabled` is off and the positional's phase (or plan file) holds engine-written vault records (16-09, SEAL-02, D-21) — the answer the `ship:pre` seal gate dispatches for | `src/check-command-router.cts:3066,3078,3081,3113,3144,3169,3199,3225,3500` (04-16: CHECKED — a test asserts every line cited here lies inside `cmdVaultTrace` and carries a `block` emission, because four plans in this pass moved these numbers and nothing noticed). 16-07 (SEAL-01): at the strict points only, `appendSealProblems` compares the phase's recorded end anchors with `HEAD` through bounded git and adds `uncovered_source_commit` (a source commit after the ends that no record's start-end range covers), `anchor_missing`, `anchor_start_missing`, `anchor_unknown`, `anchor_not_ancestor` and `seal_could_not_check` (all blocking) and the `anchor_backfilled` note; it pushes problems into `checked` and owns no emission site and no status. 16-09 (SEAL-02): + the `disabled_with_artifacts` emission inside the switch-off guard. Standards-only vault: re-derived with the probe's own `handlerRange`/`emitsBlock` after the second record family, the invalid-config refusal and the envelope's mode tag left the handler. |
|
|
64
64
|
| `verify.codebase-drift` | `verify-codebase-drift` branch (`verify.cmdVerifyCodebaseDrift`) | yes — `block = action_required` | `src/verify.cts:2134,2149,2164,2186,2231,2246` |
|
|
65
65
|
| `verify.schema-drift` | `verify-schema-drift` branch (`verify.cmdVerifySchemaDrift`) | yes — `block = !skipped && driftDetected` | `src/verify.cts:2051,2071,2108` |
|
|
66
66
|
|
|
@@ -60,6 +60,7 @@ from step `init_context` is for `pp-executor`, not the mapper):
|
|
|
60
60
|
# with the single-canonical-preamble parity invariant (#619). This block only runs on the
|
|
61
61
|
# `auto-remap` directive, which is always reached after the drift check above has run.
|
|
62
62
|
AGENT_SKILLS_MAPPER=$(pp_run query agent-skills pp-codebase-mapper)
|
|
63
|
+
pp_run timeline start other "${PHASE_NUMBER}" --agent pp-codebase-mapper --source execute-phase --model inherit || true
|
|
63
64
|
```
|
|
64
65
|
|
|
65
66
|
Then spawn `pp-codebase-mapper` agents with the `--paths` hint (runs in a subagent — no output until it returns, ~1–5 min; expected, not a freeze):
|
|
@@ -80,11 +81,11 @@ ${AGENT_SKILLS_MAPPER}"
|
|
|
80
81
|
|
|
81
82
|
> **ORCHESTRATOR RULE — CODEX RUNTIME**: After calling Agent() above, stop working on this task immediately. Do not read more files, edit code, or run tests related to this task while the subagent is active. Wait for the subagent to return its result. This prevents duplicate work, conflicting edits, and wasted context. Only resume when the subagent result is available.
|
|
82
83
|
|
|
83
|
-
If the spawn fails or the agent reports an error: log `Codebase drift
|
|
84
|
+
If the spawn fails or the agent reports an error: run `pp_run timeline end other "${PHASE_NUMBER}" failed || true`, then log `Codebase drift
|
|
84
85
|
auto-remap failed: {reason}` and continue to `verify_phase_goal`. The phase
|
|
85
86
|
is NOT failed by a remap failure.
|
|
86
87
|
|
|
87
|
-
If the remap succeeds: log `Codebase drift auto-remap completed for paths:
|
|
88
|
+
If the remap succeeds: run `pp_run timeline end other "${PHASE_NUMBER}" complete || true`, then log `Codebase drift auto-remap completed for paths:
|
|
88
89
|
{affected_paths}` and continue to `verify_phase_goal`.
|
|
89
90
|
|
|
90
91
|
The two relevant config keys (continue on error / failure if either is invalid):
|
|
@@ -87,7 +87,7 @@ if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
|
87
87
|
AGENT_SKILLS=$(pp_run query agent-skills pp-executor)
|
|
88
88
|
```
|
|
89
89
|
|
|
90
|
-
Parse JSON for: `executor_model`, `verifier_model`, `commit_docs`, `parallelization`, `branching_strategy`, `branch_name`, `phase_found`, `phase_dir`, `phase_number`, `phase_name`, `phase_slug`, `plans`, `incomplete_plans`, `plan_count`, `incomplete_count`, `state_exists`, `roadmap_exists`, `phase_req_ids`, `response_language`.
|
|
90
|
+
Parse JSON for: `executor_model`, `verifier_model`, `commit_docs`, `parallelization`, `branching_strategy`, `branch_name`, `phase_found`, `phase_dir`, `phase_number`, `phase_name`, `phase_slug`, `plans`, `incomplete_plans`, `plan_count`, `incomplete_count`, `state_exists`, `roadmap_exists`, `phase_req_ids`, `verifier_depth`, `response_language`.
|
|
91
91
|
|
|
92
92
|
**Model resolution:** If `executor_model` is `"inherit"`, omit the `model=` parameter from all `Agent()` calls — do NOT pass `model="inherit"` to Agent. Omitting the `model=` parameter causes Claude Code to inherit the current orchestrator model automatically. Only set `model=` when `executor_model` is an explicit model name (e.g., `"claude-sonnet-4-6"`, `"claude-opus-4-7"`).
|
|
93
93
|
|
|
@@ -535,6 +535,8 @@ increases monotonically across waves. `{status}` is `complete` (success),
|
|
|
535
535
|
|
|
536
536
|
`[checkpoint] phase {PHASE_NUMBER} wave {N}/{M} plan {plan_id} starting ({P}/{Q} plans done)`
|
|
537
537
|
|
|
538
|
+
Then `pp_run timeline start executor "${PHASE_NUMBER}" --plan {plan_id} --model "{executor_model}" || true` — rules: `pp-core/references/phase-timeline.md`
|
|
539
|
+
|
|
538
540
|
Pass paths only — executors read files themselves with their fresh context window.
|
|
539
541
|
For 200k models, this keeps orchestrator context lean (~10-15%).
|
|
540
542
|
For 1M+ models (Opus 4.6, Sonnet 4.6), richer context can be passed directly.
|
|
@@ -547,7 +549,7 @@ increases monotonically across waves. `{status}` is `complete` (success),
|
|
|
547
549
|
DISPATCH_TS=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
|
|
548
550
|
EXPECTED_BRANCH=$(git rev-parse --abbrev-ref HEAD)
|
|
549
551
|
if [ "${USE_WORKTREES_FOR_PLAN:-true}" != "false" ] && [ -z "${WAVE_WORKTREE_MANIFEST:-}" ]; then
|
|
550
|
-
WAVE_WORKTREE_MANIFEST=$(mktemp "${TMPDIR:-/tmp}/pp-worktree-wave-XXXXXX
|
|
552
|
+
WAVE_WORKTREE_MANIFEST=$(mktemp "${TMPDIR:-/tmp}/pp-worktree-wave-XXXXXX")
|
|
551
553
|
# Persist the dispatch-time orchestrator worktree root so wave-cleanup can pin back to the
|
|
552
554
|
# orchestrator's OWN worktree — NOT `git worktree list`'s first entry (always the main
|
|
553
555
|
# checkout), which pins a non-primary (per-phase lane) orchestrator off its branch (#630).
|
|
@@ -699,6 +701,8 @@ increases monotonically across waves. `{status}` is `complete` (success),
|
|
|
699
701
|
[checkpoint] phase {PHASE_NUMBER} wave {N}/{M} plan {plan_id} checkpoint ({P}/{Q} plans done)
|
|
700
702
|
```
|
|
701
703
|
|
|
704
|
+
Run `pp_run timeline end executor "${PHASE_NUMBER}" {outcome} --plan {plan_id} || true` per line (`{outcome}`: that word, or `fallback` if the spot-check confirmed it). Background worktree executors end here, not after `Agent()`.
|
|
705
|
+
|
|
702
706
|
**Completion signal fallback (Copilot and runtimes where Agent() may not return):**
|
|
703
707
|
|
|
704
708
|
If a spawned agent does not return a completion signal but appears to have finished
|
|
@@ -1070,7 +1074,7 @@ After all waves:
|
|
|
1070
1074
|
**Security gate check:**
|
|
1071
1075
|
```bash
|
|
1072
1076
|
[ -z "${ZSH_VERSION:-}" ] || emulate -R sh
|
|
1073
|
-
VERIFY_POST_HOOKS_JSON=$(pp_run loop render-hooks verify:post --raw)
|
|
1077
|
+
VERIFY_POST_HOOKS_JSON=$(pp_run loop render-hooks verify:post --raw --phase "${PHASE_NUMBER}")
|
|
1074
1078
|
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}))"
|
|
1075
1079
|
SECURITY_FILE=$(ls "${PHASE_DIR}"/*-SECURITY.md 2>/dev/null | head -1)
|
|
1076
1080
|
```
|
|
@@ -1298,6 +1302,7 @@ Verify phase achieved its GOAL, not just completed tasks.
|
|
|
1298
1302
|
|
|
1299
1303
|
```bash
|
|
1300
1304
|
VERIFIER_SKILLS=$(pp_run query agent-skills pp-verifier)
|
|
1305
|
+
pp_run timeline start verifier "${PHASE_NUMBER}" || true
|
|
1301
1306
|
```
|
|
1302
1307
|
|
|
1303
1308
|
```
|
|
@@ -1307,6 +1312,7 @@ Agent(
|
|
|
1307
1312
|
Phase directory: {phase_dir}
|
|
1308
1313
|
Phase goal: {goal from ROADMAP.md}
|
|
1309
1314
|
Phase requirement IDs: {phase_req_ids}
|
|
1315
|
+
Verifier depth: {verifier_depth}
|
|
1310
1316
|
Check must_haves against actual codebase.
|
|
1311
1317
|
Cross-reference requirement IDs from PLAN frontmatter against REQUIREMENTS.md — every ID MUST be accounted for.
|
|
1312
1318
|
Create VERIFICATION.md.
|
|
@@ -1336,6 +1342,7 @@ VERIFICATION=$(pp_run query verification.status "$PHASE_DIR" 2>/dev/null)
|
|
|
1336
1342
|
STATUS=$(printf '%s' "$VERIFICATION" | jq -r '.status' 2>/dev/null || echo "")
|
|
1337
1343
|
NEXT_ACTION=$(printf '%s' "$VERIFICATION" | jq -r '.next_action' 2>/dev/null || echo "")
|
|
1338
1344
|
NEXT_COMMAND=$(printf '%s' "$VERIFICATION" | jq -r '.next_command' 2>/dev/null || echo "")
|
|
1345
|
+
pp_run timeline end verifier "${PHASE_NUMBER}" "${STATUS:-failed}" || true
|
|
1339
1346
|
```
|
|
1340
1347
|
|
|
1341
1348
|
Route on `$STATUS`: if `passed`, proceed to update_roadmap. Otherwise keep the phase pending — present `$NEXT_ACTION` to the user and, when `$NEXT_COMMAND` is non-empty, show it as the next command to run. The query covers all cases including missing files (`missing`) and unexpected values (`unknown`), so no per-status arm needs to be listed here.
|
|
@@ -1466,7 +1473,8 @@ These items are tracked and will appear in `/pp:progress` and `/pp:audit-uat`.
|
|
|
1466
1473
|
|
|
1467
1474
|
```bash
|
|
1468
1475
|
[ -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
|
|
1476
|
+
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 {phase_dir}/*-TIMELINE.jsonl
|
|
1477
|
+
pp_run timeline summary "${PHASE_NUMBER}" --banner || true
|
|
1470
1478
|
```
|
|
1471
1479
|
</step>
|
|
1472
1480
|
|
|
@@ -1567,6 +1575,7 @@ After verification passes and roadmap is updated, return completion status to pa
|
|
|
1567
1575
|
Phase: ${PHASE_NUMBER} - ${PHASE_NAME}
|
|
1568
1576
|
Plans: ${completed_count}/${total_count}
|
|
1569
1577
|
Verification: {Passed | Gaps Found}
|
|
1578
|
+
{timeline banner, verbatim}
|
|
1570
1579
|
|
|
1571
1580
|
[Include aggregate_results output]
|
|
1572
1581
|
```
|
|
@@ -1613,6 +1622,7 @@ If CONTEXT.md does **not** exist for the next phase, present:
|
|
|
1613
1622
|
|
|
1614
1623
|
```
|
|
1615
1624
|
## ✓ Phase {X}: {Name} Complete
|
|
1625
|
+
{timeline banner, verbatim}
|
|
1616
1626
|
|
|
1617
1627
|
/pp:progress ${GSD_WS} — see updated roadmap
|
|
1618
1628
|
/pp:discuss-phase {next} ${GSD_WS} — start here: discuss next phase before planning ← recommended
|
|
@@ -1624,6 +1634,7 @@ If CONTEXT.md **exists** for the next phase, present:
|
|
|
1624
1634
|
|
|
1625
1635
|
```
|
|
1626
1636
|
## ✓ Phase {X}: {Name} Complete
|
|
1637
|
+
{timeline banner, verbatim}
|
|
1627
1638
|
|
|
1628
1639
|
/pp:progress ${GSD_WS} — see updated roadmap
|
|
1629
1640
|
/pp:plan-phase {next} ${GSD_WS} — start here: plan next phase (CONTEXT.md already present) ← recommended
|
|
@@ -67,7 +67,7 @@ if [ "$(pp_run query platform-bindings --pick present 2>/dev/null)" = "true" ];
|
|
|
67
67
|
# multi-line values, embedded quotes, backslashes, and $(...) sequences are encoded
|
|
68
68
|
# correctly (CR-02: an unquoted heredoc would produce invalid JSON for any multi-line
|
|
69
69
|
# field, breaking cmdGenerateClientContext with "Failed to parse JSON input").
|
|
70
|
-
TMP_CTX=$(mktemp /tmp/pp-client-ctx-XXXXXX
|
|
70
|
+
TMP_CTX=$(mktemp /tmp/pp-client-ctx-XXXXXX)
|
|
71
71
|
CLIENT_NAME="$CLIENT_NAME" \
|
|
72
72
|
CLIENT_SLUG="$CLIENT_SLUG" \
|
|
73
73
|
CODING_STANDARDS="$CODING_STANDARDS" \
|
|
@@ -35,6 +35,7 @@ Display:
|
|
|
35
35
|
Spawn the planner in **outline-only** mode — it must write only the outline manifest, not any
|
|
36
36
|
PLAN.md files:
|
|
37
37
|
|
|
38
|
+
`pp_run timeline start planner "$PHASE" || true`
|
|
38
39
|
```javascript
|
|
39
40
|
Agent(
|
|
40
41
|
prompt="{same planning_context as step 8, plus:}
|
|
@@ -56,6 +57,7 @@ Agent(
|
|
|
56
57
|
> **ORCHESTRATOR RULE — ALL RUNTIMES**: After calling Agent() above, stop working on this task immediately. Do not read more files, edit code, or run tests related to this task while the subagent is active. Wait for the subagent to return its result. This prevents duplicate work, conflicting edits, and wasted context. Only resume when the subagent result is available.
|
|
57
58
|
|
|
58
59
|
Handle return:
|
|
60
|
+
`pp_run timeline end planner "$PHASE" {outcome} || true`, `complete` on `## OUTLINE COMPLETE`, otherwise `failed`.
|
|
59
61
|
- **`## OUTLINE COMPLETE`:** Read `PLAN-OUTLINE.md`, extract plan list. Continue to 8.5.2.
|
|
60
62
|
- **Any other return or empty:** Display error. Offer: 1) Retry outline, 2) Stop. (`--unattended`: U-P15 — retry once, then Stop.)
|
|
61
63
|
|
|
@@ -80,6 +82,7 @@ For each plan entry extracted from `PLAN-OUTLINE.md`:
|
|
|
80
82
|
```
|
|
81
83
|
|
|
82
84
|
3. Spawn the planner in **single-plan** mode — it must write exactly one PLAN.md file:
|
|
85
|
+
`pp_run timeline start planner "$PHASE" || true`
|
|
83
86
|
```javascript
|
|
84
87
|
Agent(
|
|
85
88
|
prompt="{same planning_context as step 8, plus:}
|
|
@@ -99,7 +102,7 @@ For each plan entry extracted from `PLAN-OUTLINE.md`:
|
|
|
99
102
|
|
|
100
103
|
> **ORCHESTRATOR RULE — ALL RUNTIMES**: After calling Agent() above, stop working on this task immediately. Do not read more files, edit code, or run tests related to this task while the subagent is active. Wait for the subagent to return its result. This prevents duplicate work, conflicting edits, and wasted context. Only resume when the subagent result is available.
|
|
101
104
|
|
|
102
|
-
4. **Verify disk:** Check `${PHASE_DIR}/{plan_id}-PLAN.md` exists. If missing: offer 1) Retry, 2) Stop.
|
|
105
|
+
4. **Verify disk:** Check `${PHASE_DIR}/{plan_id}-PLAN.md` exists. Run `pp_run timeline end planner "$PHASE" {outcome} || true` with `complete` when it exists, otherwise `failed`. If missing: offer 1) Retry, 2) Stop.
|
|
103
106
|
|
|
104
107
|
5. **Commit per-plan:**
|
|
105
108
|
```bash
|
|
@@ -107,5 +110,6 @@ _PP_SHIM_NAME="pp-tools.cjs"; _pp_root() { ( for _v in $(env | sed -n 's/^\(GIT_
|
|
|
107
110
|
pp_run query commit "docs(planning): plan ${plan_id} (chunked)" --phase "${PADDED_PHASE}" --files "${PHASE_DIR}/${plan_id}-PLAN.md"
|
|
108
111
|
```
|
|
109
112
|
|
|
110
|
-
After all N plans are written and committed, treat this as `## PLANNING COMPLETE` and continue
|
|
111
|
-
|
|
113
|
+
After all N plans are written and committed, treat this as `## PLANNING COMPLETE` and continue to
|
|
114
|
+
step 9's return handling, skipping step 9's planner `end` line — every chunked planner run was
|
|
115
|
+
already closed in 8.5.1 (outline) and 8.5.2 step 4 (per plan), so a third `end` has nothing to close.
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# Plan-phase step — PRD express path
|
|
2
|
+
|
|
3
|
+
> Read and executed from `workflows/plan-phase.md` §3.5 when `--prd` is given. Writes CONTEXT.md from the PRD, so step 4 is skipped; planning continues at step 4.6.
|
|
4
|
+
|
|
5
|
+
**If `--prd <filepath>` provided:**
|
|
6
|
+
|
|
7
|
+
1. Read the PRD file:
|
|
8
|
+
```bash
|
|
9
|
+
PRD_CONTENT=$(cat "$PRD_FILE" 2>/dev/null)
|
|
10
|
+
if [ -z "$PRD_CONTENT" ]; then
|
|
11
|
+
echo "Error: PRD file not found: $PRD_FILE"
|
|
12
|
+
exit 1
|
|
13
|
+
fi
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
2. Display banner:
|
|
17
|
+
```
|
|
18
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
19
|
+
pp-core ► PRD EXPRESS PATH
|
|
20
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
21
|
+
|
|
22
|
+
Using PRD: {PRD_FILE}
|
|
23
|
+
Generating CONTEXT.md from requirements...
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
3. Parse the PRD content and generate CONTEXT.md. The orchestrator should:
|
|
27
|
+
- Extract all requirements, user stories, acceptance criteria, and constraints from the PRD
|
|
28
|
+
- Map each to a locked decision (everything in the PRD is treated as a locked decision)
|
|
29
|
+
- Identify any areas the PRD doesn't cover and mark as "Claude's Discretion"
|
|
30
|
+
- **Extract canonical refs** from ROADMAP.md for this phase, plus any specs/ADRs referenced in the PRD — expand to full file paths (MANDATORY)
|
|
31
|
+
- Create CONTEXT.md in the phase directory
|
|
32
|
+
|
|
33
|
+
4. Write CONTEXT.md:
|
|
34
|
+
```markdown
|
|
35
|
+
# Phase [X]: [Name] - Context
|
|
36
|
+
|
|
37
|
+
**Gathered:** [date]
|
|
38
|
+
**Status:** Ready for planning
|
|
39
|
+
**Source:** PRD Express Path ({PRD_FILE})
|
|
40
|
+
|
|
41
|
+
<domain>
|
|
42
|
+
## Phase Boundary
|
|
43
|
+
|
|
44
|
+
[Extracted from PRD — what this phase delivers]
|
|
45
|
+
|
|
46
|
+
</domain>
|
|
47
|
+
|
|
48
|
+
<decisions>
|
|
49
|
+
## Implementation Decisions
|
|
50
|
+
|
|
51
|
+
{For each requirement/story/criterion in the PRD:}
|
|
52
|
+
### [Category derived from content]
|
|
53
|
+
- [Requirement as locked decision]
|
|
54
|
+
|
|
55
|
+
### Claude's Discretion
|
|
56
|
+
[Areas not covered by PRD — implementation details, technical choices]
|
|
57
|
+
|
|
58
|
+
</decisions>
|
|
59
|
+
|
|
60
|
+
<canonical_refs>
|
|
61
|
+
## Canonical References
|
|
62
|
+
|
|
63
|
+
**Downstream agents MUST read these before planning or implementing.**
|
|
64
|
+
|
|
65
|
+
[MANDATORY. Extract from ROADMAP.md and any docs referenced in the PRD.
|
|
66
|
+
Use full relative paths. Group by topic area.]
|
|
67
|
+
|
|
68
|
+
### [Topic area]
|
|
69
|
+
- `path/to/spec-or-adr.md` — [What it decides/defines]
|
|
70
|
+
|
|
71
|
+
[If no external specs: "No external specs — requirements fully captured in decisions above"]
|
|
72
|
+
|
|
73
|
+
</canonical_refs>
|
|
74
|
+
|
|
75
|
+
<specifics>
|
|
76
|
+
## Specific Ideas
|
|
77
|
+
|
|
78
|
+
[Any specific references, examples, or concrete requirements from PRD]
|
|
79
|
+
|
|
80
|
+
</specifics>
|
|
81
|
+
|
|
82
|
+
<deferred>
|
|
83
|
+
## Deferred Ideas
|
|
84
|
+
|
|
85
|
+
[Items in PRD explicitly marked as future/v2/out-of-scope]
|
|
86
|
+
[If none: "None — PRD covers phase scope"]
|
|
87
|
+
|
|
88
|
+
</deferred>
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
*Phase: XX-name*
|
|
93
|
+
*Context gathered: [date] via PRD Express Path*
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
5. Commit:
|
|
97
|
+
```bash
|
|
98
|
+
_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
|
|
99
|
+
pp_run query commit "docs(planning): generate context from PRD" --phase "${padded_phase}" --files "${phase_dir}/${padded_phase}-CONTEXT.md"
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
6. Set `context_content` to the generated CONTEXT.md content and continue to step 4.6 (Classify Ceremony).
|
|
103
|
+
|
|
104
|
+
**Effect:** This completely bypasses step 4 (Load CONTEXT.md) since we just created it. The rest of the workflow (research, planning, verification) proceeds normally with the PRD-derived context.
|