@pareto4/pp-core 1.8.1 → 1.9.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 (37) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/NOTICE +23 -0
  3. package/README.md +10 -1
  4. package/bin/install.js +34 -1
  5. package/gemini-extension.json +1 -1
  6. package/package.json +8 -3
  7. package/pareto-skills/pp-project-setup/SKILL.md +32 -440
  8. package/pp-core/bin/lib/capability-state.cjs +13 -7
  9. package/pp-core/bin/lib/config.cjs +7 -22
  10. package/pp-core/bin/lib/init.cjs +4 -4
  11. package/pp-core/bin/lib/installer-migration-report.cjs +1 -1
  12. package/pp-core/bin/lib/loop-resolver.cjs +6 -0
  13. package/pp-core/bin/lib/profile-output.cjs +4 -2
  14. package/pp-core/bin/lib/runtime-name-policy.cjs +0 -1
  15. package/pp-core/bin/lib/surface.cjs +2 -2
  16. package/pp-core/bin/shared/config-schema.manifest.json +4 -0
  17. package/pp-core/references/workstream-flag.md +13 -0
  18. package/pp-core/workflows/discovery-sprint.md +409 -16
  19. package/pp-core/workflows/discovery-to-build/steps/architecture-deliverables.md +250 -0
  20. package/pp-core/workflows/discovery-to-build.md +218 -48
  21. package/pp-core/workflows/discuss-phase/modes/chain.md +5 -0
  22. package/pp-core/workflows/discuss-phase.md +4 -0
  23. package/pp-core/workflows/execute-phase.md +4 -0
  24. package/pp-core/workflows/new-milestone.md +4 -0
  25. package/pp-core/workflows/plan-phase.md +4 -0
  26. package/pp-core/workflows/progress.md +4 -0
  27. package/pp-core/workflows/quick.md +4 -0
  28. package/pp-core/workflows/resume-project.md +4 -0
  29. package/pp-core/workflows/ship.md +4 -0
  30. package/pp-core/workflows/transition.md +4 -0
  31. package/pp-core/workflows/validate-phase.md +4 -0
  32. package/scripts/changeset/lint.cjs +20 -5
  33. package/scripts/lint-docs-required.cjs +10 -3
  34. package/scripts/release-channel.cjs +58 -0
  35. package/scripts/release-tarball-smoke.cjs +4 -0
  36. package/scripts/verify-opengsd-sweep.cjs +12 -0
  37. package/scripts/verify-rename-guard.cjs +333 -0
@@ -27,7 +27,7 @@ Valid pp-core subagent types (use exact names — do not fall back to 'general-p
27
27
  **Text mode (`workflow.text_mode: true` in config or `--text` flag):** Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS` OR `text_mode` from init JSON is `true`. When TEXT_MODE is active, replace every `AskUserQuestion` call in this workflow with a plain-text numbered list and ask the user to type their choice number. This is required for non-Claude runtimes (OpenAI Codex, Gemini CLI, etc.) where `AskUserQuestion` is not available.
28
28
 
29
29
  **Prerequisites:**
30
- - A Pareto project with a `Discovery/` folder (created by `pareto-project-setup`)
30
+ - A Pareto project with Discovery Sprint sessions in `.planning/discovery/` (created via `/pp-discovery`)
31
31
  - Discovery Sprint sessions (ideally 13/13 completed)
32
32
  - pp-core installed and resolvable via the standard `pp_run` shim
33
33
  </context>
@@ -46,19 +46,80 @@ Resolve the `pp_run` helper before anything else. Every `pp_run` call below uses
46
46
  **Step 1: Validate environment**
47
47
 
48
48
  ```bash
49
- ls Discovery/_progress.md 2>/dev/null && echo "DISCOVERY_OK" || echo "DISCOVERY_MISSING"
49
+ ls .planning/discovery/_progress.md 2>/dev/null && echo "DISCOVERY_OK" || echo "DISCOVERY_MISSING"
50
50
  ls .planning/PROJECT.md 2>/dev/null && echo "PPCORE_EXISTS" || echo "PPCORE_FRESH"
51
51
  ```
52
52
 
53
- **If DISCOVERY_MISSING:** Error and stop.
53
+ **If DISCOVERY_MISSING:** Before erroring, check for a legacy root-level Discovery tree
54
+ (D-02) — an older `pareto-project-setup` scaffold that pre-dates the canonical
55
+ `.planning/discovery/` path family. <!-- legacy-read-target -->
56
+
57
+ ```bash
58
+ ls Discovery/_progress.md 2>/dev/null && echo "LEGACY_FOUND" || echo "LEGACY_ABSENT" # legacy detection read target <!-- legacy-read-target -->
59
+ ```
60
+
61
+ **If LEGACY_ABSENT:** Error and stop.
54
62
  ```
55
63
  Error: No Discovery Sprint found in this project.
56
64
 
57
- Expected: Discovery/_progress.md
58
- Run /pareto-project-setup to create a new project with the Discovery framework,
59
- then complete the Discovery Sprint sessions before transitioning to build.
65
+ Expected: .planning/discovery/_progress.md
66
+ Run /pp-discovery 1 to start a Discovery Sprint, then complete the sessions
67
+ before transitioning to build.
68
+ ```
69
+
70
+ **If LEGACY_FOUND:** A legacy pre-canonical tree exists with real client answers — this is
71
+ business data, not disposable scaffolding. <!-- legacy-read-target --> Offer a one-time
72
+ guided conversion into the canonical `.planning/discovery/` path family; no silent ignore,
73
+ no hard error (D-02):
74
+
75
+ ```
76
+ AskUserQuestion([
77
+ {
78
+ header: "Legacy Discovery Tree Found",
79
+ question: "Found a legacy pre-canonical Discovery tree (from an older pareto-project-setup scaffold) but no .planning/discovery/ tree. Convert it to the canonical .planning/discovery/ format now? This copies your 13 session files plus the progress and context files into .planning/discovery/ — the original legacy folder is left untouched.",
80
+ multiSelect: false,
81
+ options: [
82
+ { label: "Convert now (Recommended)", description: "Copy the legacy tree's content into .planning/discovery/session-NN.md and proceed" },
83
+ { label: "Cancel", description: "Stop here — I'll migrate manually or run /pp-discovery instead" }
84
+ ]
85
+ }
86
+ ])
87
+ ```
88
+
89
+ **If "Cancel":** Exit with guidance:
90
+ ```
91
+ No changes made. To migrate manually, copy each legacy session file's content into
92
+ .planning/discovery/session-NN.md (see the Discovery Traceability mapping in this
93
+ workflow's Step 3b for the exact legacy-filename-to-session-NN pairs), then re-run
94
+ /pp-discovery-to-build.
95
+ ```
96
+
97
+ **If "Convert now":** Perform the guided migration. For each of the 13 legacy session
98
+ files (the exact legacy filenames are the primary-source column of the Discovery
99
+ Traceability table in Step 3b), read the legacy file's frontmatter and content, then
100
+ write `.planning/discovery/session-NN.md`: <!-- legacy-read-target -->
101
+
102
+ - Preserve `status`, `completed_date`, and `completeness_score` frontmatter fields where
103
+ present in the legacy file; normalize any missing fields to the current session
104
+ template's defaults (do not blind-copy — read what exists, fill gaps honestly).
105
+ - Copy the legacy progress and context files to `.planning/discovery/_context.md` and
106
+ `.planning/discovery/_progress.md` respectively <!-- legacy-read-target -->, adding a
107
+ `Parked` column to the progress table (default 0) if the legacy schema predates it.
108
+
109
+ **Path safety (T-04-03, reused verbatim):** Reject any source or destination path that is
110
+ absolute or contains `..`. Every migration write target MUST resolve under
111
+ `.planning/discovery/` — never write outside it, and never delete or modify the original
112
+ legacy tree. <!-- legacy-read-target -->
113
+
114
+ ```bash
115
+ ls .planning/discovery/_progress.md 2>/dev/null && echo "DISCOVERY_OK" || echo "MIGRATION_FAILED"
60
116
  ```
61
117
 
118
+ **If MIGRATION_FAILED:** Report the failure and stop — do not proceed with a partial
119
+ migration.
120
+
121
+ **If DISCOVERY_OK:** Proceed to Step 2 with the newly migrated canonical tree.
122
+
62
123
  **If PPCORE_EXISTS:** Error and stop.
63
124
  ```
64
125
  Error: pp-core is already initialized (.planning/PROJECT.md exists).
@@ -71,7 +132,7 @@ Or use /pp-progress to continue where you left off.
71
132
 
72
133
  **Step 2: Validate Discovery completion**
73
134
 
74
- Read `Discovery/_progress.md` and parse the Session Progress table. Count sessions by
135
+ Read `.planning/discovery/_progress.md` and parse the Session Progress table. Count sessions by
75
136
  status: **Completed**, **In Progress**, **Not Started**.
76
137
 
77
138
  **If `--skip-validation` is present:** Skip to Step 3 with a note.
@@ -102,6 +163,39 @@ When all sessions are complete, run /pp-discovery-to-build again.
102
163
 
103
164
  **If "Proceed anyway":** Continue to Step 3, noting which sessions are incomplete.
104
165
 
166
+ **Surface unresolved parked questions (D-12):** Scan `.planning/discovery/_progress.md`'s
167
+ Parked column and every session file's `PARKED — needs business/senior input` markers to
168
+ build the full list of unresolved parked questions across all sessions. This list carries
169
+ forward into Step 3b's `## Open Items & Risks` synthesis section regardless of the outcome
170
+ below.
171
+
172
+ **If the parked list is non-empty:** Surface it and gate proceeding behind an explicit
173
+ confirmation — never a hard block:
174
+
175
+ ```
176
+ AskUserQuestion([
177
+ {
178
+ header: "Parked Questions Open",
179
+ question: "{parked_count} question(s) were parked during Discovery Sprint sessions as needing business/senior input:\n\n{list of parked questions, one per line, with session + topic}\n\nThese will be carried into the handoff synthesis as known gaps under Open Items & Risks — completeness scores already reflect them as not-covered. Proceed with them open?",
180
+ multiSelect: false,
181
+ options: [
182
+ { label: "Proceed with gaps noted (Recommended)", description: "Continue — parked items are tracked as known gaps, not blockers" },
183
+ { label: "Pause and resolve first", description: "Go back to Discovery to resolve the business/senior-input questions before continuing" }
184
+ ]
185
+ }
186
+ ])
187
+ ```
188
+
189
+ **If "Pause and resolve first":** Exit with guidance:
190
+ ```
191
+ Parked questions need business/senior input before proceeding. Resolve them in the
192
+ relevant Discovery session (see /pp-discovery), then re-run /pp-discovery-to-build.
193
+ ```
194
+
195
+ **If "Proceed with gaps noted":** Continue to Step 3, carrying the parked list forward.
196
+
197
+ **If the parked list is empty:** Skip this confirmation silently and continue to Step 3.
198
+
105
199
  ---
106
200
 
107
201
  **Step 3: Read and synthesize Discovery outputs**
@@ -113,9 +207,9 @@ them into a single document optimized for the pp-core new-project generators.
113
207
 
114
208
  Read these files (skip any that don't exist):
115
209
 
116
- 1. `Discovery/_context.md` — accumulated cross-session context (primary source)
117
- 2. `Discovery/_progress.md` — session completion status
118
- 3. All 13 session files in `Discovery/` — for detail not captured in `_context.md`
210
+ 1. `.planning/discovery/_context.md` — accumulated cross-session context (primary source)
211
+ 2. `.planning/discovery/_progress.md` — session completion status
212
+ 3. All 13 session files in `.planning/discovery/session-NN.md` — for detail not captured in `_context.md`
119
213
  4. The Project Definition document (glob for `*-Project-Definition.md` in root)
120
214
  5. `prototype/README.md` — if a prototype exists, note its state
121
215
 
@@ -125,7 +219,7 @@ authored content that replaces placeholder text.
125
219
 
126
220
  ### 3b. Synthesize into the handoff document
127
221
 
128
- Write `Discovery/_pp-handoff.md` with the structure below. The new-project generators
222
+ Write `.planning/discovery/_pp-handoff.md` with the structure below. The new-project generators
129
223
  use it to produce PROJECT.md, REQUIREMENTS.md, and ROADMAP.md, so the structure must
130
224
  map cleanly onto what those generators expect.
131
225
 
@@ -133,7 +227,7 @@ map cleanly onto what those generators expect.
133
227
  # Discovery Sprint Synthesis — pp-core Handoff
134
228
 
135
229
  > Auto-generated from {completed_count}/13 completed Discovery Sprint sessions.
136
- > Source: Discovery/_context.md + individual session files
230
+ > Source: .planning/discovery/_context.md + individual session files
137
231
  > Generated: {date}
138
232
 
139
233
  ---
@@ -266,6 +360,14 @@ application — what it does, who it's for, why it matters}
266
360
 
267
361
  ## Open Items & Risks
268
362
 
363
+ ### Parked Questions (Unresolved)
364
+ {From the D-12 scan of every session's PARKED — needs business/senior input markers:
365
+ list each parked question verbatim, honestly, as a known gap — never silently dropped}
366
+
367
+ | Question | Session | Owner |
368
+ |----------|---------|-------|
369
+ | {parked question, verbatim} | {session} | business/senior |
370
+
269
371
  ### Open Action Items
270
372
  | Action | From Session | Status |
271
373
  |--------|-------------|--------|
@@ -285,19 +387,19 @@ application — what it does, who it's for, why it matters}
285
387
 
286
388
  | Topic | Primary Source | Secondary Sources |
287
389
  |-------|---------------|-------------------|
288
- | Business context & vision | `Discovery/01-discovery-sprint-kickoff.md` | `Discovery/_context.md` §1 |
289
- | Current state & pain points | `Discovery/02-business-process-mapping-as-is.md` | `Discovery/_context.md` §2 |
290
- | Requirements & user stories | `Discovery/03-business-requirements-to-be.md` | `Discovery/_context.md` §3 |
291
- | UX design principles | `Discovery/04-ux-design-principles.md` | `Discovery/_context.md` §4 |
292
- | Architecture & tech stack | `Discovery/05-application-integration-architecture.md` | `Discovery/_context.md` §5 |
293
- | Security & compliance | `Discovery/06-security-compliance-setup.md` | `Discovery/_context.md` §6 |
294
- | Roles & identity | `Discovery/07-user-identity-management.md` | `Discovery/_context.md` §7 |
295
- | Integrations | `Discovery/08-integration-interface-design.md` | `Discovery/_context.md` §8 |
296
- | QA & testing | `Discovery/09-quality-assurance-testing.md` | `Discovery/_context.md` §9 |
297
- | Infrastructure & deployment | `Discovery/10-infrastructure-deployment-readiness.md` | `Discovery/_context.md` §10 |
298
- | Roadmap & release plan | `Discovery/11-project-roadmap-release-planning.md` | `Discovery/_context.md` §11 |
299
- | Team & delivery model | `Discovery/12-team-delivery-model.md` | `Discovery/_context.md` §12 |
300
- | Wrap-up & go/no-go | `Discovery/13-discovery-sprint-wrapup.md` | `Discovery/_context.md` §13 |
390
+ | Business context & vision | `.planning/discovery/session-01.md` | `.planning/discovery/_context.md` §1 |
391
+ | Current state & pain points | `.planning/discovery/session-02.md` | `.planning/discovery/_context.md` §2 |
392
+ | Requirements & user stories | `.planning/discovery/session-03.md` | `.planning/discovery/_context.md` §3 |
393
+ | UX design principles | `.planning/discovery/session-04.md` | `.planning/discovery/_context.md` §4 |
394
+ | Architecture & tech stack | `.planning/discovery/session-05.md` | `.planning/discovery/_context.md` §5 |
395
+ | Security & compliance | `.planning/discovery/session-06.md` | `.planning/discovery/_context.md` §6 |
396
+ | Roles & identity | `.planning/discovery/session-07.md` | `.planning/discovery/_context.md` §7 |
397
+ | Integrations | `.planning/discovery/session-08.md` | `.planning/discovery/_context.md` §8 |
398
+ | QA & testing | `.planning/discovery/session-09.md` | `.planning/discovery/_context.md` §9 |
399
+ | Infrastructure & deployment | `.planning/discovery/session-10.md` | `.planning/discovery/_context.md` §10 |
400
+ | Roadmap & release plan | `.planning/discovery/session-11.md` | `.planning/discovery/_context.md` §11 |
401
+ | Team & delivery model | `.planning/discovery/session-12.md` | `.planning/discovery/_context.md` §12 |
402
+ | Wrap-up & go/no-go | `.planning/discovery/session-13.md` | `.planning/discovery/_context.md` §13 |
301
403
  ```
302
404
 
303
405
  **Synthesis rules:**
@@ -307,6 +409,8 @@ application — what it does, who it's for, why it matters}
307
409
  - Preserve role names (Session 7) and technology choices (Session 5) exactly
308
410
  - If the Project Definition document has content not in `_context.md`, merge it in
309
411
  - Keep it factual — no interpretation or recommendations, just structured outputs
412
+ - List every unresolved parked question from Step 2's D-12 scan verbatim in the Parked
413
+ Questions (Unresolved) table — never inflate completeness by omitting them
310
414
 
311
415
  ---
312
416
 
@@ -316,11 +420,11 @@ application — what it does, who it's for, why it matters}
316
420
  AskUserQuestion([
317
421
  {
318
422
  header: "Handoff Ready",
319
- question: "I've synthesized your Discovery Sprint into Discovery/_pp-handoff.md.\n\nSummary:\n- {epic_count} EPICs, {story_count} user stories\n- {fr_count} functional / {nfr_count} non-functional requirements\n- Tech stack: {stack_summary}\n- {role_count} user roles, {integration_count} integrations, {phase_count} phases\n- {incomplete_sessions} incomplete sessions (if any)\n\nReview the file and confirm to proceed with pp-core initialization.",
423
+ question: "I've synthesized your Discovery Sprint into .planning/discovery/_pp-handoff.md.\n\nSummary:\n- {epic_count} EPICs, {story_count} user stories\n- {fr_count} functional / {nfr_count} non-functional requirements\n- Tech stack: {stack_summary}\n- {role_count} user roles, {integration_count} integrations, {phase_count} phases\n- {incomplete_sessions} incomplete sessions (if any)\n\nReview the file and confirm to proceed with pp-core initialization.",
320
424
  multiSelect: false,
321
425
  options: [
322
426
  { label: "Initialize pp-core", description: "Generate .planning/ from this handoff document (Recommended)" },
323
- { label: "Review first", description: "Check Discovery/_pp-handoff.md before proceeding" },
427
+ { label: "Review first", description: "Check .planning/discovery/_pp-handoff.md before proceeding" },
324
428
  { label: "Regenerate", description: "Something looks off — resynthesize from discovery" }
325
429
  ]
326
430
  }
@@ -399,11 +503,19 @@ pp_run commit "chore: add project config" --files .planning/config.json
399
503
 
400
504
  ### 5d. Generate PROJECT.md
401
505
 
402
- Read `Discovery/_pp-handoff.md` and synthesize `.planning/PROJECT.md` using the pp-core
506
+ Read `.planning/discovery/_pp-handoff.md` and synthesize `.planning/PROJECT.md` using the pp-core
403
507
  project template structure: use "What We're Building" as the description, include all
404
508
  Key Decisions, list requirements in Validated/Active/Out-of-Scope form, and reference
405
509
  Discovery artifacts (the section is added in Step 6a).
406
510
 
511
+ **Inline source refs (D-05):** Every Key Decision and every requirement summary carried
512
+ into PROJECT.md gets a compact trailing ref at its point of use — `(source: session-NN
513
+ §Section)`, e.g. `Auth uses magic links, not passwords (source: session-05 §Auth Strategy)`
514
+ — naming the canonical `.planning/discovery/session-NN.md` file and the section within it
515
+ the item was synthesized from. Then append one `## Discovery Traceability` table (same
516
+ shape as the table already in this workflow's Step 3b handoff synthesis) mapping each
517
+ PROJECT.md section to its canonical `.planning/discovery/session-NN.md` source(s).
518
+
407
519
  ```bash
408
520
  pp_run commit "docs: initialize project from Discovery Sprint" --files .planning/PROJECT.md
409
521
  ```
@@ -414,6 +526,15 @@ From the Functional Requirements section: map EPICs to requirement groups, user
414
526
  to individual requirements, include NFRs and Business Rules, preserve all original IDs
415
527
  (FR-xxx, NFR-xxx, US-xxx), and mark all requirements active.
416
528
 
529
+ **Inline source refs (D-05):** Every generated requirement line — FR/NFR/EPIC/US — carries
530
+ a trailing `(source: session-NN §Section)` ref at point of use, e.g. `FR-012: User can
531
+ export a report as CSV (source: session-03 §Order Intake)`, naming the canonical
532
+ `.planning/discovery/session-NN.md` file and section it was derived from. Then append one
533
+ `## Discovery Traceability` table (same shape as Step 3b's table) mapping each requirement
534
+ category (Authentication, EPIC group, NFRs, Business Rules, …) to its canonical
535
+ `.planning/discovery/session-NN.md` source(s) — the file-level map that complements the
536
+ per-item inline refs above.
537
+
417
538
  ```bash
418
539
  pp_run commit "docs: requirements from Discovery Sprint" --files .planning/REQUIREMENTS.md
419
540
  ```
@@ -424,17 +545,62 @@ From the Roadmap & Phasing section: map Discovery phases to pp-core phases, deri
424
545
  goals from EPIC scope, set dependencies from build-order preferences, and include the
425
546
  milestone name (Session 11, or default "v1.0 — MVP").
426
547
 
548
+ **Canonical refs producer (D-06):** For every generated phase entry, emit a
549
+ `**Canonical refs:** .planning/discovery/session-NN.md, ...` line listing every canonical
550
+ session file that fed that phase's requirements — placed immediately after the
551
+ `**Requirements**:` line and before `**Success Criteria**`, per `pp-core/templates/roadmap.md`'s
552
+ phase-entry field order:
553
+
554
+ ```markdown
555
+ ### Phase [N]: [Name]
556
+ **Goal**: [What this phase delivers]
557
+ **Depends on**: [...]
558
+ **Requirements**: [REQ-01, REQ-02]
559
+ **Canonical refs:** .planning/discovery/session-03.md, .planning/discovery/session-05.md
560
+ **Success Criteria** (what must be TRUE):
561
+ ```
562
+
563
+ Use the exact label string `Canonical refs:` — the existing `discuss-phase.md:313` consumer
564
+ already copies this line unchanged into `CONTEXT.md`'s canonical refs accumulator. Do not
565
+ modify `discuss-phase.md`, the researcher, or the planner — this workflow is the first
566
+ *producer* of a line those consumers already read.
567
+
427
568
  ```bash
428
569
  pp_run commit "docs: roadmap from Discovery Sprint" --files .planning/ROADMAP.md
429
570
  ```
430
571
 
431
572
  ### 5g. Initialize STATE.md
432
573
 
574
+ No `pp_run` CLI command initializes STATE.md — author `.planning/STATE.md` directly via
575
+ `Write`, following `pp-core/templates/state.md`'s schema (the same approach `new-project.md`'s
576
+ roadmapper agent uses). Populate it from what Step 5f already established:
577
+
578
+ - `status: planning`, `progress.total_phases`/`total_plans` from the generated ROADMAP.md,
579
+ `completed_phases`/`completed_plans` at 0
580
+ - **Project Reference:** core value from `.planning/PROJECT.md`, current focus = Phase 1
581
+ - **Current Position:** Phase 1 of N, "Ready to plan", today's date, 0% progress bar
582
+ - **Accumulated Context › Decisions:** none yet (fresh project)
583
+ - **Accumulated Context › Blockers/Concerns:** any unresolved parked questions carried
584
+ forward from Step 2's D-12 confirmation (see below), so they stay visible after handoff
585
+ - **Session Continuity:** last session = now, stopped at "Discovery handoff complete", no
586
+ resume file
587
+
433
588
  ```bash
434
- pp_run state-init 2>/dev/null
435
589
  pp_run commit "docs: initialize state" --files .planning/STATE.md
436
590
  ```
437
591
 
592
+ ### 5h. Generate architecture deliverables
593
+
594
+ `Read(workflows/discovery-to-build/steps/architecture-deliverables.md)` and execute it
595
+ end-to-end — it produces `docs/architecture/architecture.md` (arc42-lite) and one
596
+ `docs/architecture/adr/NNNN-title.md` per Session 5 ADR row from the already-synthesized
597
+ handoff content (D-13). The generation instructions live entirely in that sub-file
598
+ (lazily loaded, unmeasured by `tests/workflow-size-budget.test.cjs`) — do not inline them
599
+ here. The sub-file performs its own commit of these files as the final step of its
600
+ "Completing the step" section (its own `pp_run` resolver guard makes it safe to run
601
+ standalone too) — do NOT re-run a commit for `docs/architecture/` here; that would be
602
+ a duplicate of the sub-file's own commit.
603
+
438
604
  ---
439
605
 
440
606
  **Step 6: Wire Discovery references**
@@ -453,15 +619,15 @@ Discovery outputs are the source of truth for business decisions and requirement
453
619
 
454
620
  | Topic | File | Use When |
455
621
  |-------|------|----------|
456
- | All decisions (accumulated) | `Discovery/_context.md` | Understanding why a decision was made |
457
- | pp-core handoff synthesis | `Discovery/_pp-handoff.md` | Complete structured summary of all sessions |
458
- | Business requirements | `Discovery/03-business-requirements-to-be.md` | Detailed EPICs, user stories, acceptance criteria |
459
- | Architecture decisions | `Discovery/05-application-integration-architecture.md` | Tech stack rationale, ADRs, component design |
460
- | Security requirements | `Discovery/06-security-compliance-setup.md` | Compliance, encryption, audit requirements |
461
- | Role definitions | `Discovery/07-user-identity-management.md` | RBAC model, permissions, identity provider |
462
- | Integration specs | `Discovery/08-integration-interface-design.md` | External system interfaces, protocols, data flows |
463
- | QA strategy | `Discovery/09-quality-assurance-testing.md` | Test types, coverage targets, quality gates |
464
- | Release plan | `Discovery/11-project-roadmap-release-planning.md` | Sprint plan, milestones, build order |
622
+ | All decisions (accumulated) | `.planning/discovery/_context.md` | Understanding why a decision was made |
623
+ | pp-core handoff synthesis | `.planning/discovery/_pp-handoff.md` | Complete structured summary of all sessions |
624
+ | Business requirements | `.planning/discovery/session-03.md` | Detailed EPICs, user stories, acceptance criteria |
625
+ | Architecture decisions | `.planning/discovery/session-05.md` | Tech stack rationale, ADRs, component design |
626
+ | Security requirements | `.planning/discovery/session-06.md` | Compliance, encryption, audit requirements |
627
+ | Role definitions | `.planning/discovery/session-07.md` | RBAC model, permissions, identity provider |
628
+ | Integration specs | `.planning/discovery/session-08.md` | External system interfaces, protocols, data flows |
629
+ | QA strategy | `.planning/discovery/session-09.md` | Test types, coverage targets, quality gates |
630
+ | Release plan | `.planning/discovery/session-11.md` | Sprint plan, milestones, build order |
465
631
  | Interactive prototype | `prototype/` | Visual reference for UI implementation |
466
632
 
467
633
  ### How pp-core Agents Should Use Discovery
@@ -484,18 +650,18 @@ replace an existing block if present, otherwise append):
484
650
  ```markdown
485
651
  ## Discovery Sprint Context
486
652
 
487
- This project has a completed Discovery Sprint in `Discovery/`. pp-core agents should:
653
+ This project has a completed Discovery Sprint in `.planning/discovery/`. pp-core agents should:
488
654
 
489
655
  1. **Check Discovery before asking the user** — most business and architecture decisions are already documented
490
- 2. **Reference `Discovery/_context.md`** for accumulated cross-session decisions
491
- 3. **Reference `Discovery/_pp-handoff.md`** for the structured synthesis used to initialize pp-core
656
+ 2. **Reference `.planning/discovery/_context.md`** for accumulated cross-session decisions
657
+ 3. **Reference `.planning/discovery/_pp-handoff.md`** for the structured synthesis used to initialize pp-core
492
658
  4. **Use original requirement IDs** (FR-xxx, NFR-xxx, US-xxx, EPIC-xxx) from Discovery in plans and commits
493
659
  5. **Reference specific session files** when a phase involves topics covered in that session:
494
- - Auth/roles → Session 7 (`Discovery/07-user-identity-management.md`)
495
- - Integrations → Session 8 (`Discovery/08-integration-interface-design.md`)
496
- - UI/UX → Session 4 (`Discovery/04-ux-design-principles.md`) + `prototype/`
497
- - Security → Session 6 (`Discovery/06-security-compliance-setup.md`)
498
- - Testing → Session 9 (`Discovery/09-quality-assurance-testing.md`)
660
+ - Auth/roles → Session 7 (`.planning/discovery/session-07.md`)
661
+ - Integrations → Session 8 (`.planning/discovery/session-08.md`)
662
+ - UI/UX → Session 4 (`.planning/discovery/session-04.md`) + `prototype/`
663
+ - Security → Session 6 (`.planning/discovery/session-06.md`)
664
+ - Testing → Session 9 (`.planning/discovery/session-09.md`)
499
665
  ```
500
666
 
501
667
  ```bash
@@ -567,7 +733,7 @@ Phase 1 fleshes it out.
567
733
  Discovery Sprint → pp-core transition successful.
568
734
 
569
735
  Created:
570
- Discovery/_pp-handoff.md Synthesized discovery outputs
736
+ .planning/discovery/_pp-handoff.md Synthesized discovery outputs
571
737
  .planning/PROJECT.md Project context for pp-core
572
738
  .planning/REQUIREMENTS.md {req_count} requirements from {epic_count} EPICs
573
739
  .planning/ROADMAP.md {phase_count} phases mapped from Discovery roadmap
@@ -591,7 +757,11 @@ Quality drives speed. Discovery done, now build.
591
757
 
592
758
  <success_criteria>
593
759
  - Discovery completion validated (or the user acknowledged gaps)
594
- - All session content read and synthesized into `Discovery/_pp-handoff.md`
760
+ - A legacy root-level Discovery tree, if found with no canonical tree present, triggers a
761
+ one-time guided migration offer — never a silent ignore, never a hard error (D-02)
762
+ - Unresolved parked questions are surfaced in the completion check and require explicit
763
+ user confirmation before proceeding — never a hard block (D-12)
764
+ - All session content read and synthesized into `.planning/discovery/_pp-handoff.md`
595
765
  - Synthesis preserves original requirement IDs, role names, and tech choices
596
766
  - pp-core initialized with PROJECT.md, REQUIREMENTS.md, ROADMAP.md, STATE.md, config.json
597
767
  - PROJECT.md contains a Discovery Artifacts reference section
@@ -1,5 +1,10 @@
1
1
  # --chain mode — interactive discuss, then auto-advance
2
2
 
3
+ <workstream_flag_substitution>
4
+ `${GSD_WS}` / `{GSD_WS}` in emitted "Next:" commands and `Skill()` args and agent dispatch prompts is a placeholder, not a shell variable — nothing expands it automatically. Substitute the active `--ws <name>`, or remove it entirely in flat mode. Never print the literal token in user-facing output. See `pp-core/references/workstream-flag.md` § Substitution rule.
5
+ </workstream_flag_substitution>
6
+
7
+
3
8
  > **Lazy-loaded.** Read this file from `workflows/discuss-phase.md` when
4
9
  > `--chain` is present in `$ARGUMENTS`, or when the parent's `auto_advance`
5
10
  > step needs to dispatch to plan-phase under `--auto`.
@@ -11,6 +11,10 @@ Extract implementation decisions that downstream agents need. Analyze the phase
11
11
  You are a thinking partner, not an interviewer. The user is the visionary — you are the builder. Your job is to capture decisions that will guide research and planning, not to figure out implementation yourself.
12
12
  </purpose>
13
13
 
14
+ <workstream_flag_substitution>
15
+ `${GSD_WS}` is a placeholder — substitute the active `--ws <name>` (drop in flat mode); never emit it literally.
16
+ </workstream_flag_substitution>
17
+
14
18
  <required_reading>
15
19
  @~/.claude/pp-core/references/domain-probes.md
16
20
  @~/.claude/pp-core/references/gate-prompts.md
@@ -9,6 +9,10 @@ consumes: PLAN.md
9
9
  Execute all plans in a phase using wave-based parallel execution. Orchestrator stays lean — delegates plan execution to subagents.
10
10
  </purpose>
11
11
 
12
+ <workstream_flag_substitution>
13
+ `${GSD_WS}` is a placeholder — substitute the active `--ws <name>` (drop in flat mode); never emit it literally.
14
+ </workstream_flag_substitution>
15
+
12
16
  <core_principle>
13
17
  Orchestrator coordinates, not executes. Each subagent loads the full execute-plan context. Orchestrator: discover plans → analyze deps → group waves → spawn agents → handle checkpoints → collect results.
14
18
  </core_principle>
@@ -4,6 +4,10 @@ Start a new milestone cycle for an existing project. Loads project context, gath
4
4
 
5
5
  </purpose>
6
6
 
7
+ <workstream_flag_substitution>
8
+ `${GSD_WS}` / `{GSD_WS}` in emitted "Next:" commands and `Skill()` args and agent dispatch prompts is a placeholder, not a shell variable — nothing expands it automatically. Substitute the active `--ws <name>`, or remove it entirely in flat mode. Never print the literal token in user-facing output. See `pp-core/references/workstream-flag.md` § Substitution rule.
9
+ </workstream_flag_substitution>
10
+
7
11
  <required_reading>
8
12
 
9
13
  Read all files referenced by the invoking prompt's execution_context before starting.
@@ -9,6 +9,10 @@ consumes: CONTEXT.md
9
9
  Create executable phase prompts (PLAN.md files) for a roadmap phase with integrated research and verification. Default flow: Research (if needed) -> Plan -> Verify -> Done. Orchestrates pp-phase-researcher, pp-planner, and pp-plan-checker agents with a revision loop (max 3 iterations).
10
10
  </purpose>
11
11
 
12
+ <workstream_flag_substitution>
13
+ `${GSD_WS}` is a placeholder — substitute the active `--ws <name>` (drop in flat mode); never emit it literally.
14
+ </workstream_flag_substitution>
15
+
12
16
  <required_reading>
13
17
  Read all files referenced by the invoking prompt's execution_context before starting.
14
18
 
@@ -2,6 +2,10 @@
2
2
  Check project progress, summarize recent work and what's ahead, then intelligently route to the next action — either executing an existing plan or creating the next one. Provides situational awareness before continuing work.
3
3
  </purpose>
4
4
 
5
+ <workstream_flag_substitution>
6
+ `${GSD_WS}` / `{GSD_WS}` in emitted "Next:" commands and `Skill()` args and agent dispatch prompts is a placeholder, not a shell variable — nothing expands it automatically. Substitute the active `--ws <name>`, or remove it entirely in flat mode. Never print the literal token in user-facing output. See `pp-core/references/workstream-flag.md` § Substitution rule.
7
+ </workstream_flag_substitution>
8
+
5
9
  <required_reading>
6
10
  Read all files referenced by the invoking prompt's execution_context before starting.
7
11
  </required_reading>
@@ -12,6 +12,10 @@ With `--research` flag: spawns a focused research agent before planning. Investi
12
12
  Granular flags are composable: `--discuss --research --validate` gives the same result as `--full`.
13
13
  </purpose>
14
14
 
15
+ <workstream_flag_substitution>
16
+ `${GSD_WS}` / `{GSD_WS}` in emitted "Next:" commands and `Skill()` args and agent dispatch prompts is a placeholder, not a shell variable — nothing expands it automatically. Substitute the active `--ws <name>`, or remove it entirely in flat mode. Never print the literal token in user-facing output. See `pp-core/references/workstream-flag.md` § Substitution rule.
17
+ </workstream_flag_substitution>
18
+
15
19
  <required_reading>
16
20
  Read all files referenced by the invoking prompt's execution_context before starting.
17
21
  </required_reading>
@@ -10,6 +10,10 @@ Use this workflow when:
10
10
  Instantly restore full project context so "Where were we?" has an immediate, complete answer.
11
11
  </purpose>
12
12
 
13
+ <workstream_flag_substitution>
14
+ `${GSD_WS}` / `{GSD_WS}` in emitted "Next:" commands and `Skill()` args and agent dispatch prompts is a placeholder, not a shell variable — nothing expands it automatically. Substitute the active `--ws <name>`, or remove it entirely in flat mode. Never print the literal token in user-facing output. See `pp-core/references/workstream-flag.md` § Substitution rule.
15
+ </workstream_flag_substitution>
16
+
13
17
  <required_reading>
14
18
  @~/.claude/pp-core/references/continuation-format.md
15
19
  </required_reading>
@@ -9,6 +9,10 @@ consumes: UAT.md
9
9
  Create a pull request from completed phase/milestone work, generate a rich PR body from planning artifacts, optionally run code review, and prepare for merge. Closes the plan → execute → verify → ship loop.
10
10
  </purpose>
11
11
 
12
+ <workstream_flag_substitution>
13
+ `${GSD_WS}` / `{GSD_WS}` in emitted "Next:" commands and `Skill()` args and agent dispatch prompts is a placeholder, not a shell variable — nothing expands it automatically. Substitute the active `--ws <name>`, or remove it entirely in flat mode. Never print the literal token in user-facing output. See `pp-core/references/workstream-flag.md` § Substitution rule.
14
+ </workstream_flag_substitution>
15
+
12
16
  <required_reading>
13
17
  Read all files referenced by the invoking prompt's execution_context before starting.
14
18
  </required_reading>
@@ -34,6 +34,10 @@ Mark current phase complete and advance to next. This is the natural point where
34
34
 
35
35
  </purpose>
36
36
 
37
+ <workstream_flag_substitution>
38
+ `${GSD_WS}` / `{GSD_WS}` in emitted "Next:" commands and `Skill()` args and agent dispatch prompts is a placeholder, not a shell variable — nothing expands it automatically. Substitute the active `--ws <name>`, or remove it entirely in flat mode. Never print the literal token in user-facing output. See `pp-core/references/workstream-flag.md` § Substitution rule.
39
+ </workstream_flag_substitution>
40
+
37
41
  <process>
38
42
 
39
43
  <step name="load_project_state" priority="first">
@@ -2,6 +2,10 @@
2
2
  Audit Nyquist validation gaps for a completed phase. Generate missing tests. Update VALIDATION.md.
3
3
  </purpose>
4
4
 
5
+ <workstream_flag_substitution>
6
+ `${GSD_WS}` / `{GSD_WS}` in emitted "Next:" commands and `Skill()` args and agent dispatch prompts is a placeholder, not a shell variable — nothing expands it automatically. Substitute the active `--ws <name>`, or remove it entirely in flat mode. Never print the literal token in user-facing output. See `pp-core/references/workstream-flag.md` § Substitution rule.
7
+ </workstream_flag_substitution>
8
+
5
9
  <required_reading>
6
10
  @~/.claude/pp-core/references/ui-brand.md
7
11
  </required_reading>
@@ -24,20 +24,35 @@ const OPT_OUT_LABEL = 'no-changelog';
24
24
 
25
25
  // Files counted as "user-facing" — touching any of these requires either a
26
26
  // fragment or an explicit opt-out label. Test/CI/docs/lock files do not.
27
+ // This list mirrors package.json's npm-shipped `files` array so that
28
+ // everything reaching an end user's install is gate-covered. Two `files`
29
+ // entries are deliberately EXCLUDED here: `LICENSE` and `NOTICE` — a
30
+ // licence-text edit carries no changelog-worthy behavior change, so it is
31
+ // not a gate trigger even though it ships in the tarball.
32
+ //
33
+ // `src/` is the load-bearing addition (BUS-02, 21-10): the compiled
34
+ // `pp-core/bin/lib/*.cjs` output is gitignored, so a CLI behavior change
35
+ // reaches users through `src/*.cts` alone. Before this widening such a
36
+ // diff matched zero prefixes here (see historical bypass commit 3320c0a4).
27
37
  const USER_FACING_PREFIXES = [
28
38
  'bin/',
29
- 'gsd-core/',
39
+ 'pp-core/',
30
40
  'agents/',
31
41
  'commands/',
32
42
  'hooks/',
33
- 'sdk/src/',
34
- 'sdk/prompts/',
43
+ 'src/',
44
+ 'pareto-skills/',
45
+ 'assets/',
46
+ '.claude-plugin/',
47
+ 'scripts/',
35
48
  ];
36
49
 
37
50
  // Exact-match user-facing files. Any direct edit to one of these without a
38
51
  // fragment also fails the lint — closes the bypass where a contributor edits
39
- // CHANGELOG.md directly to sneak past the new workflow.
40
- const USER_FACING_FILES = new Set(['CHANGELOG.md']);
52
+ // CHANGELOG.md directly to sneak past the new workflow. `gemini-extension.json`
53
+ // and `GEMINI.md` are the other two exact-match npm-shipped files (package.json
54
+ // `files`) that are not already covered by a directory prefix above.
55
+ const USER_FACING_FILES = new Set(['CHANGELOG.md', 'gemini-extension.json', 'GEMINI.md']);
41
56
 
42
57
  function isUserFacing(file) {
43
58
  if (USER_FACING_FILES.has(file)) return true;
@@ -38,8 +38,10 @@ function isFragmentPath(file) {
38
38
  return /^\.changeset\/[^/]+\.md$/.test(file) && !file.endsWith('/README.md');
39
39
  }
40
40
 
41
+ // Phase 21 BUS-02/D-03: CONTRIBUTING.md is a gated deliverable in addition to
42
+ // anything under docs/, so engine MRs that touch it are recognized by the gate.
41
43
  function isDocsFile(file) {
42
- return file.startsWith(DOCS_PREFIX);
44
+ return file === 'CONTRIBUTING.md' || file.startsWith(DOCS_PREFIX);
43
45
  }
44
46
 
45
47
  // Per-fragment escape hatch: parse.cjs extracts `<!-- docs-exempt: <reason> -->`
@@ -193,9 +195,14 @@ function main() {
193
195
  for (const f of fragments.filter((f) => TRIGGERING_TYPES.has(f.type))) {
194
196
  process.stderr.write(` ${f.path} (type: ${f.type})\n`);
195
197
  }
196
- process.stderr.write(`\nNo files under docs/ were modified in this PR.\n\n`);
197
198
  process.stderr.write(
198
- `Update the relevant docs/ file(s), or add the \`${OPT_OUT_LABEL}\` label if this change\n`,
199
+ `\nNo gate-satisfying documentation file was modified in this PR — neither anything\n`,
200
+ );
201
+ process.stderr.write(
202
+ `under \`${DOCS_PREFIX}\` nor \`CONTRIBUTING.md\`.\n\n`,
203
+ );
204
+ process.stderr.write(
205
+ `Update a file under \`${DOCS_PREFIX}\` or \`CONTRIBUTING.md\`, or add the \`${OPT_OUT_LABEL}\` label if this change\n`,
199
206
  );
200
207
  process.stderr.write(
201
208
  `is genuinely internal-only (infrastructure, refactor, test-only). Per-fragment\n`,