@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.
- package/.claude-plugin/plugin.json +1 -1
- package/agents/pp-nyquist-auditor.md +19 -14
- package/agents/pp-phase-researcher.md +10 -0
- package/agents/pp-plan-checker.md +59 -36
- package/agents/pp-planner.md +49 -53
- package/agents/pp-vault-reviewer.md +2 -0
- package/agents/pp-verifier.md +15 -60
- package/commands/pp-autonomous.md +2 -1
- package/commands/pp-discovery.md +3 -2
- 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 +6 -3
- package/pareto-skills/_shared/pp-claude-md-protocol.md +1 -1
- package/pareto-skills/pp-project-setup/SKILL.md +18 -343
- package/pp-core/bin/lib/capability-activation.cjs +77 -0
- package/pp-core/bin/lib/capability-registry.cjs +15 -15
- 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/discovery-access.cjs +276 -0
- package/pp-core/bin/lib/discovery-charter.cjs +664 -0
- package/pp-core/bin/lib/discovery-deviations.cjs +264 -0
- package/pp-core/bin/lib/discovery-entities.cjs +323 -0
- package/pp-core/bin/lib/discovery-for-phase.cjs +628 -0
- package/pp-core/bin/lib/discovery-integrations.cjs +286 -0
- package/pp-core/bin/lib/discovery-migration.cjs +246 -0
- package/pp-core/bin/lib/discovery-phases.cjs +233 -0
- package/pp-core/bin/lib/discovery-processes.cjs +355 -0
- package/pp-core/bin/lib/discovery-research-track.cjs +5 -4
- package/pp-core/bin/lib/discovery-rollup.cjs +8 -7
- package/pp-core/bin/lib/discovery-rules.cjs +216 -0
- package/pp-core/bin/lib/discovery-screens.cjs +1 -1
- package/pp-core/bin/lib/discovery-session-check.cjs +264 -0
- package/pp-core/bin/lib/discovery-stories.cjs +273 -0
- package/pp-core/bin/lib/discovery-sweep.cjs +1 -1
- package/pp-core/bin/lib/discovery-table.cjs +55 -0
- package/pp-core/bin/lib/init.cjs +50 -1
- package/pp-core/bin/lib/io.cjs +24 -0
- package/pp-core/bin/lib/loop-resolver.cjs +26 -12
- package/pp-core/bin/lib/phase.cjs +39 -3
- package/pp-core/bin/lib/plan-sizing.cjs +346 -0
- package/pp-core/bin/lib/test-substance.cjs +3190 -0
- package/pp-core/bin/lib/timeline.cjs +605 -0
- package/pp-core/bin/lib/vault-standards-review.cjs +50 -2
- package/pp-core/bin/pp-tools.cjs +214 -5
- 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/discovery-access.md +112 -0
- package/pp-core/references/discovery-build-consumption.md +256 -0
- package/pp-core/references/discovery-charter.md +127 -0
- package/pp-core/references/discovery-data-model.md +145 -0
- package/pp-core/references/discovery-id-conventions.md +50 -14
- package/pp-core/references/discovery-integrations.md +151 -0
- package/pp-core/references/discovery-processes.md +190 -0
- package/pp-core/references/discovery-rebaseline.md +2 -2
- package/pp-core/references/discovery-research-track.md +5 -6
- package/pp-core/references/discovery-session-output.md +70 -0
- package/pp-core/references/discovery-standards.md +107 -0
- package/pp-core/references/discovery-traceability.md +2 -2
- 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-discovery-extract.md +35 -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-discovery-conformance.md +36 -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/project-charter.md +161 -100
- package/pp-core/templates/project.md +3 -3
- package/pp-core/templates/requirements.md +18 -0
- package/pp-core/templates/roadmap.md +1 -1
- package/pp-core/templates/verification-report.md +17 -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 +15 -6
- package/pp-core/workflows/discovery-sprint/charter.md +114 -0
- package/pp-core/workflows/discovery-sprint/prefill.md +1 -1
- package/pp-core/workflows/discovery-sprint/prototype.md +4 -4
- package/pp-core/workflows/discovery-sprint/session-13-gates.md +10 -0
- package/pp-core/workflows/discovery-sprint/sessions/01-kick-off.md +5 -2
- package/pp-core/workflows/discovery-sprint/sessions/02-as-is.md +27 -5
- package/pp-core/workflows/discovery-sprint/sessions/03-to-be.md +56 -31
- package/pp-core/workflows/discovery-sprint/sessions/04-ux-design.md +1 -1
- package/pp-core/workflows/discovery-sprint/sessions/05-architecture.md +42 -19
- package/pp-core/workflows/discovery-sprint/sessions/06-security.md +27 -12
- package/pp-core/workflows/discovery-sprint/sessions/07-identity.md +41 -23
- package/pp-core/workflows/discovery-sprint/sessions/08-integration.md +50 -23
- package/pp-core/workflows/discovery-sprint/sessions/09-qa.md +26 -11
- package/pp-core/workflows/discovery-sprint/sessions/10-infrastructure.md +28 -9
- package/pp-core/workflows/discovery-sprint/sessions/11-roadmap.md +21 -0
- package/pp-core/workflows/discovery-sprint/sessions/13-wrap-up.md +24 -9
- package/pp-core/workflows/discovery-sprint.md +12 -15
- package/pp-core/workflows/discovery-to-build/steps/architecture-deliverables.md +80 -29
- package/pp-core/workflows/discovery-to-build/steps/{screen-inventory-gate.md → handoff-gates.md} +111 -3
- package/pp-core/workflows/discovery-to-build/templates/discovery-references.md +12 -9
- package/pp-core/workflows/discovery-to-build/templates/pp-handoff.md +27 -26
- package/pp-core/workflows/discovery-to-build.md +70 -34
- package/pp-core/workflows/discuss-phase/discovery.md +83 -0
- package/pp-core/workflows/discuss-phase/templates/context.md +4 -0
- package/pp-core/workflows/discuss-phase.md +10 -7
- 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 +14 -3
- package/pp-core/workflows/new-project.md +3 -3
- package/pp-core/workflows/plan-phase/steps/chunked-planning.md +7 -3
- package/pp-core/workflows/plan-phase/steps/discovery-extract.md +41 -0
- package/pp-core/workflows/plan-phase/steps/prd-express.md +104 -0
- package/pp-core/workflows/plan-phase.md +62 -124
- package/pp-core/workflows/plan-review-convergence.md +6 -3
- package/pp-core/workflows/ship.md +2 -2
- package/pp-core/workflows/stats.md +19 -4
- package/pp-core/workflows/validate-phase.md +19 -4
- package/pp-core/workflows/vault-review.md +5 -0
- 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
- package/pp-core/workflows/discovery-sprint/templates/context-template.md +0 -272
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# Discovery Standards First — `_deviations.md` Template, Parser Contract & the Standards Applied Table
|
|
2
|
+
|
|
3
|
+
Single home for how the Discovery Sprint treats the client's standards once a vault is bound
|
|
4
|
+
(Discovery Sprint improvement plan, Batch 3): the questions the vault already answers are not asked
|
|
5
|
+
open-ended, every session from 4 to 10 records which standard governs each area in a **Standards
|
|
6
|
+
Applied** table, and every departure from a standard is one `DEV-` row of `_deviations.md` — the
|
|
7
|
+
register the charter § 7 copies, the handoff gates on, and `pp-vault-review` reads so an approved
|
|
8
|
+
deviation is reported as a deviation on file, never as a violation. This file is Read lazily; it is
|
|
9
|
+
never `@`-imported.
|
|
10
|
+
|
|
11
|
+
## Standards first — the question rule
|
|
12
|
+
|
|
13
|
+
When a session's `## Vault Context` record names a document that already fixes what a topic asks the
|
|
14
|
+
client to decide, the facilitator does not ask the open question. The question becomes:
|
|
15
|
+
|
|
16
|
+
> The vault fixes `<what>` — `[vault: <path>]`. Does this product deviate, and why?
|
|
17
|
+
|
|
18
|
+
- **No deviation:** the Standards Applied row cites the standard, `Deviation` reads `none`. Nothing
|
|
19
|
+
else is written — the vault stays the single home of the standard (never copy its text).
|
|
20
|
+
- **A deviation:** mint one `DEV-<nn>` row in `.planning/discovery/_deviations.md` (create the file
|
|
21
|
+
from the template below on first need), record the decision as a Key Decisions row `D-<ss>-<n>` and
|
|
22
|
+
write both IDs into the Standards Applied row (`Deviation` = the `DEV-nn`, `Decision` = the `D-ss-n`).
|
|
23
|
+
- **No standard covers the area:** the Standards Applied row reads `not in vault`; the question stays
|
|
24
|
+
open-ended and the answer is a Key Decisions row; add an Action Items row for the vault owner when
|
|
25
|
+
the gap should be closed in the vault.
|
|
26
|
+
- **No vault bound** (the session record says `Index: none`, or the project runs without the vault
|
|
27
|
+
capability): every question stays open-ended, Standards Applied rows read `not in vault`, and
|
|
28
|
+
`_deviations.md` is never created — there is no standard to deviate from.
|
|
29
|
+
|
|
30
|
+
The session files phrase their stack and tooling questions in this shape; the vault document to cite
|
|
31
|
+
is the one the session's `## Vault Context` record selected for that topic.
|
|
32
|
+
|
|
33
|
+
## The Standards Applied table
|
|
34
|
+
|
|
35
|
+
Every session from 4 to 10 carries one, in its Notes Template, with the areas the session decides:
|
|
36
|
+
|
|
37
|
+
| Area | Standard | Deviation | Decision |
|
|
38
|
+
|------|----------|-----------|----------|
|
|
39
|
+
|
|
40
|
+
- **Standard** is the governing document's `[vault: <rel path>]` citation (several, space-separated,
|
|
41
|
+
when more than one applies), or `not in vault`.
|
|
42
|
+
- **Deviation** is `none`, or the `DEV-<nn>` of the `_deviations.md` row.
|
|
43
|
+
- **Decision** is `—`, or the `D-<ss>-<n>` that records the deviation or the decision taken for an
|
|
44
|
+
uncovered area.
|
|
45
|
+
|
|
46
|
+
The charter § 7 reads `_deviations.md`, not these tables; the tables are where a reader of one
|
|
47
|
+
session sees which standards bound it. Session 4 introduced the shape (frontend standards); Sessions
|
|
48
|
+
5–10 follow it.
|
|
49
|
+
|
|
50
|
+
## `_deviations.md`
|
|
51
|
+
|
|
52
|
+
A deviation is a choice that goes against a standard the vault states. The vault's own rule
|
|
53
|
+
(`architecture/deviations.md` in the Pareto vault, and its equivalent elsewhere): deviating is
|
|
54
|
+
allowed, hiding it is not; an architect signs every one; only what is **hard to reverse** waits for
|
|
55
|
+
the signature before the dependent work proceeds, and a security or compliance deviation is always
|
|
56
|
+
hard. The register carries exactly that record.
|
|
57
|
+
|
|
58
|
+
Illustration only — not part of the template:
|
|
59
|
+
|
|
60
|
+
| ID | Standard | Choice | Reason | Reversible | Approver | Decision | Status |
|
|
61
|
+
|---|---|---|---|---|---|---|---|
|
|
62
|
+
| DEV-01 | [vault: pipeline/quality-gates.md] | Trivy and CodeQL instead of SonarCloud | Free plan, one-person team | easy | Architect | D-09-3 | Approved |
|
|
63
|
+
|
|
64
|
+
Bootstrap template — the first session that records a deviation copies it verbatim to
|
|
65
|
+
`.planning/discovery/_deviations.md`, replacing `[PROJECT_NAME]`:
|
|
66
|
+
|
|
67
|
+
```markdown
|
|
68
|
+
# Deviations from standards — [PROJECT_NAME]
|
|
69
|
+
|
|
70
|
+
**Conventions:** pp-core reference `references/discovery-standards.md`. One `DEV-` row per departure from a vault standard: the standard as a `[vault: <path>]` citation, the choice made instead, why, whether it is `easy` or `hard` to reverse (a security or compliance deviation is always `hard`), who approves it (an approver of Session 1's Approval Matrix), the `D-<ss>-<n>` that recorded it and its status (`Proposed`, `Approved`, `Rejected`, `Superseded`). A hard deviation is approved before the handoff. Rows are never renumbered or deleted; a change after sign-off edits the row in place and appends `→ amended by D-<ss>-<n>`.
|
|
71
|
+
|
|
72
|
+
## Deviations
|
|
73
|
+
|
|
74
|
+
| ID | Standard | Choice | Reason | Reversible | Approver | Decision | Status |
|
|
75
|
+
|----|----------|--------|--------|------------|----------|----------|--------|
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Parser contract — `pp_run query discovery.deviations-check [--require-approved]`
|
|
79
|
+
|
|
80
|
+
No positional path. Faults name the artifact, the 1-based line, a validated ID or path, a column name
|
|
81
|
+
and the reason code — never cell prose. Absent `_deviations.md` → exit 0, `present: false`.
|
|
82
|
+
|
|
83
|
+
| Cell / field | Grammar | Fault when violated |
|
|
84
|
+
|---|---|---|
|
|
85
|
+
| `## Deviations` | once, holding one table with the template's columns | `missing_section`, `bad_table_shape` |
|
|
86
|
+
| `ID` | `DEV-\d{2}`, unique, contiguous from 01 | `bad_id`, `duplicate_id`, `sequence_gap` naming the missing ID |
|
|
87
|
+
| `Standard` | at least one `[vault: <path>]`; each path relative, no `..` or dot segment, ending `.md`, and present in the vault cache when `.planning/vault/` is on disk | `bad_standard` (no citation, or an unsafe path); `unknown_standard` naming the path. **Not resolved** while there is no cache |
|
|
88
|
+
| `Choice`, `Reason` | non-empty | `empty_cell` naming the column |
|
|
89
|
+
| `Reversible` | `easy` \| `hard` | `bad_reversible` |
|
|
90
|
+
| `Approver` | non-empty; one of the `Approver` tokens of Session 1's **Approval Matrix** when that table is on file with rows | `empty_cell (Approver)`; `unknown_approver`. **Not resolved** while Session 1 has no matrix (an engagement that predates it) |
|
|
91
|
+
| `Decision` | `—`, or `D-<ss>-<n>` / `D-P<nn>-<n>` (shape only — `charter-check` resolves it) | `bad_decision`; `decision_missing` when `Status` is `Approved` or `Rejected` and the cell is `—` |
|
|
92
|
+
| `Status` | `Proposed` \| `Approved` \| `Rejected` \| `Superseded` | `bad_status` |
|
|
93
|
+
| a `hard` row still `Proposed` | approved before the handoff | `hard_deviation_unapproved` under `--require-approved` only |
|
|
94
|
+
| `session-01.md` present but unreadable | present-and-readable | `artifact_unreadable` naming the path |
|
|
95
|
+
|
|
96
|
+
**Exit identity.** `discovery_deviations_check_failed` for structural faults;
|
|
97
|
+
`discovery_deviations_unapproved` when every fault is a `hard_deviation_unapproved`. Payload: `ok`,
|
|
98
|
+
`present`, `file`, `deviations`, `approved`, `unapproved_hard`.
|
|
99
|
+
|
|
100
|
+
## Who reads it
|
|
101
|
+
|
|
102
|
+
| Reader | Contract |
|
|
103
|
+
|---|---|
|
|
104
|
+
| Project Charter § 7 | copies every row; `charter-check` resolves `DEV-` IDs against this file alone and reports `deviation_missing` for a row the charter leaves out (`references/discovery-charter.md`) |
|
|
105
|
+
| `/pp-discovery-to-build` | `deviations-check --require-approved` hard-blocks on a hard deviation still `Proposed` (`workflows/discovery-to-build/steps/handoff-gates.md`) |
|
|
106
|
+
| `pp-vault-review` | reads `Standard` and `Status` by header name; an `Approved` row covering a failed clause turns the FAIL into `N-A` "deviation on file" (`references/discovery-build-consumption.md` § `_deviations.md` read contract) |
|
|
107
|
+
| `discovery for-phase` | the register has no requirement column, so every extract lists it as not filterable — the planner reads it whole |
|
|
@@ -14,8 +14,8 @@ does not restate them. Read that file when you need an ID's shape or the reserve
|
|
|
14
14
|
|
|
15
15
|
## When these files appear
|
|
16
16
|
|
|
17
|
-
Both artifacts are bootstrapped **on first need**, exactly the way `_progress.md`
|
|
18
|
-
|
|
17
|
+
Both artifacts are bootstrapped **on first need**, exactly the way `_progress.md`
|
|
18
|
+
is in Flow 2 Step 1, and exactly the way the three research-track registers
|
|
19
19
|
are in `references/discovery-research-track.md`: if the file is absent when a session first
|
|
20
20
|
has something to put in it, create it verbatim from the template below, then add the row.
|
|
21
21
|
There is no sub-command and no setup step — an empty inventory is not a milestone, and an
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
component: plan-checker
|
|
3
|
-
version:
|
|
4
|
-
last_calibrated: 2026-
|
|
3
|
+
version: 2
|
|
4
|
+
last_calibrated: 2026-10-27
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Plan-Checker Few-Shot Examples
|
|
@@ -55,19 +55,19 @@ last_calibrated: 2026-03-24
|
|
|
55
55
|
|
|
56
56
|
**Why this is bad:** The checker missed two violations. verification_derivation requires verify commands to be runnable and test actual output -- an empty verify block is a BLOCKER. Verify commands must distinguish pass from fail -- `echo "done"` always returns 0 regardless of implementation state. Both should have been flagged.
|
|
57
57
|
|
|
58
|
-
### Example 2: False positive
|
|
58
|
+
### Example 2: False positive on a 6-task plan within limits, missed serial over-split
|
|
59
59
|
|
|
60
|
-
**Input:** Plan
|
|
60
|
+
**Input:** Phase at `context_window: 1000000` (`plan_budget_tokens` 500000). Plan 01 has 6 tasks, 14 files, `context_estimate: 240000`, wave 1. Plan 02 (2 tasks, `context_estimate: 60000`) is alone in wave 2 and depends on 01. Plan 03 (3 tasks, `context_estimate: 70000`) is alone in wave 3 and depends on 02. `check plan-sizing` reports `over_ceiling: []` and `unjustified_splits: [02, 03]`.
|
|
61
61
|
|
|
62
62
|
**Output:**
|
|
63
63
|
|
|
64
64
|
> ```yaml
|
|
65
65
|
> issues:
|
|
66
66
|
> - dimension: scope_sanity
|
|
67
|
-
> severity:
|
|
68
|
-
> finding: "Plan has
|
|
67
|
+
> severity: WARNING
|
|
68
|
+
> finding: "Plan 01 has 6 tasks -- consider splitting into smaller plans"
|
|
69
69
|
> affected_field: "task count"
|
|
70
|
-
> suggested_fix: "Split
|
|
70
|
+
> suggested_fix: "Split plan 01 into separate plans"
|
|
71
71
|
> ```
|
|
72
72
|
|
|
73
|
-
**Why this is bad:**
|
|
73
|
+
**Why this is bad:** Both calls are wrong. 6 tasks is within the ceiling and 240000 fits the 500000 budget, so plan 01 has no issue (01 and 02 merged would be 8 tasks, so that split is justified). Plans 02 and 03 are a serial split with neither reason (merged 5 tasks / 130000 tokens), so a correct check raises one scope_sanity blocker for that pair with fix "merge 03 into 02" and nothing for plan 01.
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# Phase Timeline
|
|
2
|
+
|
|
3
|
+
Every `Agent()` run that plan-phase, execute-phase and code-review spawn is recorded in `{phase_dir}/{padded}-TIMELINE.jsonl`, one JSON object per line, append-only. Only the orchestrator writes, on its own checkout, before and after each spawn. An executor never receives a timeline instruction, so a worktree executor is recorded like any other run and nothing is lost when its worktree is removed. The file is committed with the existing planning commits (plan-phase 13d, execute-phase `update_roadmap` and code-review `commit_review`), never per run. When `.planning/` is gitignored that commit reports `skipped_gitignored` by design and the file stays on disk.
|
|
4
|
+
|
|
5
|
+
## Record
|
|
6
|
+
|
|
7
|
+
| Field | Type | Meaning |
|
|
8
|
+
|-------|------|---------|
|
|
9
|
+
| `id` | string | `{phase}-{role}[-{plan}]-{n}`, minted by `start` |
|
|
10
|
+
| `phase` | string | padded phase token, for example `35` |
|
|
11
|
+
| `agent` | string | agent name, defaulted from the role table |
|
|
12
|
+
| `role` | enum | `researcher`, `pattern-mapper`, `planner`, `plan-checker`, `executor`, `code-reviewer`, `verifier`, `other` |
|
|
13
|
+
| `model` | string | the model the orchestrator passed to `Agent()`; `inherit` is recorded literally |
|
|
14
|
+
| `plan` | string or null | plan id for executors, `null` for every other role |
|
|
15
|
+
| `started_at` | string | ISO-8601 UTC |
|
|
16
|
+
| `ended_at` | string or null | ISO-8601 UTC; `null` while the run is open |
|
|
17
|
+
| `duration_ms` | number or null | `ended_at - started_at`, recomputed on read |
|
|
18
|
+
| `outcome` | string or null | return marker mapped in Outcomes; `null` while open |
|
|
19
|
+
| `source` | enum | `plan-phase`, `execute-phase` or `code-review` |
|
|
20
|
+
|
|
21
|
+
`start` appends a full record with null end fields. `end` appends a second complete line with the same `id`. Readers keep the last line per `id`, sort by `started_at` and skip lines that do not parse, so a torn write loses at most one line. A record with `ended_at: null` is incomplete: it is shown as `incomplete` and excluded from wall-clock and agent time.
|
|
22
|
+
|
|
23
|
+
## Commands
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
pp_run timeline start <role> <phase> [--plan P] [--agent A] [--model M] [--source S]
|
|
27
|
+
pp_run timeline end <role> <phase> <outcome> [--plan P] [--id ID]
|
|
28
|
+
pp_run timeline summary <phase> [--banner]
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
- `start` prints the new id. `end` closes the most recent open record with that role, and that plan when `--plan` is given, and prints the closed record.
|
|
32
|
+
- Synonyms: `--phase`, `--role`, `--outcome` replace the positionals, and `end` takes `--id ID`, or an id positional together with `--outcome`, in place of the role.
|
|
33
|
+
- Defaults: `agent` comes from the role table (`pp-phase-researcher`, `pp-pattern-mapper`, `pp-planner`, `pp-plan-checker`, `pp-executor`, `pp-code-reviewer`, `pp-verifier`); `model` comes from the model-profile resolver when `--model` is omitted; `source` is inferred from the role. Role `other` requires both `--agent` and `--source`.
|
|
34
|
+
- `end` with nothing open exits 1 with reason `timeline_no_open_run`; an unknown or archived phase exits 1 with `phase_not_found`; bad flags exit 1 with `usage`. A failed call never changes the file.
|
|
35
|
+
- Free text (outcome, agent, model) is sanitized and capped at 80 characters before it is written.
|
|
36
|
+
- The clock comes from the CLI. Workflows never compute a duration with `date`.
|
|
37
|
+
- `summary` reads live and archived phases. Plain `summary` prints JSON (or the footer line with `--raw`); `--banner` prints the two completion-block lines.
|
|
38
|
+
|
|
39
|
+
## Call-site rules
|
|
40
|
+
|
|
41
|
+
- Put `start` on the line before the `Agent()` fence and `end` where the return is handled.
|
|
42
|
+
- Every call ends with `|| true`, so a timing failure can never break a phase, and carries no stderr redirection.
|
|
43
|
+
- Key by role (and `--plan {plan_id}` for executors), never by an id held in a shell variable: each fenced block runs in its own shell (issue #381) and `Agent()` is not bash.
|
|
44
|
+
- Pass `--model` only where the `Agent()` model differs from the resolver default: `"{researcher_model}"` for the pattern mapper, `"{executor_model}"` for executors, `inherit` where `Agent()` receives no `model=` (code reviewer, drift-gate mapper).
|
|
45
|
+
- Worktree executors are dispatched in the background, so the executor `end` rides the plan-complete heartbeat in step 4, not the line after the fence.
|
|
46
|
+
- Never put a timeline call inside an agent prompt.
|
|
47
|
+
- Workflows reference this file by plain path, never with an `@` import, so it is read only when a rule is needed.
|
|
48
|
+
|
|
49
|
+
## Sites
|
|
50
|
+
|
|
51
|
+
| Workflow | Section | Role | Flags | End location |
|
|
52
|
+
|----------|---------|------|-------|--------------|
|
|
53
|
+
| plan-phase.md | 5.1 researcher | `researcher` | none | first line under `### Handle Researcher Return` |
|
|
54
|
+
| plan-phase.md | 5.6 capability `ref.agent` dispatch | `other` | `--agent {capId} --source plan-phase` | after the dispatched agent returns |
|
|
55
|
+
| plan-phase.md | 7.8 pattern mapper | `pattern-mapper` | `--model "{researcher_model}"` | under `**Handle return:**` |
|
|
56
|
+
| plan-phase.md | 8 planner | `planner` | none | first line of `## 9. Handle Planner Return` |
|
|
57
|
+
| plan-phase.md | 10 plan checker | `plan-checker` | none | first line of `## 11. Handle Checker Return` |
|
|
58
|
+
| plan-phase.md | 12 revision planner | `planner` | none | on the `After planner returns` line |
|
|
59
|
+
| chunked-planning.md | 8.5.1 outline planner | `planner` | none | under `Handle return:` |
|
|
60
|
+
| chunked-planning.md | 8.5.2 per-plan planner | `planner` | none | step 4 `Verify disk`, before the Retry/Stop offer |
|
|
61
|
+
| execute-phase.md | step 3/4 executor, worktree and sequential mode | `executor` | `--plan {plan_id} --model "{executor_model}"` | start after the plan-start heartbeat; end with the plan-complete heartbeat |
|
|
62
|
+
| execute-phase.md | `verify_phase_goal` verifier | `verifier` | none | start in the `VERIFIER_SKILLS` fence; end in the `verification.status` fence with `"${STATUS:-failed}"` |
|
|
63
|
+
| execute-phase/steps/codebase-drift-gate.md | optional mapper | `other` | `--agent pp-codebase-mapper --source execute-phase --model inherit` | after the mapper returns |
|
|
64
|
+
| code-review.md | `pp-code-reviewer` | `code-reviewer` | `--model inherit` | last line of `commit_review`: `complete` only when REVIEW.md exists with valid frontmatter, else `failed`; `failed` on the agent-failure path |
|
|
65
|
+
|
|
66
|
+
Chunked return path: chunked-planning.md hands `## PLANNING COMPLETE` to step 9 but skips step 9's planner `end` — both chunked runs are already closed, and a third `end` would only print `timeline_no_open_run`.
|
|
67
|
+
|
|
68
|
+
Commit sites: plan-phase 13d, execute-phase `update_roadmap` and code-review `commit_review` add `{phase_dir}/*-TIMELINE.jsonl` to the existing planning commit, so a standalone `/pp-code-review` (or a `--fix` re-run) does not leave the reviewer's lines uncommitted. `cmdCommit` skips the glob when it matches nothing.
|
|
69
|
+
|
|
70
|
+
Banner site: execute-phase `update_roadmap` runs `pp_run timeline summary {phase} --banner`, and the three completion blocks (`## PHASE COMPLETE` on the `--no-transition` path and both `## ✓ Phase {X}: {Name} Complete` blocks) print its stdout verbatim.
|
|
71
|
+
|
|
72
|
+
## Outcomes
|
|
73
|
+
|
|
74
|
+
| Run | Return | Outcome |
|
|
75
|
+
|-----|--------|---------|
|
|
76
|
+
| researcher | `## RESEARCH COMPLETE` | `complete` |
|
|
77
|
+
| researcher | `## RESEARCH BLOCKED` | `blocked` |
|
|
78
|
+
| pattern mapper | `## PATTERN MAPPING COMPLETE` | `complete` |
|
|
79
|
+
| pattern mapper | error or empty | `failed` |
|
|
80
|
+
| planner | `## PLANNING COMPLETE` | `complete` |
|
|
81
|
+
| planner | `## PLANNING INCONCLUSIVE` | `inconclusive` |
|
|
82
|
+
| planner | `## CHECKPOINT REACHED` | `checkpoint` |
|
|
83
|
+
| planner | `## PHASE SPLIT RECOMMENDED` | `split_recommended` |
|
|
84
|
+
| planner | `## ⚠ Source Audit` | `source_audit_gaps` |
|
|
85
|
+
| planner | no marker (filesystem fallback) | `fallback` |
|
|
86
|
+
| plan checker | `## VERIFICATION PASSED` | `passed` |
|
|
87
|
+
| plan checker | `## ISSUES FOUND` | `issues_found` |
|
|
88
|
+
| plan checker | no marker | `fallback` |
|
|
89
|
+
| chunked outline | `## OUTLINE COMPLETE` | `complete`, otherwise `failed` |
|
|
90
|
+
| chunked per-plan | plan file on disk | `complete`; missing: `failed` |
|
|
91
|
+
| executor | plan-complete heartbeat word | `complete`, `failed` or `checkpoint`; `fallback` when the spot-check confirmed completion |
|
|
92
|
+
| verifier | `$STATUS` verbatim | `passed`, `gaps_found`, `human_needed`, `missing` or `unknown`; empty: `failed` |
|
|
93
|
+
| code reviewer, drift-gate mapper, capability agents | agent result | `complete` or `failed` |
|
|
94
|
+
|
|
95
|
+
Free text is accepted and shown verbatim after sanitizing.
|
|
96
|
+
|
|
97
|
+
## Wall-clock
|
|
98
|
+
|
|
99
|
+
- Each source (`plan-phase`, `execute-phase`, `code-review`) gets one span: the latest `ended_at` minus the earliest `started_at` over that source's completed runs, so parallel executors count once.
|
|
100
|
+
- Total wall-clock is the length of the union of those spans. It equals the plain sum when the spans are disjoint, so idle days between planning and executing are excluded, and a code review that runs inside the execute span counts once.
|
|
101
|
+
- `elapsed` is the first start to the last end. It appears in the footer only when it differs from the total.
|
|
102
|
+
- Agent time is the sum of completed run durations.
|
|
103
|
+
- Durations are compact: `38s`, `45m 10s`, `1h 12m`, `3h 02m`. `Started` is local time `HH:MM`, with the date shown once per table (a run on another day carries `MM-DD HH:MM`).
|
|
104
|
+
- Footer: `Total wall-clock: 2h 14m · agent time 3h 02m · 12 runs (1 incomplete)`, plus `· elapsed {duration}` when it differs.
|
|
105
|
+
- Banner (two lines): `Wall-clock: 2h 14m (12 runs)` and `Longest: executor 35-03 (claude-opus-4-7) 41m · planner (opus) 22m · verifier (sonnet) 17m`. Each longest entry is `{role}[ {plan}][ ({model})] {duration}`; the model is omitted only when it is `inherit`. With fewer than three completed runs there are fewer entries.
|
|
106
|
+
- No records (every phase executed before the timeline existed): pp-stats has no timeline section for the phase, the Wall-clock column shows `—`, plain `summary` prints `no recorded runs`, and `--banner` prints nothing and exits 0.
|
|
107
|
+
- Known limit: a source whose runs are days apart (for example a re-plan after execution) forms one span and counts the idle gap.
|
|
@@ -88,6 +88,38 @@ A plan should not interleave multiple checkpoint types with implementation tasks
|
|
|
88
88
|
|
|
89
89
|
If a decision from CONTEXT.md says "display cost calculated from billing table in impulses", the plan must deliver exactly that. Not "static label /min" as a "v1". If the phase is too complex, recommend a phase split instead of silently reducing scope.
|
|
90
90
|
|
|
91
|
+
## Plan-Split Anti-Patterns
|
|
92
|
+
|
|
93
|
+
A plan is split for exactly two reasons: **parallelism** (independent subsystems, disjoint `files_modified`, same wave) or **budget** (merged, the work exceeds `plan_budget_tokens` or 6 tasks). Anything else is over-splitting: every extra plan pays its own executor, review and verification run.
|
|
94
|
+
|
|
95
|
+
### Bad — Serial single-concern work split to fit a task count
|
|
96
|
+
|
|
97
|
+
"Add authentication" on an empty repository, `context_window: 200000` (`plan_budget_tokens` 100000), planned as three plans each alone in its wave:
|
|
98
|
+
|
|
99
|
+
```yaml
|
|
100
|
+
# 01-01 wave 1 schema 2 tasks context_estimate: 35000
|
|
101
|
+
# 01-02 wave 2 endpoints 2 tasks context_estimate: 35000 depends_on: [01-01]
|
|
102
|
+
# 01-03 wave 3 middleware 2 tasks context_estimate: 35000 depends_on: [01-02]
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
**Why bad:** nothing runs in parallel and no plan is near the budget. 01-01 and 01-02 merge to 4 tasks / 70000 tokens, within both limits. `check plan-sizing` flags both pairs and reports `min_plans: 2`.
|
|
106
|
+
|
|
107
|
+
### Good — Merge while the estimate fits; split only with a visible reason
|
|
108
|
+
|
|
109
|
+
```yaml
|
|
110
|
+
# One plan: 5 tasks, context_estimate: 90000 (fits 100000)
|
|
111
|
+
# Honest estimate 105000 -> two plans, the budget reason is visible:
|
|
112
|
+
# 01-01 4 tasks context_estimate: 70000
|
|
113
|
+
# 01-02 2 tasks context_estimate: 35000 depends_on: [01-01]
|
|
114
|
+
# At context_window: 1000000 the same 105000 fits one plan.
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Two plans on independent subsystems with disjoint `files_modified` in the same wave are the parallelism reason.
|
|
118
|
+
|
|
119
|
+
### Merging a flagged pair
|
|
120
|
+
|
|
121
|
+
Merge one pair at a time: the first `unjustified_splits` pair in wave order. Fold the later plan's tasks, `files_modified`, `requirements`, `must_haves` and estimate into the earlier plan; delete the later PLAN.md; renumber later plans and fix every `depends_on` and `wave`; re-run `pp_run check plan-sizing <phase> --raw` and `pp_run query verify.plan-structure` on every renumbered or merged PLAN.md, check that every `depends_on` names a plan that still exists (neither command catches a dangling one), and repeat until `block` is false and no plan reports errors. Overlapping pairs share a plan (01→02→03 reports both (01, 02) and (02, 03)), so merging every reported pair at once can overshoot the budget; one at a time ends at `min_plans` plans. Plans in the same wave with disjoint files, and pairs whose merge exceeds 6 tasks or `plan_budget_tokens`, stay split. Gap-closure plans and phase splits (`## PHASE SPLIT RECOMMENDED`) are separate mechanisms.
|
|
122
|
+
|
|
91
123
|
## Comment-Text Discipline (HARD GATE)
|
|
92
124
|
|
|
93
125
|
> Enforced at plan-write time by `verify.plan-structure` (the `validate_plan` step). Issue #429.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Discovery extract — the planner and researcher contract (R1)
|
|
2
|
+
|
|
3
|
+
**Load this file when a `{padded}-DISCOVERY-EXTRACT.md` is listed in your files to read** — the
|
|
4
|
+
plan-phase orchestrator renders it with `pp_run query discovery.for-phase <N> --markdown` on a
|
|
5
|
+
project that ran the Discovery Sprint (contract: `references/discovery-build-consumption.md`).
|
|
6
|
+
When no such file is listed, nothing described here applies.
|
|
7
|
+
|
|
8
|
+
The extract holds the rows of the Discovery registers (`_requirements.md`, `_stories.md`,
|
|
9
|
+
`_processes.md`, `_entities.md`, `_rules.md`, `_screens.md`, roles, integrations) that cite this
|
|
10
|
+
phase's requirement IDs. It is the client's signed-off fact base for this phase.
|
|
11
|
+
|
|
12
|
+
## Planner
|
|
13
|
+
|
|
14
|
+
1. **Required reading.** Read the extract in full before planning.
|
|
15
|
+
2. **Never open `.planning/discovery/session-NN.md`.** The session files are the facilitation
|
|
16
|
+
record; the registers are the source of truth, amended in place. A fact you need that the
|
|
17
|
+
extract lacks is a question for the user — surface it under Claude's Discretion or the plan's
|
|
18
|
+
open questions — not a reason to read a transcript.
|
|
19
|
+
3. **Cite rows, do not restate them.** A task that realises a step cites `MP-01 #3`; a validation
|
|
20
|
+
task cites `BR-02`; a data task cites the entity by name; a screen task cites `SCR-04`. Put the
|
|
21
|
+
row's acceptance criteria (`_requirements.md`, `_stories.md`) into the task's
|
|
22
|
+
`<acceptance_criteria>` verbatim — they are the verifier's UAT (R3).
|
|
23
|
+
4. **Embed verbatim.** Copy the file's content byte for byte, `<!-- discovery:auto -->` markers
|
|
24
|
+
included, as the `<discovery_extract>` block of every PLAN.md of this phase, after `<context>`
|
|
25
|
+
(after `<vault_standards>` when present) and before `<tasks>`. Never edit a cell: a discovery
|
|
26
|
+
fact that must change is amended in the register by `/pp-discuss-phase` (R2), then re-rendered.
|
|
27
|
+
5. **Contradictions are findings.** If the extract contradicts CONTEXT.md, the codebase or itself,
|
|
28
|
+
plan nothing on the contradiction — name both sides in the plan's open questions.
|
|
29
|
+
|
|
30
|
+
## Researcher
|
|
31
|
+
|
|
32
|
+
Research HOW to build what the rows say, never WHETHER: entities, rules, process steps, screens
|
|
33
|
+
and acceptance criteria here are decided. List the entities, integrations and rules the extract
|
|
34
|
+
names under `## User Constraints` as "Discovery facts (by row ID)" so the planner sees them beside
|
|
35
|
+
the locked decisions. Rule 2 above applies in full.
|
|
@@ -24,7 +24,7 @@ PLAN.md IS the prompt (not a document that becomes one). Contains:
|
|
|
24
24
|
| 50-70% | DEGRADING | Efficiency mode begins |
|
|
25
25
|
| 70%+ | POOR | Rushed, minimal |
|
|
26
26
|
|
|
27
|
-
**Rule:** Plans should complete within ~50% context.
|
|
27
|
+
**Rule:** Plans should complete within ~50% context. Each plan: up to 6 tasks while its summed estimate stays within `plan_budget_tokens` (50% of the configured `context_window`); the task count follows the estimate, never a target. Split only for parallelism or budget.
|
|
28
28
|
|
|
29
29
|
## Ship Fast
|
|
30
30
|
|
|
@@ -47,19 +47,20 @@ Plan -> Execute -> Ship -> Learn -> Repeat
|
|
|
47
47
|
|
|
48
48
|
## Task Sizing
|
|
49
49
|
|
|
50
|
-
Each task targets **10–30% context consumption
|
|
50
|
+
Each task targets **10–30% context consumption** at the 200k calibration — ~20-60k tokens, a band stated in tokens so it holds at every `context_window` (a larger window fits more tasks per plan, not larger tasks).
|
|
51
51
|
|
|
52
52
|
| Context Cost | Action |
|
|
53
53
|
|--------------|--------|
|
|
54
|
-
| < 10%
|
|
55
|
-
| 10-30%
|
|
56
|
-
| > 30%
|
|
54
|
+
| < 10% (< ~20k tokens) | Too small — combine with a related task |
|
|
55
|
+
| 10-30% (~20-60k tokens) | Right size — proceed |
|
|
56
|
+
| > 30% (> ~60k tokens) | Too large — split into two tasks |
|
|
57
57
|
|
|
58
58
|
**Context cost signals (use these, not time estimates):**
|
|
59
|
-
- Files modified: 0-3 = ~
|
|
60
|
-
- New subsystem: ~
|
|
61
|
-
- Migration + data transform: ~
|
|
62
|
-
- Pure config/wiring: ~
|
|
59
|
+
- Files modified: 0-3 = ~20-30k tokens, 4-6 = ~40-60k, 7+ = ~80k+ (split the task)
|
|
60
|
+
- New subsystem: ~50-70k tokens
|
|
61
|
+
- Migration + data transform: ~60-80k tokens
|
|
62
|
+
- Pure config/wiring: ~10-20k tokens
|
|
63
|
+
- A plan's `context_estimate` is the sum of its task estimates.
|
|
63
64
|
|
|
64
65
|
**Too large signals:** Touches >3-5 files, multiple distinct chunks, action section >1 paragraph.
|
|
65
66
|
|
|
@@ -125,11 +126,13 @@ No overlap → can run parallel. File in multiple plans → later plan depends o
|
|
|
125
126
|
|
|
126
127
|
The resolved granularity is provided in the planning context as `**Granularity:** <value>`. Read that value and apply the corresponding row below. When no explicit value is present, default to Standard.
|
|
127
128
|
|
|
128
|
-
| Granularity | Typical Plans/Phase |
|
|
129
|
-
|
|
130
|
-
| Coarse | 1-3 |
|
|
131
|
-
| Standard | 3-5 |
|
|
132
|
-
| Fine | 5-10 |
|
|
129
|
+
| Granularity | Typical Plans/Phase |
|
|
130
|
+
|-------------|---------------------|
|
|
131
|
+
| Coarse | 1-3 |
|
|
132
|
+
| Standard | 3-5 |
|
|
133
|
+
| Fine | 5-10 |
|
|
134
|
+
|
|
135
|
+
Plans/Phase is typical for phases with several independent subsystems. Granularity never splits serial single-concern work: such a phase is 1-2 plans at every granularity.
|
|
133
136
|
|
|
134
137
|
Derive plans from actual work. Granularity determines compression tolerance, not a target.
|
|
135
138
|
|
|
@@ -36,7 +36,7 @@ Group by plan, dimension, severity.
|
|
|
36
36
|
| task_completeness | Add missing elements to existing task |
|
|
37
37
|
| dependency_correctness | Fix depends_on, recompute waves |
|
|
38
38
|
| key_links_planned | Add wiring task or update action |
|
|
39
|
-
| scope_sanity | Split
|
|
39
|
+
| scope_sanity | Over the 6-task ceiling or `plan_budget_tokens` (`over_ceiling` / `over_budget`): split the unexecuted plan; an executed plan (`has_summary` true) is reported only. Flagged serial split (`unjustified_splits`): merge the pair (planner-antipatterns.md "Plan-Split Anti-Patterns"). Serial pair without an estimate (`unestimated_serial`): add `context_estimate` (an `unparseable_estimate` value: rewrite as a bare integer or `60k`), then merge or keep the split as the check reports |
|
|
40
40
|
| must_haves_derivation | Derive and add must_haves to frontmatter |
|
|
41
41
|
|
|
42
42
|
### Step 4: Make Targeted Updates
|
|
@@ -236,7 +236,7 @@ Generated from `CONFIG_DEFAULTS` (configuration.cjs) and `VALID_CONFIG_KEYS` (co
|
|
|
236
236
|
| `phase_naming` | string | `"sequential"` | `"sequential"`, `"custom"` | Phase numbering: auto-increment or arbitrary string IDs |
|
|
237
237
|
| `project_code` | string\|null | `null` | Any short string | Prefix for phase dirs (e.g., `"CK"` produces `CK-01-foundation`) |
|
|
238
238
|
| `response_language` | string\|null | `null` | Any language name | Language for user-facing prompts (e.g., `"Portuguese"`, `"Japanese"`) |
|
|
239
|
-
| `context_window` | number | `200000` | `200000`, `1000000` | Context window size; set `1000000` for 1M-context models |
|
|
239
|
+
| `context_window` | number | `200000` | `200000`, `1000000` | Context window size; set `1000000` for 1M-context models. Also sets the per-plan budget (`plan_budget_tokens` = 50% of the window), which the planner sizes plans to and `check plan-sizing` reads |
|
|
240
240
|
| `resolve_model_ids` | boolean\|string | `false` | `false`, `true`, `"omit"` | Map model aliases to full Claude IDs; `"omit"` returns empty string |
|
|
241
241
|
| `context` | string\|null | `null` | `"dev"`, `"research"`, `"review"` | Execution context profile that adjusts agent behavior: `"dev"` for development tasks, `"research"` for investigation/exploration, `"review"` for code review workflows |
|
|
242
242
|
| `review.models.<cli>` | string\|null | `null` | Any model ID string | Per-CLI model override for /pp:review (e.g., `review.models.gemini`). Falls back to CLI default when null. |
|
|
@@ -268,7 +268,8 @@ Set via `workflow.*` namespace in config.json (e.g., `"workflow": { "research":
|
|
|
268
268
|
| `workflow.build_command` | string\|null | `null` | Any shell command | Build gate command run by the post-merge gate. Unset → build step auto-detected/skipped. |
|
|
269
269
|
| `workflow.inline_plan_threshold` | number | `2` | `0`–`10` | Plans with ≤N tasks execute inline instead of spawning a subagent |
|
|
270
270
|
| `workflow.code_review` | boolean | `true` | `true`, `false` | Enable built-in code review step in the ship workflow |
|
|
271
|
-
| `workflow.code_review_depth` | string | `"standard"` | `"
|
|
271
|
+
| `workflow.code_review_depth` | string | `"standard"` | `"quick"`, `"standard"`, `"deep"` | Depth level for code review analysis in the ship workflow |
|
|
272
|
+
| `workflow.ceremony` | string | `"proportional"` | `"proportional"`, `"full"` | `proportional` classifies each phase at plan-phase time and skips gates the verdict does not need; `full` runs the whole gate stack as before. Override per phase with `--full` or a `**Ceremony:** full` ROADMAP line. See references/ceremony.md |
|
|
272
273
|
| `workflow._auto_chain_active` | boolean | `false` | `true`, `false` | Internal: tracks whether autonomous chaining is active |
|
|
273
274
|
| `workflow.security_enforcement` | boolean | `true` | `true`, `false` | Enable threat-model-anchored security verification via `/pp:secure-phase`. When `false`, security checks are skipped entirely |
|
|
274
275
|
| `workflow.security_asvs_level` | number | `1` | `1`, `2`, `3` | OWASP ASVS verification level. Level 1 = opportunistic, Level 2 = standard, Level 3 = comprehensive |
|