@pareto4/pp-core 1.19.0 → 1.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/agents/pp-nyquist-auditor.md +19 -14
  3. package/agents/pp-phase-researcher.md +10 -0
  4. package/agents/pp-plan-checker.md +59 -36
  5. package/agents/pp-planner.md +49 -53
  6. package/agents/pp-vault-reviewer.md +2 -0
  7. package/agents/pp-verifier.md +15 -60
  8. package/commands/pp-autonomous.md +2 -1
  9. package/commands/pp-discovery.md +3 -2
  10. package/commands/pp-plan-phase.md +2 -1
  11. package/commands/pp-plan-review-convergence.md +2 -1
  12. package/gemini-extension.json +1 -1
  13. package/package.json +6 -3
  14. package/pareto-skills/_shared/pp-claude-md-protocol.md +1 -1
  15. package/pareto-skills/pp-project-setup/SKILL.md +18 -343
  16. package/pp-core/bin/lib/capability-activation.cjs +77 -0
  17. package/pp-core/bin/lib/capability-registry.cjs +15 -15
  18. package/pp-core/bin/lib/capability-state.cjs +8 -18
  19. package/pp-core/bin/lib/ceremony.cjs +1342 -0
  20. package/pp-core/bin/lib/check-command-router.cjs +62 -1
  21. package/pp-core/bin/lib/commands.cjs +29 -3
  22. package/pp-core/bin/lib/config.cjs +5 -0
  23. package/pp-core/bin/lib/discovery-access.cjs +276 -0
  24. package/pp-core/bin/lib/discovery-charter.cjs +664 -0
  25. package/pp-core/bin/lib/discovery-deviations.cjs +264 -0
  26. package/pp-core/bin/lib/discovery-entities.cjs +323 -0
  27. package/pp-core/bin/lib/discovery-for-phase.cjs +628 -0
  28. package/pp-core/bin/lib/discovery-integrations.cjs +286 -0
  29. package/pp-core/bin/lib/discovery-migration.cjs +246 -0
  30. package/pp-core/bin/lib/discovery-phases.cjs +233 -0
  31. package/pp-core/bin/lib/discovery-processes.cjs +355 -0
  32. package/pp-core/bin/lib/discovery-research-track.cjs +5 -4
  33. package/pp-core/bin/lib/discovery-rollup.cjs +8 -7
  34. package/pp-core/bin/lib/discovery-rules.cjs +216 -0
  35. package/pp-core/bin/lib/discovery-screens.cjs +1 -1
  36. package/pp-core/bin/lib/discovery-session-check.cjs +264 -0
  37. package/pp-core/bin/lib/discovery-stories.cjs +273 -0
  38. package/pp-core/bin/lib/discovery-sweep.cjs +1 -1
  39. package/pp-core/bin/lib/discovery-table.cjs +55 -0
  40. package/pp-core/bin/lib/init.cjs +50 -1
  41. package/pp-core/bin/lib/io.cjs +24 -0
  42. package/pp-core/bin/lib/loop-resolver.cjs +26 -12
  43. package/pp-core/bin/lib/phase.cjs +39 -3
  44. package/pp-core/bin/lib/plan-sizing.cjs +346 -0
  45. package/pp-core/bin/lib/test-substance.cjs +3190 -0
  46. package/pp-core/bin/lib/timeline.cjs +605 -0
  47. package/pp-core/bin/lib/vault-standards-review.cjs +50 -2
  48. package/pp-core/bin/pp-tools.cjs +214 -5
  49. package/pp-core/bin/shared/ceremony-gates.json +17 -0
  50. package/pp-core/bin/shared/config-schema.manifest.json +1 -0
  51. package/pp-core/references/ceremony.md +81 -0
  52. package/pp-core/references/discovery-access.md +112 -0
  53. package/pp-core/references/discovery-build-consumption.md +256 -0
  54. package/pp-core/references/discovery-charter.md +127 -0
  55. package/pp-core/references/discovery-data-model.md +145 -0
  56. package/pp-core/references/discovery-id-conventions.md +50 -14
  57. package/pp-core/references/discovery-integrations.md +151 -0
  58. package/pp-core/references/discovery-processes.md +190 -0
  59. package/pp-core/references/discovery-rebaseline.md +2 -2
  60. package/pp-core/references/discovery-research-track.md +5 -6
  61. package/pp-core/references/discovery-session-output.md +70 -0
  62. package/pp-core/references/discovery-standards.md +107 -0
  63. package/pp-core/references/discovery-traceability.md +2 -2
  64. package/pp-core/references/few-shot-examples/plan-checker.md +8 -8
  65. package/pp-core/references/phase-timeline.md +107 -0
  66. package/pp-core/references/planner-antipatterns.md +32 -0
  67. package/pp-core/references/planner-discovery-extract.md +35 -0
  68. package/pp-core/references/planner-guidance.md +17 -14
  69. package/pp-core/references/planner-revision.md +1 -1
  70. package/pp-core/references/planning-config.md +3 -2
  71. package/pp-core/references/test-substance.md +324 -0
  72. package/pp-core/references/verifier-discovery-conformance.md +36 -0
  73. package/pp-core/references/verifier-stub-patterns.md +51 -0
  74. package/pp-core/templates/VALIDATION.md +1 -0
  75. package/pp-core/templates/phase-prompt.md +19 -7
  76. package/pp-core/templates/project-charter.md +161 -100
  77. package/pp-core/templates/project.md +3 -3
  78. package/pp-core/templates/requirements.md +18 -0
  79. package/pp-core/templates/roadmap.md +1 -1
  80. package/pp-core/templates/verification-report.md +17 -1
  81. package/pp-core/workflows/audit-milestone.md +4 -1
  82. package/pp-core/workflows/autonomous.md +11 -8
  83. package/pp-core/workflows/code-review.md +15 -6
  84. package/pp-core/workflows/discovery-sprint/charter.md +114 -0
  85. package/pp-core/workflows/discovery-sprint/prefill.md +1 -1
  86. package/pp-core/workflows/discovery-sprint/prototype.md +4 -4
  87. package/pp-core/workflows/discovery-sprint/session-13-gates.md +10 -0
  88. package/pp-core/workflows/discovery-sprint/sessions/01-kick-off.md +5 -2
  89. package/pp-core/workflows/discovery-sprint/sessions/02-as-is.md +27 -5
  90. package/pp-core/workflows/discovery-sprint/sessions/03-to-be.md +56 -31
  91. package/pp-core/workflows/discovery-sprint/sessions/04-ux-design.md +1 -1
  92. package/pp-core/workflows/discovery-sprint/sessions/05-architecture.md +42 -19
  93. package/pp-core/workflows/discovery-sprint/sessions/06-security.md +27 -12
  94. package/pp-core/workflows/discovery-sprint/sessions/07-identity.md +41 -23
  95. package/pp-core/workflows/discovery-sprint/sessions/08-integration.md +50 -23
  96. package/pp-core/workflows/discovery-sprint/sessions/09-qa.md +26 -11
  97. package/pp-core/workflows/discovery-sprint/sessions/10-infrastructure.md +28 -9
  98. package/pp-core/workflows/discovery-sprint/sessions/11-roadmap.md +21 -0
  99. package/pp-core/workflows/discovery-sprint/sessions/13-wrap-up.md +24 -9
  100. package/pp-core/workflows/discovery-sprint.md +12 -15
  101. package/pp-core/workflows/discovery-to-build/steps/architecture-deliverables.md +80 -29
  102. package/pp-core/workflows/discovery-to-build/steps/{screen-inventory-gate.md → handoff-gates.md} +111 -3
  103. package/pp-core/workflows/discovery-to-build/templates/discovery-references.md +12 -9
  104. package/pp-core/workflows/discovery-to-build/templates/pp-handoff.md +27 -26
  105. package/pp-core/workflows/discovery-to-build.md +70 -34
  106. package/pp-core/workflows/discuss-phase/discovery.md +83 -0
  107. package/pp-core/workflows/discuss-phase/templates/context.md +4 -0
  108. package/pp-core/workflows/discuss-phase.md +10 -7
  109. package/pp-core/workflows/execute-phase/steps/check-query-gate.md +7 -7
  110. package/pp-core/workflows/execute-phase/steps/codebase-drift-gate.md +3 -2
  111. package/pp-core/workflows/execute-phase.md +14 -3
  112. package/pp-core/workflows/new-project.md +3 -3
  113. package/pp-core/workflows/plan-phase/steps/chunked-planning.md +7 -3
  114. package/pp-core/workflows/plan-phase/steps/discovery-extract.md +41 -0
  115. package/pp-core/workflows/plan-phase/steps/prd-express.md +104 -0
  116. package/pp-core/workflows/plan-phase.md +62 -124
  117. package/pp-core/workflows/plan-review-convergence.md +6 -3
  118. package/pp-core/workflows/ship.md +2 -2
  119. package/pp-core/workflows/stats.md +19 -4
  120. package/pp-core/workflows/validate-phase.md +19 -4
  121. package/pp-core/workflows/vault-review.md +5 -0
  122. package/pp-core/workflows/verify-phase.md +1 -1
  123. package/pp-core/workflows/verify-work.md +1 -1
  124. package/scripts/gen-capability-registry.cjs +43 -45
  125. package/scripts/run-tests.cjs +54 -30
  126. package/pp-core/workflows/discovery-sprint/templates/context-template.md +0 -272
@@ -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.
@@ -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
@@ -501,9 +501,9 @@ Initialize with any decisions made during questioning:
501
501
  ```markdown
502
502
  ## Key Decisions
503
503
 
504
- | Decision | Rationale | Outcome |
505
- |----------|-----------|---------|
506
- | [Choice from questioning] | [Why] | — Pending |
504
+ | ID | Decision | Rationale | Outcome |
505
+ |----|----------|-----------|---------|
506
+ | — | [Choice from questioning] | [Why] | — Pending |
507
507
  ```
508
508
 
509
509
  **Last updated footer:**
@@ -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
- to step 9.
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,41 @@
1
+ # Plan-phase step — Discovery extract (R1)
2
+
3
+ > Read and executed from `workflows/plan-phase.md` §7 after the context paths are extracted and
4
+ > before the researcher (§5.1) and planner (§8) prompts are built. Inert on a project without
5
+ > `.planning/discovery/`. Contract: `references/discovery-build-consumption.md`.
6
+
7
+ Render the phase's discovery rows fresh — the registers may have been amended since
8
+ `/pp-discuss-phase` wrote CONTEXT.md — into one file the researcher and the planner read:
9
+
10
+ ```bash
11
+ _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
12
+ DISCOVERY_EXTRACT_PATH=""
13
+ _DX_JSON=$(pp_run query discovery.for-phase "${PHASE_NUMBER}" 2>/dev/null || true)
14
+ if [[ "$_DX_JSON" == @file:* ]]; then _DX_JSON=$(cat "${_DX_JSON#@file:}"); fi
15
+ _DX_PRESENT=$(printf '%s' "$_DX_JSON" | node -e "let s='';process.stdin.on('data',d=>s+=d).on('end',()=>{try{const o=JSON.parse(s);console.log(o.present===true&&o.ok===true?'true':'false')}catch{console.log('false')}})")
16
+ if [ "$_DX_PRESENT" = true ]; then
17
+ DISCOVERY_EXTRACT_PATH="${PHASE_DIR}/${PADDED_PHASE}-DISCOVERY-EXTRACT.md"
18
+ pp_run query discovery.for-phase "${PHASE_NUMBER}" --markdown > "${DISCOVERY_EXTRACT_PATH}"
19
+ echo "DISCOVERY_EXTRACT_PATH=${DISCOVERY_EXTRACT_PATH}"
20
+ else
21
+ rm -f "${PHASE_DIR}/${PADDED_PHASE}-DISCOVERY-EXTRACT.md"
22
+ fi
23
+ ```
24
+
25
+ A non-zero exit from the first command is a structural fault in a discovery artifact
26
+ (`discovery_for_phase_failed`): print the fault list and stop. Planning on a malformed register
27
+ copies the malformation into the build; the sprint's own check names the row to fix.
28
+
29
+ When `DISCOVERY_EXTRACT_PATH` is non-empty:
30
+
31
+ - add `- {DISCOVERY_EXTRACT_PATH} (Discovery extract — register rows citing this phase's
32
+ requirement IDs; required reading, never open a session-NN.md)` to the `<files_to_read>` of
33
+ the researcher prompt (§5.1) and the planner prompt (§8);
34
+ - the planner embeds the file's content verbatim — markers included — as the `<discovery_extract>`
35
+ block of every PLAN.md it writes, after `<context>` (and after `<vault_standards>` when present)
36
+ and before `<tasks>`;
37
+ - the file is a render and is never committed: it is regenerated on every planning run and
38
+ `*-DISCOVERY-EXTRACT.md` is not a phase artifact.
39
+
40
+ The name is deliberate: `{padded}-DISCOVERY.md` already belongs to the planner's library
41
+ discovery protocol and is a different thing.
@@ -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.