@pareto4/pp-core 1.21.1 → 1.22.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/gemini-extension.json +1 -1
- package/package.json +2 -2
- package/pp-core/bin/lib/discovery-flow-page.cjs +191 -0
- package/pp-core/bin/lib/discovery-for-phase.cjs +33 -5
- package/pp-core/bin/lib/discovery-processes.cjs +97 -4
- package/pp-core/bin/lib/discovery-stories.cjs +36 -5
- package/pp-core/bin/lib/discovery-tests.cjs +398 -0
- package/pp-core/bin/lib/io.cjs +5 -0
- package/pp-core/bin/pp-tools.cjs +25 -1
- package/pp-core/references/discovery-build-consumption.md +5 -2
- package/pp-core/references/discovery-id-conventions.md +1 -1
- package/pp-core/references/discovery-processes.md +31 -7
- package/pp-core/references/discovery-session-output.md +1 -1
- package/pp-core/references/discovery-tests.md +186 -0
- package/pp-core/workflows/discovery-sprint/session-13-gates.md +2 -0
- package/pp-core/workflows/discovery-sprint/sessions/03-to-be.md +135 -76
- package/pp-core/workflows/discovery-sprint/sessions/09-qa.md +94 -64
- package/pp-core/workflows/discovery-sprint/sessions/13-wrap-up.md +2 -1
- package/pp-core/workflows/discovery-sprint.md +2 -2
- package/pp-core/workflows/discovery-to-build/steps/handoff-gates.md +16 -9
- package/pp-core/workflows/discovery-to-build/templates/discovery-references.md +1 -1
- package/pp-core/workflows/discovery-to-build/templates/pp-handoff.md +9 -1
- package/pp-core/workflows/discovery-to-build.md +2 -2
- package/pp-core/workflows/discuss-phase/discovery.md +2 -2
- package/scripts/run-tests.cjs +9 -6
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
# Discovery Tests — Template & Parser Contract
|
|
2
|
+
|
|
3
|
+
Single home for `_tests.md`, the register Session 9 writes: which main processes get an end-to-end
|
|
4
|
+
test and why (a risk analysis per `MP-` process), which parts of the solution get extra test
|
|
5
|
+
attention because they are complex, and the testability review of every user story. The build reads
|
|
6
|
+
it by requirement ID; `pp_run query discovery.tests-check` is its gate. This file is Read lazily; it
|
|
7
|
+
is never `@`-imported.
|
|
8
|
+
|
|
9
|
+
## Why the register exists
|
|
10
|
+
|
|
11
|
+
In this delivery the agents write the tests — first, from the acceptance criteria — and run the same
|
|
12
|
+
checks on every change. What the agents cannot decide is *where the risk is*: which processes would
|
|
13
|
+
hurt most if they broke, which components are hard enough that ordinary tests will miss their
|
|
14
|
+
failures, and whether a story's acceptance criteria can be tested at all. Those are the test
|
|
15
|
+
manager's calls, made in Session 9 with the product owner and the architect. The register records
|
|
16
|
+
them in a form the build can act on: the planner adds the end-to-end tests and the extra test work,
|
|
17
|
+
and the verifier knows which role and which data each story is accepted with.
|
|
18
|
+
|
|
19
|
+
## When the file appears
|
|
20
|
+
|
|
21
|
+
| Session | `_tests.md` |
|
|
22
|
+
|---|---|
|
|
23
|
+
| 9 | created from the template; topic 2 fills `## Acceptance`, topic 3 `## Process risk`, topic 4 `## Focus areas`; `tests-check` in the session |
|
|
24
|
+
| 13 | `tests-check` in the Step 0 gates (reporting) |
|
|
25
|
+
| handoff | `tests-check --require-complete` hard-blocks |
|
|
26
|
+
|
|
27
|
+
Session 9's **Test Approach**, **Test Environment Plan**, **Quality Gates** and **UAT Process** stay
|
|
28
|
+
in `session-09.md`: they are decisions for the whole product, not rows the build selects per phase.
|
|
29
|
+
|
|
30
|
+
## Shared grammar
|
|
31
|
+
|
|
32
|
+
- **Rows are keyed by the ID they assess** — an `MP-nn`, a `US-nn`, a subject ID. `_tests.md` mints
|
|
33
|
+
no IDs of its own, so it reserves no prefix.
|
|
34
|
+
- **`—` is a pending cell**, allowed until the session that owns it runs.
|
|
35
|
+
- **Requirements** cites `_requirements.md` IDs, comma-separated.
|
|
36
|
+
- **Roles** are names from `_roles.md` § Roles, spelled the same, comma-separated.
|
|
37
|
+
- **A change after sign-off edits the row in place** and appends `→ amended by D-<ss>-<n>`
|
|
38
|
+
(`references/discovery-id-conventions.md` § Precedence).
|
|
39
|
+
|
|
40
|
+
## Risk rating
|
|
41
|
+
|
|
42
|
+
`Impact` and `Likelihood` are each `high`, `medium` or `low`; `Risk` follows from them and nothing
|
|
43
|
+
else:
|
|
44
|
+
|
|
45
|
+
| Impact ↓ · Likelihood → | low | medium | high |
|
|
46
|
+
|---|---|---|---|
|
|
47
|
+
| **high** | medium | high | high |
|
|
48
|
+
| **medium** | low | medium | high |
|
|
49
|
+
| **low** | low | low | medium |
|
|
50
|
+
|
|
51
|
+
- **Impact** — what breaks for the business when this process fails in production: money, legal or
|
|
52
|
+
regulatory exposure, customers affected, data that cannot be repaired. Session 2's `Criticality` of
|
|
53
|
+
the as-is processes a main process replaces is the first evidence; Session 6's classification of
|
|
54
|
+
the entities it touches (`Confidential`, `Restricted`) the second.
|
|
55
|
+
- **Likelihood** — how likely the process is to break: new rather than replaced, many steps, several
|
|
56
|
+
interfaces (`IF-` in its step matrix), several business rules, new technology, a migration feeding
|
|
57
|
+
it, exception paths nobody has run before.
|
|
58
|
+
|
|
59
|
+
A `high` risk process gets an end-to-end test. Choosing not to is allowed only as a decision: the
|
|
60
|
+
`Rationale` cites the `D-09-<n>` Key Decision that records why. A process without an end-to-end test
|
|
61
|
+
is still covered — step by step, by the tests the build writes from the acceptance criteria; the
|
|
62
|
+
end-to-end test proves the steps work *together*, across roles, screens, rules and interfaces.
|
|
63
|
+
|
|
64
|
+
## `_tests.md`
|
|
65
|
+
|
|
66
|
+
Illustration only — not part of the template, names invented:
|
|
67
|
+
|
|
68
|
+
| Process | Impact | Likelihood | Risk | End-to-end | Roles | Test data | Rationale |
|
|
69
|
+
|---|---|---|---|---|---|---|---|
|
|
70
|
+
| MP-01 | high | medium | high | yes | Requester, Approver | Three orders: under, at and over the approval limit | Invoices go to customers; replaces a critical process (PRC-02) |
|
|
71
|
+
| MP-02 | low | low | low | no | — | — | Read-only report; covered by step tests |
|
|
72
|
+
|
|
73
|
+
| Subject | Complexity | Extra testing | Requirements |
|
|
74
|
+
|---|---|---|---|
|
|
75
|
+
| BR-04 | Tariff rule with 14 branches across three customer types | One test per row of the rule's decision table; boundary values on every threshold | K-12, K-13 |
|
|
76
|
+
| IF-02 | Asynchronous, at-least-once, messages may arrive out of order | Contract test against the provider's schema; duplicate and out-of-order delivery tests | K-20 |
|
|
77
|
+
|
|
78
|
+
| Story | Testable | Role | Test data |
|
|
79
|
+
|---|---|---|---|
|
|
80
|
+
| US-01 | yes | Requester | An open order under the approval limit |
|
|
81
|
+
| US-02 | amended (D-09-2) | Approver | An order exactly at the limit |
|
|
82
|
+
| US-03 | open (A-09-1) | Finance | — |
|
|
83
|
+
|
|
84
|
+
Bootstrap template — Session 9 copies it verbatim to `.planning/discovery/_tests.md`, replacing
|
|
85
|
+
`[PROJECT_NAME]`:
|
|
86
|
+
|
|
87
|
+
```markdown
|
|
88
|
+
# Tests — [PROJECT_NAME]
|
|
89
|
+
|
|
90
|
+
**Conventions:** pp-core reference `references/discovery-tests.md`. `## Process risk` holds one row per `MP-` main process of `_processes.md` § To-be: impact, likelihood, the risk they give, and whether the process gets an end-to-end test. `## Focus areas` holds the parts of the solution that get extra test attention because they are complex. `## Acceptance` holds the testability review of every `US-` story of `_stories.md`. A change after sign-off edits the row in place and appends `→ amended by D-<ss>-<n>`.
|
|
91
|
+
|
|
92
|
+
## Process risk
|
|
93
|
+
|
|
94
|
+
| Process | Impact | Likelihood | Risk | End-to-end | Roles | Test data | Rationale |
|
|
95
|
+
|---------|--------|------------|------|------------|-------|-----------|-----------|
|
|
96
|
+
|
|
97
|
+
## Focus areas
|
|
98
|
+
|
|
99
|
+
| Subject | Complexity | Extra testing | Requirements |
|
|
100
|
+
|---------|------------|---------------|--------------|
|
|
101
|
+
|
|
102
|
+
## Acceptance
|
|
103
|
+
|
|
104
|
+
| Story | Testable | Role | Test data |
|
|
105
|
+
|-------|----------|------|-----------|
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Cells
|
|
109
|
+
|
|
110
|
+
**Process risk**
|
|
111
|
+
|
|
112
|
+
- `Process` — an `MP-nn` of `_processes.md` § To-be. Every main process has exactly one row.
|
|
113
|
+
- `End-to-end` — `yes` or `no`.
|
|
114
|
+
- `Roles`, `Test data` — required when `End-to-end` is `yes`: the roles the test walks the process
|
|
115
|
+
as, and the data it needs (synthetic, seeded, anonymised — never a production copy unless Session
|
|
116
|
+
6 allows it). `—` when `no`.
|
|
117
|
+
- `Rationale` — why this rating; the evidence, in a line.
|
|
118
|
+
|
|
119
|
+
**Focus areas** — a part of the solution whose failures ordinary step tests are likely to miss.
|
|
120
|
+
Not every engagement has one; an empty table is a valid answer only when the session wrote that down
|
|
121
|
+
(`None identified in Discovery.` under the session's **Focus Areas** heading).
|
|
122
|
+
|
|
123
|
+
- `Subject` — one of: a component `C-nn` of Session 5's **Component Inventory**, an interface
|
|
124
|
+
`IF-nn` of `_integrations.md`, a business rule `BR-nn` of `_rules.md`, a migration row `MG-nn` of
|
|
125
|
+
`_migration.md`, or an entity of `_entities.md` (PascalCase, spelled the same). One row per
|
|
126
|
+
subject.
|
|
127
|
+
- `Complexity` — what makes it hard: branches, state, concurrency, timing, money, volume, an
|
|
128
|
+
external party, data that cannot be repaired.
|
|
129
|
+
- `Extra testing` — what the build does beyond the step tests, concretely enough to plan: a test per
|
|
130
|
+
row of a decision table, boundary values, property-based tests, contract tests, duplicate and
|
|
131
|
+
out-of-order delivery, reconciliation counts on a migration rehearsal, a load test with a number,
|
|
132
|
+
a security test against a named threat.
|
|
133
|
+
- `Requirements` — the requirements the subject realises; `—` until known, required at the handoff.
|
|
134
|
+
|
|
135
|
+
**Acceptance** — the testability review: can the build's verifier, reading a story's acceptance
|
|
136
|
+
criteria verbatim, tell pass from fail?
|
|
137
|
+
|
|
138
|
+
- `Story` — a `US-nn` of `_stories.md`. Every story has exactly one row.
|
|
139
|
+
- `Testable` — `yes` (the criteria name an observable outcome); `amended (D-09-<n>)` (the room
|
|
140
|
+
rewrote the criteria in `_stories.md`, with `→ amended by D-09-<n>` in the cell); or
|
|
141
|
+
`open (A-09-<n>)` (an action owns the rewrite — the handoff refuses it).
|
|
142
|
+
- `Role` — the role the story is accepted as.
|
|
143
|
+
- `Test data` — the data the story is accepted with; `—` only for a story that needs none.
|
|
144
|
+
|
|
145
|
+
### Parser contract — `pp_run query discovery.tests-check [--require-complete]`
|
|
146
|
+
|
|
147
|
+
No positional path. Faults name the artifact, the 1-based line, a validated ID, a section or column
|
|
148
|
+
name and the reason code — never cell prose. Absent `_tests.md` → exit 0, `present: false`.
|
|
149
|
+
|
|
150
|
+
| Cell / field | Grammar | Fault when violated |
|
|
151
|
+
|---|---|---|
|
|
152
|
+
| `## Process risk`, `## Focus areas`, `## Acceptance` | each once as a `##` heading holding one table with the template's columns | `missing_section`, `bad_table_shape` naming the section |
|
|
153
|
+
| Process risk `Process` | `MP-\d{2}`, once per process, present in `_processes.md` § To-be when it is on file | `bad_process`, `duplicate_process`, `unknown_process` |
|
|
154
|
+
| every To-be main process | has a Process risk row | `process_not_assessed` naming the MP |
|
|
155
|
+
| `Impact`, `Likelihood`, `Risk` | `high` \| `medium` \| `low` | `bad_rating` naming the column |
|
|
156
|
+
| `Risk` | the rating the matrix gives for `Impact` and `Likelihood` | `risk_mismatch` naming the MP |
|
|
157
|
+
| `End-to-end` | `yes` \| `no` | `bad_end_to_end` |
|
|
158
|
+
| a `high` risk row with `End-to-end` `no` | `Rationale` cites a `D-09-<n>` | `high_risk_not_end_to_end` |
|
|
159
|
+
| `Roles` | when `End-to-end` is `yes`: a comma list of roles present in `_roles.md` § Roles when it is on file | `empty_cell (Roles)`, `unknown_role` |
|
|
160
|
+
| `Test data` (Process risk) | non-empty when `End-to-end` is `yes` | `empty_cell (Test data)` |
|
|
161
|
+
| `Rationale` | non-empty | `empty_cell (Rationale)` |
|
|
162
|
+
| Focus areas `Subject` | `C-\d{2}`, `IF-\d{2}`, `BR-\d{2}`, `MG-\d{2}` or a PascalCase entity, once each; resolved against its source when that source is on file | `bad_subject`, `duplicate_subject`, `unknown_subject` |
|
|
163
|
+
| `Complexity`, `Extra testing` | non-empty | `empty_cell` naming the column |
|
|
164
|
+
| Focus areas `Requirements` | `—` (uncited), or a comma list of requirement IDs each present in `_requirements.md` when on file and parseable | `unknown_requirement_id`; `uncited_focus` under `--require-complete` only |
|
|
165
|
+
| Acceptance `Story` | `US-\d{2}`, once per story, present in `_stories.md` when it is on file | `bad_story`, `duplicate_story`, `unknown_story` |
|
|
166
|
+
| every story of `_stories.md` | has an Acceptance row | `story_not_reviewed` naming the US |
|
|
167
|
+
| `Testable` | `yes` \| `amended (D-09-<n>)` \| `open (A-09-<n>)` | `bad_testable`; `story_not_testable` for `open` under `--require-complete` only |
|
|
168
|
+
| Acceptance `Role` | one role present in `_roles.md` § Roles when it is on file | `empty_cell (Role)`, `unknown_role` |
|
|
169
|
+
| Acceptance `Test data` | non-empty (`—` allowed) | `empty_cell (Test data)` |
|
|
170
|
+
| `_requirements.md` present but unparseable | the rollup grammar is owned by `discovery rollup` | `requirements_unparseable`, once |
|
|
171
|
+
| a source present but unreadable | present-and-readable | `artifact_unreadable` naming the path |
|
|
172
|
+
|
|
173
|
+
**Exit identity.** `discovery_tests_check_failed` for structural faults; `discovery_tests_incomplete`
|
|
174
|
+
when every fault was raised by `--require-complete`. Payload: `ok`, `present`, `file`, `processes`,
|
|
175
|
+
`end_to_end`, `focus_areas`, `stories`, `open_stories`, `uncited`.
|
|
176
|
+
|
|
177
|
+
## How the build reads it
|
|
178
|
+
|
|
179
|
+
`discovery for-phase <N>` extracts, for the phase's requirements:
|
|
180
|
+
|
|
181
|
+
- the **Process risk** rows of the main processes whose steps cite one of them — the planner adds an
|
|
182
|
+
end-to-end test task for each `yes` row, walking the roles with the test data named;
|
|
183
|
+
- the **Focus areas** rows citing one of them — the planner turns `Extra testing` into tasks, the
|
|
184
|
+
verifier checks they ran;
|
|
185
|
+
- the **Acceptance** rows of the stories citing one of them — the verifier accepts each story as the
|
|
186
|
+
role, with the data, the row names.
|
|
@@ -25,6 +25,8 @@ documented absent-artifact arm — before the cross-reference analysis begins.
|
|
|
25
25
|
|
|
26
26
|
**Standards-first gates (roles, integrations, migration, deviations):** run `pp_run query discovery.roles-check`, `pp_run query discovery.integrations-check`, `pp_run query discovery.migration-check` and `pp_run query discovery.deviations-check`. Each exits 0 → proceed. Non-zero → a section or table header is off the template, a role is listed twice or is neither a Session 2 persona, a step-matrix actor nor `System`, a permission or screen row names an unknown role, entity, screen or requirement, an operation is not a lowercase verb, an `IF-`/`MG-`/`DEV-` ID is malformed, repeated or leaves a hole, a direction, required flag, reversibility or status is outside its vocabulary, a contract or error row names an interface that does not exist, a step matrix cites an `IF-` the register lacks, a migration source is not in the Systems Landscape, a deviation cites no `[vault: <path>]` or one the cache does not hold, names an approver the Session 1 Approval Matrix lacks, or is approved or rejected without a decision — fix the named rows in the artifact and re-run. These gates report: an uncited interface or migration row and a hard deviation still `Proposed` are not faults here; the handoff adds `--require-cited` and `--require-approved` and hard-blocks on them. An artifact that does not exist exits 0 by itself. Fault vocabularies: `references/discovery-access.md`, `references/discovery-integrations.md`, `references/discovery-standards.md`.
|
|
27
27
|
|
|
28
|
+
**Test-register gate (Session 9):** run `pp_run query discovery.tests-check`. Exit 0 → proceed. Non-zero → a section or table header of `_tests.md` is off the template, a main process of `_processes.md` § To-be has no risk row or two, a rating is outside `high`/`medium`/`low`, a risk does not follow from its impact and likelihood by the matrix, a high-risk process has no end-to-end test and no `D-09-<n>` saying why, an end-to-end row names no role, an unknown role or no test data, a focus-area subject is malformed, repeated or unknown to its source, a story of `_stories.md` has no acceptance row or two, a `Testable` cell is outside `yes`/`amended (D-09-<n>)`/`open (A-09-<n>)`, or a cited requirement does not exist — fix the named rows and re-run. The gate reports: an `open` story and a focus area without requirements are not faults here; the handoff adds `--require-complete` and hard-blocks on them, so close their actions before the charter is signed. An artifact that does not exist exits 0 by itself. Fault vocabulary: `references/discovery-tests.md`.
|
|
29
|
+
|
|
28
30
|
**Session-output gate (review F-6):** run `pp_run query discovery.session-check --all`. Exit 0 → proceed. Non-zero → a Notes Template section of a completed session is missing, repeated, off its template columns or empty: fill it in that session file from the session's notes, or write `None identified in Discovery.` under its title, then re-run (`references/discovery-session-output.md`). A session whose `completeness_score` reads 100 while this gate names it empty was scored on the conversation, not the output — correct the score.
|
|
29
31
|
|
|
30
32
|
**Build-consumption gates (stories, phase plan, extract):** run `pp_run query discovery.stories-check`, `pp_run query discovery.phases-check` and `pp_run query discovery.for-phase 1 --markdown >/dev/null`. Each exits 0 → proceed. Non-zero → a `US-` or phase number is malformed, repeated or leaves a hole, a story names no `E-nn` EPIC, cites no requirement or one that does not exist, has an empty story or acceptance-criteria cell or a source step that is neither `—` nor an existing `MP-nn #k`, an MVP domain requirement has no story, a phase has no goal, no success criteria or no requirement, plans a dropped requirement or one another phase also plans, depends on a later or missing phase, an MVP requirement belongs to no phase, or an artifact the extract reads has a section or header off its template — fix the named rows and re-run. These gates report; the handoff hard-blocks on `stories-check` and `phases-check`. An artifact that does not exist exits 0 by itself; the extract smoke renders empty, exit 0, when no phase plan or roadmap names Phase 1. Fault vocabulary: `references/discovery-build-consumption.md`.
|
|
@@ -5,47 +5,49 @@
|
|
|
5
5
|
|
|
6
6
|
### Session 3: Business Requirements & Future State (To-Be)
|
|
7
7
|
|
|
8
|
-
**Goal:**
|
|
8
|
+
**Goal:** Agree what the application is for, identify every process it supports, refine each process step by step — sub-processes, a swimlane diagram iterated with the room, a step matrix — until the processes cover the whole application, then derive the requirements, business rules and user stories from those steps.
|
|
9
9
|
|
|
10
10
|
**Special Protocol — Process-First (required for Session 3):**
|
|
11
|
-
This session uses the **Session 3: Process-First Protocol** (Steps 5A–5G, at the end of this file).
|
|
11
|
+
This session uses the **Session 3: Process-First Protocol** (Steps 5A–5G, at the end of this file). It starts from the application's goal, inventories every process the application supports, and refines one process at a time; requirements and stories are derived from validated steps (not collected from a blank template).
|
|
12
12
|
|
|
13
13
|
**What We Cover:**
|
|
14
14
|
|
|
15
|
-
1. **
|
|
16
|
-
*Why it matters:
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
- What is the expected ROI or business case?
|
|
20
|
-
- Are there specific targets (e.g., reduce processing time by 50%)?
|
|
15
|
+
1. **Application goal and business objectives**
|
|
16
|
+
*Why it matters: the goal is the yardstick for the process inventory — a process that serves no part of it is out of scope, a part of it no process serves is a gap. Skip when: never; with Session 1's vision on file this is a confirmation.*
|
|
17
|
+
- In one or two sentences: what is this application for, and for whom?
|
|
18
|
+
- What are the measurable business outcomes it must achieve, and how will we measure them (KPIs, targets)?
|
|
21
19
|
- **Glossary sweep:** for every concept named so far — entities, roles, statuses, documents — confirm the one term the requirements will use and add or complete its `.planning/discovery/_glossary.md` row (definition, synonyms under `Do not use`, source). A term with two spellings is a Session 13 cross-reference finding
|
|
22
20
|
|
|
23
|
-
2. **
|
|
24
|
-
*Why it matters:
|
|
25
|
-
-
|
|
26
|
-
-
|
|
27
|
-
-
|
|
28
|
-
- What is the target go-live date for MVP? [needs-business-input]
|
|
21
|
+
2. **Process inventory — every process the application supports**
|
|
22
|
+
*Why it matters: what is not in a process is not in the stories, the requirements, the tests or the build. The inventory is complete when every user, every piece of data and every connection has a process that handles it. Skip when: never.*
|
|
23
|
+
- Starting from the goal and Session 2's as-is processes: which business processes does the application run?
|
|
24
|
+
- Then sweep for the processes a business view forgets: user and role management, onboarding and set-up, configuration and reference data, notifications, scheduled and batch jobs, reporting and exports, archiving and deletion, incoming and outgoing integrations.
|
|
25
|
+
- Check coverage: does every persona have a process, does every entity have a process that creates it and one that ends its life, does every external system have a process that uses it?
|
|
29
26
|
|
|
30
|
-
3. **
|
|
31
|
-
*Why it matters:
|
|
32
|
-
-
|
|
33
|
-
-
|
|
34
|
-
-
|
|
27
|
+
3. **Process refinement — one process at a time**
|
|
28
|
+
*Why it matters: a process the room has walked step by step, on a diagram, is a process the build can implement and the testers can test end to end. Skip when: never — every main process is refined.*
|
|
29
|
+
- Which sub-processes does it consist of, and which steps make up each one?
|
|
30
|
+
- Who does each step — which persona, or the system? What happens when a step cannot complete?
|
|
31
|
+
- Walk the swimlane diagram with the room and change it until they recognise their work in it.
|
|
35
32
|
|
|
36
|
-
4. **
|
|
37
|
-
*Why it matters: acceptance criteria are what QA (Session 9) and UAT (Session 13) will test against. Skip when: only doing high-level EPIC planning this round, not story-level detail.*
|
|
38
|
-
- For highest-priority EPICs, what are the key user stories?
|
|
39
|
-
- What does "done" look like for each story (acceptance criteria)?
|
|
40
|
-
- Are there edge cases or exception flows to account for?
|
|
41
|
-
|
|
42
|
-
5. **Functional requirements** (derived from step matrices)
|
|
33
|
+
4. **Functional requirements and business rules** (derived from the step matrices)
|
|
43
34
|
*Why it matters: functional requirements are the direct input to architecture (Session 5) and QA planning (Session 9). Skip when: requirements are already captured in a separate BRD to reference.*
|
|
44
|
-
- What specific functions must the system perform?
|
|
35
|
+
- What specific functions must the system perform at each step?
|
|
45
36
|
- What calculations, transformations, or business logic are required? Every validation, calculation or invariant becomes a `BR-` row of `.planning/discovery/_rules.md` (Step 5D′), applied to an entity or a process, checked in a named layer, citing the requirements it realises
|
|
46
37
|
- What reporting or analytics capabilities are needed?
|
|
47
38
|
|
|
48
|
-
|
|
39
|
+
5. **EPICs, user stories and acceptance criteria** (derived from the steps)
|
|
40
|
+
*Why it matters: every story is tied to the step it came from and every step a person performs has a story, so the stories cover the processes; acceptance criteria are what QA (Session 9) and UAT (Session 13) test against. Skip when: only doing high-level EPIC planning this round, not story-level detail.*
|
|
41
|
+
- For each step a persona performs: what does that person want, and what do they observe when it is done?
|
|
42
|
+
- Are there edge cases or exception flows (the matrix's `Exception` column) that need their own criteria?
|
|
43
|
+
|
|
44
|
+
6. **MVP scope definition**
|
|
45
|
+
*Why it matters: the MVP boundary drives Session 11's build order and the go-live target date. Skip when: scope is fixed by contract and non-negotiable.*
|
|
46
|
+
- Which processes, sub-processes and steps are needed to deliver value first?
|
|
47
|
+
- What can be deferred to a later release without jeopardizing the business case?
|
|
48
|
+
- What is the target go-live date for MVP? [needs-business-input]
|
|
49
|
+
|
|
50
|
+
7. **Non-functional requirements**
|
|
49
51
|
*Why it matters: NFRs drive infrastructure sizing (Session 10) and architecture tradeoffs (Session 5). Skip when: standard defaults apply and the client has no unusual NFR targets.*
|
|
50
52
|
- What are the performance expectations (response time, throughput)?
|
|
51
53
|
- What availability and uptime targets apply (e.g., 99.9%)?
|
|
@@ -54,17 +56,29 @@ This session uses the **Session 3: Process-First Protocol** (Steps 5A–5G, at t
|
|
|
54
56
|
|
|
55
57
|
**Notes Template:**
|
|
56
58
|
|
|
57
|
-
**
|
|
59
|
+
**Application Goal**
|
|
60
|
+
|
|
61
|
+
The goal statement as the room agreed it, in one or two sentences, and where it differs from Session 1's business vision.
|
|
62
|
+
|
|
63
|
+
**Main Process Register** (populated via the process inventory, Step 5B)
|
|
58
64
|
|
|
59
65
|
The canonical rows live in `.planning/discovery/_processes.md` § To-be: `| ID | Main process | Replaces | Trigger | End state | Primary actor | EPICs |`, one `MP-<nn>` row per main process, **Replaces** naming the `PRC-` rows it transforms or `new`. Record here only the summary line `N main processes (MP-01 … MP-NN)` and the orphan as-is processes no main process replaces.
|
|
60
66
|
|
|
61
|
-
**
|
|
67
|
+
**Process Coverage** (populated via Step 5B, re-checked at Step 5F)
|
|
68
|
+
|
|
69
|
+
| Dimension | Item | Covered by | Notes |
|
|
70
|
+
|-----------|------|------------|-------|
|
|
71
|
+
| | | | |
|
|
62
72
|
|
|
63
|
-
One
|
|
73
|
+
One row per persona, entity, external system and scheduled job the sweep looked at: **Dimension** is `Persona`, `Entity`, `Integration` or `Scheduled job`; **Covered by** is the `MP-nn` (or `MP-nn.k`) that handles it, or `gap — D-03-<n>` when the room decided it is out of scope.
|
|
74
|
+
|
|
75
|
+
**Sub-Process Flows** (populated via Step 5C)
|
|
76
|
+
|
|
77
|
+
One swimlane per main process in `.planning/discovery/_processes.md` § Flows — a Mermaid `flowchart` with one `subgraph` per actor and every step node labelled with its `#`; its sub-processes in § Sub-processes. Record here only which flows the room changed during the iterations, and why.
|
|
64
78
|
|
|
65
79
|
**Step Matrices** (populated via Step 5C)
|
|
66
80
|
|
|
67
|
-
One
|
|
81
|
+
One combined matrix per main process in `.planning/discovery/_processes.md` § Steps, with the **Exception** column; the § Sub-processes table groups its rows, every row in exactly one sub-process (Step 5C); Requirements column back-filled at Step 5D. Record here only what the matrices cannot hold.
|
|
68
82
|
|
|
69
83
|
**Business Objectives**
|
|
70
84
|
|
|
@@ -90,7 +104,7 @@ Orphan-requirement and uncovered-step flags only — the canonical requirements
|
|
|
90
104
|
|
|
91
105
|
**User Stories** (populated via Step 5E)
|
|
92
106
|
|
|
93
|
-
One row per story in `.planning/discovery/_stories.md` § Stories — `ID | EPIC | Requirements | Story | Acceptance criteria | Source step` (`references/discovery-build-consumption.md`); the build's verifier reads the acceptance criteria from there. Record here only what the register cannot hold.
|
|
107
|
+
One row per story in `.planning/discovery/_stories.md` § Stories — `ID | EPIC | Requirements | Story | Acceptance criteria | Source step` (`references/discovery-build-consumption.md`), every story tied to its source step and every persona step covered by a story; the build's verifier reads the acceptance criteria from there. Record here only what the register cannot hold.
|
|
94
108
|
|
|
95
109
|
**Non-Functional Requirements**
|
|
96
110
|
|
|
@@ -124,61 +138,101 @@ Flows to be clickable, personas covered, and per-flow definition of "validated".
|
|
|
124
138
|
## Session 3: Process-First Protocol
|
|
125
139
|
|
|
126
140
|
**This protocol replaces the generic Step 5 topic loop for Session 3 only.**
|
|
127
|
-
|
|
141
|
+
Goal first, then the full process inventory, then one process at a time — sub-processes, swimlane, step matrix — until the processes cover the application; requirements, rules and stories are derived from the validated steps (not collected separately). `_processes.md` was created by Session 2; if it does not exist, create it from the template in `${PP_TOOLS%/bin/pp-tools.cjs}/references/discovery-processes.md` first. If it has no `## Sub-processes` section (an engagement that predates it), add the section with its table header between `## To-be` and `## Flows` now.
|
|
128
142
|
|
|
129
|
-
### Step 5A:
|
|
143
|
+
### Step 5A: Application Goal and Objectives
|
|
130
144
|
|
|
131
|
-
Read
|
|
145
|
+
Read Session 1's business vision and Session 2's pain points. Propose the application goal in one or two sentences — what the application is for and for whom — and the business objectives with a measurable KPI each:
|
|
132
146
|
|
|
133
147
|
```
|
|
134
|
-
Based on
|
|
148
|
+
Based on Sessions 1 and 2, I propose this goal for the application:
|
|
149
|
+
|
|
150
|
+
<goal statement>
|
|
135
151
|
|
|
136
|
-
|
|
|
137
|
-
|
|
138
|
-
|
|
|
152
|
+
| ID | Objective | Success Metric / KPI | Target Value | Priority |
|
|
153
|
+
|----|-----------|---------------------|--------------|----------|
|
|
154
|
+
| BO-01 | ... | ... | ... | ... |
|
|
139
155
|
|
|
140
|
-
Validate: accept / edit
|
|
156
|
+
Validate: accept / edit. The process inventory is measured against this goal.
|
|
141
157
|
```
|
|
142
158
|
|
|
143
|
-
Iterate until the
|
|
159
|
+
Iterate until the room accepts both, then fill the section titled exactly **Application Goal** and the section titled exactly **Business Objectives** in `.planning/discovery/session-03.md` — edit in place; never append a new heading. Run the glossary sweep (topic 1) before moving on.
|
|
144
160
|
|
|
145
|
-
|
|
161
|
+
### Step 5B: Process Inventory
|
|
162
|
+
|
|
163
|
+
Read `.planning/discovery/session-02.md` (its Notes Template sections), `.planning/discovery/_processes.md` § As-is and `.planning/discovery/_entities.md`. Propose **every** main process the application supports — the business processes that replace Session 2's as-is processes, and the supporting processes a business view forgets:
|
|
164
|
+
|
|
165
|
+
- user and role management, onboarding and set-up;
|
|
166
|
+
- configuration and reference data;
|
|
167
|
+
- notifications and reminders;
|
|
168
|
+
- scheduled and batch jobs (`System` as primary actor);
|
|
169
|
+
- reporting, exports and audits;
|
|
170
|
+
- archiving, retention and deletion;
|
|
171
|
+
- every incoming and outgoing exchange with another system.
|
|
146
172
|
|
|
147
|
-
### Step 5B: Decompose into Sub-Processes (per main process)
|
|
148
|
-
|
|
149
|
-
For each accepted main process, propose 3–8 sub-processes and emit a **swimlane**: a Mermaid `flowchart` with one `subgraph` per actor (a Session 2 persona or `System`), so the lane says who does each step:
|
|
150
|
-
|
|
151
|
-
```mermaid
|
|
152
|
-
flowchart LR
|
|
153
|
-
subgraph Team member
|
|
154
|
-
SP1[Sub-process 1] --> D1{Decision}
|
|
155
|
-
D1 -->|No| SP1_alt[Alternative path]
|
|
156
|
-
end
|
|
157
|
-
subgraph System
|
|
158
|
-
SP2[Sub-process 2]
|
|
159
|
-
end
|
|
160
|
-
D1 -->|Yes| SP2
|
|
161
|
-
SP2 --> End([End state])
|
|
162
173
|
```
|
|
174
|
+
For the goal "<goal>", I'm proposing these main processes:
|
|
175
|
+
|
|
176
|
+
| MP ID | Main Process | Replaces (PRC-nn or new) | Trigger | End State | Primary Actor | Serves (goal / BO-nn) |
|
|
177
|
+
|-------|--------------|--------------------------|---------|-----------|---------------|-----------------------|
|
|
178
|
+
| MP-01 | ... | ... | ... | ... | ... | ... |
|
|
163
179
|
|
|
164
|
-
|
|
180
|
+
Validate: accept / edit / add / drop.
|
|
181
|
+
```
|
|
165
182
|
|
|
166
|
-
|
|
183
|
+
Then run the **coverage sweep** with the room and fill the section titled exactly **Process Coverage** in `.planning/discovery/session-03.md` — one row per item, edit in place; never append a new heading:
|
|
167
184
|
|
|
168
|
-
|
|
185
|
+
- every persona of Session 2's User Personas table has at least one process;
|
|
186
|
+
- every entity of `_entities.md` has a process that creates it and one that ends its life (closes, archives or deletes it);
|
|
187
|
+
- every external system of Session 2's Systems Landscape that stays has a process that uses it;
|
|
188
|
+
- every recurring job the business mentioned has a process.
|
|
169
189
|
|
|
170
|
-
|
|
190
|
+
An item no process covers is either a new main process or a decision `D-03-<n>` that it is out of scope. Iterate until the room accepts the list, then write one `MP-<nn>` row per main process to `.planning/discovery/_processes.md` § To-be — **Replaces** is the comma list of `PRC-` rows from § As-is this main process transforms, or `new` — and fill the section titled exactly **Main Process Register** in `.planning/discovery/session-03.md` with the summary line — edit in place; never append a new heading. A process found later in the session is added the same way; nothing is renumbered.
|
|
171
191
|
|
|
172
|
-
|
|
173
|
-
- **Step:** one imperative verb phrase
|
|
174
|
-
- **Actor:** a persona from Session 2's User Personas table, spelled the same, or `System`; two actors are comma-separated — never a slash-joined pair or a parenthetical qualifier
|
|
175
|
-
- **UI:** screen/component, or `—` if backend-only
|
|
176
|
-
- **Data objects:** entities of the product with CRUD flags, `Task [C], Membership [C/R]`, or `—`. Every name is a row of `.planning/discovery/_entities.md` § Entities; add a missing entity there now (Source `S3`, pending cells `—`) — `entity-check` refuses a data object that is not an entity. A file, a pull request or another system's document is not a data object: it goes in **Integration** or the step text
|
|
177
|
-
- **Integration:** external systems with direction, or `—`
|
|
178
|
-
- **Exception:** what happens when the step cannot complete — the error path the build must handle — or `—` when the step cannot fail
|
|
179
|
-
- **Requirements:** `—` during 5C — back-filled with minted `_requirements.md` IDs during Step 5D consolidation
|
|
192
|
+
**Text mode fallback:** present numbered options: 1) Accept all / 2) Edit specific process / 3) Add process / 4) Drop process.
|
|
180
193
|
|
|
181
|
-
|
|
194
|
+
### Step 5C: Refine Each Process — Sub-processes, Swimlane, Steps
|
|
195
|
+
|
|
196
|
+
Take the main processes one at a time, in the order the room prefers (usually the core business process first). For each:
|
|
197
|
+
|
|
198
|
+
1. **Sub-processes.** Propose the 2–8 sub-processes it consists of, each a named stretch of work with its own outcome (`MP-01.1 Register the request`, `MP-01.2 Approve`). Even a short process has one.
|
|
199
|
+
2. **Swimlane.** Emit a Mermaid `flowchart` with one `subgraph` per actor (a Session 2 persona or `System`), so the lane says who does each step. Every step is a node whose label starts with its `#` (`01.3`); decisions and end states need none:
|
|
200
|
+
|
|
201
|
+
```mermaid
|
|
202
|
+
flowchart LR
|
|
203
|
+
subgraph Team member
|
|
204
|
+
S1["01.1 Create task"] --> D1{Complete?}
|
|
205
|
+
D1 -->|No| S2["01.2 Add missing details"]
|
|
206
|
+
S2 --> D1
|
|
207
|
+
end
|
|
208
|
+
subgraph System
|
|
209
|
+
S3["01.3 Notify assignee"]
|
|
210
|
+
end
|
|
211
|
+
D1 -->|Yes| S3
|
|
212
|
+
S3 --> End([Task assigned])
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
3. **Show it and iterate.** Write the draft under `### MP-<nn> — <name>` in `.planning/discovery/_processes.md` § Flows at once — the register holds every round, nothing is kept in the conversation only — and let the room see it drawn:
|
|
216
|
+
- **Viewing.** A terminal does not draw Mermaid. Render the process with `pp_run query discovery.flow-page MP-<nn>` — it writes `.planning/discovery/_flows/MP-<nn>.html` from the register (swimlane, sub-processes, steps). When your runtime can publish an artifact (Claude Code's Artifact tool), publish that file as a private artifact and give the room the link; after every round re-run the command and publish **the same file path** again, so the link stays the same and a refresh shows the new version. The page is generated — publish it as written, never edit it. `flow-page` renders and checks nothing, so it has no Session 13 gate; `process-check` is the check. Without an artifact tool, open `_processes.md` in a Mermaid-capable viewer (VS Code with a Mermaid preview, or GitHub).
|
|
217
|
+
- **Consent, once per engagement.** Publishing puts the client's process on claude.ai (private to the publisher until shared). Before the first publish, ask whether that is acceptable and record the answer as a Key Decision `D-03-<n>`; if not, use the local viewer. Add `.planning/discovery/_flows/` to the project's `.gitignore` — the pages are derived.
|
|
218
|
+
- **Stop for review — every round.** After publishing (or, without an artifact tool, after writing the draft), **stop and end your turn**: give the link, list the sub-processes and the open questions you have about the diagram (a missing step, a lane you were unsure of, a `No` branch with no path, a step that cannot fail), and ask the room to review it. Do not write the step matrix, do not start the next process and do not propose the next round until the user answers. Their answer is the review: free text, no menu.
|
|
219
|
+
- **Each round.** Apply exactly what the room said — a step missing, in the wrong lane, in the wrong order, a `No` branch or a failure path — by editing the draft in place; re-render, republish to the same file path, and stop again with the same review request. Expect two or three rounds for a core process. Only an explicit acceptance ("accepted", "looks right", "next") ends the loop; then continue with the step matrix below. A flowchart without a `subgraph` is refused by `process-check`.
|
|
220
|
+
4. **Step matrix.** Turn the accepted diagram into the matrix in the columns `_processes.md` § Steps fixes — one row per numbered node, written under `### MP-<nn> — <name>` in § Steps, one combined matrix per main process:
|
|
221
|
+
|
|
222
|
+
| # | Step | Actor | UI | Data objects | Integration | Exception | Requirements |
|
|
223
|
+
|
|
224
|
+
- **#:** `<mp>.<n>` — `01.3` is the third step of MP-01, the same number the diagram shows
|
|
225
|
+
- **Step:** one imperative verb phrase
|
|
226
|
+
- **Actor:** a persona from Session 2's User Personas table, spelled the same, or `System`; two actors are comma-separated — never a slash-joined pair or a parenthetical qualifier
|
|
227
|
+
- **UI:** screen/component, or `—` if backend-only
|
|
228
|
+
- **Data objects:** entities of the product with CRUD flags, `Task [C], Membership [C/R]`, or `—`. Every name is a row of `.planning/discovery/_entities.md` § Entities; add a missing entity there now (Source `S3`, pending cells `—`) — `entity-check` refuses a data object that is not an entity. A file, a pull request or another system's document is not a data object: it goes in **Integration** or the step text
|
|
229
|
+
- **Integration:** external systems with direction, or `—`
|
|
230
|
+
- **Exception:** what happens when the step cannot complete — the error path the build must handle — or `—` when the step cannot fail
|
|
231
|
+
- **Requirements:** `—` during 5C — back-filled with minted `_requirements.md` IDs during Step 5D consolidation
|
|
232
|
+
5. **Sub-process rows.** Write one row per sub-process to `.planning/discovery/_processes.md` § Sub-processes — `| MP-01.2 | Approve | 01.4, 01.5, 01.6 |` — listing its steps by `#`. Every step belongs to exactly one sub-process.
|
|
233
|
+
6. **Check the process.** Run `pp_run query discovery.process-check` — exit 0, or fix what it names before the next process: `step_not_in_flow` (a matrix row the diagram does not show — add the node or drop the row), `step_without_subprocess`, `step_in_two_subprocesses`, `subprocess_without_steps`. A data object it accepts may still be refused by `entity-check`.
|
|
234
|
+
|
|
235
|
+
After the last process, fill the section titled exactly **Sub-Process Flows** and the section titled exactly **Step Matrices** in `.planning/discovery/session-03.md` with what changed during the iterations and what the matrices cannot hold — edit in place; never append a new heading.
|
|
182
236
|
|
|
183
237
|
### Step 5D: Consolidate Requirements
|
|
184
238
|
|
|
@@ -221,19 +275,24 @@ Full grammar reference: pp-core `references/discovery-id-conventions.md` (Read l
|
|
|
221
275
|
|
|
222
276
|
Group sub-processes into EPICs (one EPIC = one main process). Fill the section titled exactly **EPIC Register** in `.planning/discovery/session-03.md` — edit in place; never append a new heading.
|
|
223
277
|
|
|
224
|
-
|
|
278
|
+
Walk the step matrices process by process and derive the user stories from the rows where the actor is a persona — every such row that realises an MVP requirement gets at least one story, and every story names the steps it came from. Mint one `US-<nn>` row per story in `.planning/discovery/_stories.md` § Stories (template and grammar: `${PP_TOOLS%/bin/pp-tools.cjs}/references/discovery-build-consumption.md` § `_stories.md`; create the file from the template when it does not exist):
|
|
225
279
|
|
|
226
280
|
| ID | EPIC | Requirements | Story | Acceptance criteria | Source step |
|
|
227
281
|
|
|
228
282
|
- **Requirements:** the `_requirements.md` IDs the story realises — every `MVP` requirement that a persona-actor step cites needs at least one story (`System`-only and `N-`/`T-` rows do not)
|
|
229
283
|
- **Acceptance criteria:** what the user observes when the story is done, written out — never a pointer such as `As in F-01`; the build's verifier reads this cell verbatim as the UAT
|
|
230
|
-
- **Source step:** the matrix rows the story came from, as `MP-nn #<cell>` with the `#` cell copied verbatim (`MP-05 #05.1`), comma-separated when a story spans two steps
|
|
284
|
+
- **Source step:** the matrix rows the story came from, as `MP-nn #<cell>` with the `#` cell copied verbatim (`MP-05 #05.1`), comma-separated when a story spans two steps — never `—`: a story no step needs points at a step the inventory missed
|
|
285
|
+
|
|
286
|
+
Then run `pp_run query discovery.stories-check` — exit 0, or fix the rows it names: `step_without_story` names a persona step no story covers, `no_source_step` a story tied to no step, `mvp_requirement_without_story` a requirement no story covers. Then fill the section titled exactly **User Stories** in `.planning/discovery/session-03.md` with only what the register cannot hold — edit in place; never append a new heading.
|
|
231
287
|
|
|
232
|
-
|
|
288
|
+
### Step 5F: Coverage Review
|
|
233
289
|
|
|
234
|
-
|
|
290
|
+
Before closing, check that the processes cover the application and the stories cover the processes:
|
|
235
291
|
|
|
236
|
-
|
|
292
|
+
1. Re-read the **Process Coverage** table against the final process list: every row names a process that exists (`MP-nn` or `MP-nn.k`) or a decision. Add a row for any persona, entity or system the session introduced after Step 5B.
|
|
293
|
+
2. Run `pp_run query discovery.process-check --require-cited`, `pp_run query discovery.stories-check` and `pp_run query discovery.rules-check` — each exits 0, or fix the rows they name.
|
|
294
|
+
3. Read the application goal once more: is there a part of it no process serves? That is a missing process (back to Step 5B) or a decision to narrow the goal.
|
|
295
|
+
4. Settle the MVP boundary (topic 6) per process and sub-process, then fill the section titled exactly **MVP Scope Boundary** in `.planning/discovery/session-03.md` — edit in place; never append a new heading.
|
|
237
296
|
|
|
238
297
|
### Step 5G: Prototype Validation Plan
|
|
239
298
|
|