@pareto4/pp-core 1.21.1 → 1.23.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/bin/install.js +205 -28
  3. package/commands/pp-help.md +2 -1
  4. package/gemini-extension.json +1 -1
  5. package/hooks/dist/pp-check-update-worker.js +1 -1
  6. package/hooks/dist/pp-context-monitor.js +3 -3
  7. package/hooks/dist/pp-statusline.js +88 -14
  8. package/hooks/dist/pp-update-banner.js +44 -4
  9. package/hooks/dist/pp-workflow-guard.js +3 -3
  10. package/hooks/pp-check-update-worker.js +1 -1
  11. package/hooks/pp-context-monitor.js +3 -3
  12. package/hooks/pp-statusline.js +88 -14
  13. package/hooks/pp-update-banner.js +44 -4
  14. package/hooks/pp-workflow-guard.js +3 -3
  15. package/package.json +2 -2
  16. package/pp-core/bin/lib/audience-command.cjs +271 -0
  17. package/pp-core/bin/lib/audience.cjs +293 -0
  18. package/pp-core/bin/lib/commands.cjs +26 -17
  19. package/pp-core/bin/lib/discovery-charter.cjs +13 -1
  20. package/pp-core/bin/lib/discovery-flow-page.cjs +191 -0
  21. package/pp-core/bin/lib/discovery-for-phase.cjs +33 -5
  22. package/pp-core/bin/lib/discovery-input-check.cjs +11 -11
  23. package/pp-core/bin/lib/discovery-processes.cjs +97 -4
  24. package/pp-core/bin/lib/discovery-session-check.cjs +7 -7
  25. package/pp-core/bin/lib/discovery-status.cjs +419 -0
  26. package/pp-core/bin/lib/discovery-stories.cjs +36 -5
  27. package/pp-core/bin/lib/discovery-tests.cjs +398 -0
  28. package/pp-core/bin/lib/explain-command.cjs +48 -0
  29. package/pp-core/bin/lib/gate-card.cjs +97 -0
  30. package/pp-core/bin/lib/hook-messages.cjs +132 -0
  31. package/pp-core/bin/lib/init-contract.cjs +116 -76
  32. package/pp-core/bin/lib/init-interactive.cjs +110 -49
  33. package/pp-core/bin/lib/init.cjs +44 -3
  34. package/pp-core/bin/lib/io.cjs +38 -0
  35. package/pp-core/bin/lib/message-labels.cjs +75 -0
  36. package/pp-core/bin/lib/messages/core.cjs +20 -0
  37. package/pp-core/bin/lib/messages/discovery.cjs +267 -0
  38. package/pp-core/bin/lib/messages/gate.cjs +257 -0
  39. package/pp-core/bin/lib/messages/hook.cjs +114 -0
  40. package/pp-core/bin/lib/messages/init.cjs +513 -0
  41. package/pp-core/bin/lib/messages/progress.cjs +110 -0
  42. package/pp-core/bin/lib/messages.cjs +208 -0
  43. package/pp-core/bin/lib/vault-command-router.cjs +16 -3
  44. package/pp-core/bin/lib/violation-render.cjs +78 -0
  45. package/pp-core/bin/pp-tools.cjs +92 -23
  46. package/pp-core/bin/shared/config-schema.manifest.json +1 -0
  47. package/pp-core/references/audience-moments.md +119 -0
  48. package/pp-core/references/audience.md +114 -0
  49. package/pp-core/references/discovery-build-consumption.md +5 -2
  50. package/pp-core/references/discovery-charter.md +2 -2
  51. package/pp-core/references/discovery-id-conventions.md +1 -1
  52. package/pp-core/references/discovery-processes.md +31 -7
  53. package/pp-core/references/discovery-session-output.md +1 -1
  54. package/pp-core/references/discovery-tests.md +186 -0
  55. package/pp-core/templates/project-charter.md +3 -4
  56. package/pp-core/workflows/add-phase.md +2 -0
  57. package/pp-core/workflows/add-tests.md +2 -0
  58. package/pp-core/workflows/add-todo.md +2 -0
  59. package/pp-core/workflows/ai-integration-phase.md +2 -0
  60. package/pp-core/workflows/audit-milestone.md +2 -0
  61. package/pp-core/workflows/autonomous.md +2 -0
  62. package/pp-core/workflows/check-todos.md +2 -0
  63. package/pp-core/workflows/code-review-fix.md +2 -0
  64. package/pp-core/workflows/code-review.md +2 -0
  65. package/pp-core/workflows/complete-milestone.md +10 -1
  66. package/pp-core/workflows/discovery-sprint/charter.md +3 -2
  67. package/pp-core/workflows/discovery-sprint/prefill.md +3 -0
  68. package/pp-core/workflows/discovery-sprint/prototype.md +14 -0
  69. package/pp-core/workflows/discovery-sprint/session-13-gates.md +2 -0
  70. package/pp-core/workflows/discovery-sprint/sessions/01-kick-off.md +4 -1
  71. package/pp-core/workflows/discovery-sprint/sessions/03-to-be.md +135 -76
  72. package/pp-core/workflows/discovery-sprint/sessions/09-qa.md +94 -64
  73. package/pp-core/workflows/discovery-sprint/sessions/13-wrap-up.md +3 -2
  74. package/pp-core/workflows/discovery-sprint/vault-context.md +15 -0
  75. package/pp-core/workflows/discovery-sprint.md +16 -2
  76. package/pp-core/workflows/discovery-to-build/steps/handoff-gates.md +16 -9
  77. package/pp-core/workflows/discovery-to-build/templates/discovery-references.md +1 -1
  78. package/pp-core/workflows/discovery-to-build/templates/pp-handoff.md +9 -1
  79. package/pp-core/workflows/discovery-to-build.md +10 -4
  80. package/pp-core/workflows/discuss-phase/discovery.md +2 -2
  81. package/pp-core/workflows/discuss-phase-assumptions.md +2 -0
  82. package/pp-core/workflows/discuss-phase.md +1 -1
  83. package/pp-core/workflows/edit-phase.md +2 -0
  84. package/pp-core/workflows/eval-review.md +2 -0
  85. package/pp-core/workflows/execute-phase/steps/check-query-gate.md +25 -1
  86. package/pp-core/workflows/execute-phase/steps/vault-fetch.md +1 -0
  87. package/pp-core/workflows/execute-phase/steps/vault-load-gate.md +2 -0
  88. package/pp-core/workflows/execute-phase.md +1 -1
  89. package/pp-core/workflows/execute-plan.md +2 -0
  90. package/pp-core/workflows/extract-learnings.md +2 -0
  91. package/pp-core/workflows/help/modes/business.md +56 -0
  92. package/pp-core/workflows/help.md +12 -2
  93. package/pp-core/workflows/import.md +10 -1
  94. package/pp-core/workflows/ingest-docs.md +2 -0
  95. package/pp-core/workflows/init.md +17 -1
  96. package/pp-core/workflows/insert-phase.md +2 -0
  97. package/pp-core/workflows/list-workspaces.md +2 -0
  98. package/pp-core/workflows/manager.md +2 -0
  99. package/pp-core/workflows/map-codebase.md +2 -0
  100. package/pp-core/workflows/milestone-summary.md +2 -0
  101. package/pp-core/workflows/new-milestone.md +10 -1
  102. package/pp-core/workflows/new-project.md +12 -2
  103. package/pp-core/workflows/new-workspace.md +2 -0
  104. package/pp-core/workflows/next.md +8 -0
  105. package/pp-core/workflows/plan-milestone-gaps.md +10 -1
  106. package/pp-core/workflows/plan-phase.md +2 -1
  107. package/pp-core/workflows/plan-review-convergence.md +1 -1
  108. package/pp-core/workflows/progress.md +10 -0
  109. package/pp-core/workflows/quick.md +11 -1
  110. package/pp-core/workflows/remove-phase.md +2 -0
  111. package/pp-core/workflows/remove-workspace.md +2 -0
  112. package/pp-core/workflows/resume-project.md +25 -0
  113. package/pp-core/workflows/review.md +2 -0
  114. package/pp-core/workflows/scan.md +2 -0
  115. package/pp-core/workflows/secure-phase.md +2 -0
  116. package/pp-core/workflows/settings.md +41 -0
  117. package/pp-core/workflows/ship.md +2 -0
  118. package/pp-core/workflows/spec-phase.md +1 -1
  119. package/pp-core/workflows/ui-phase.md +2 -0
  120. package/pp-core/workflows/ui-review.md +2 -0
  121. package/pp-core/workflows/ultraplan-phase.md +2 -0
  122. package/pp-core/workflows/validate-phase.md +2 -0
  123. package/pp-core/workflows/vault-review.md +2 -0
  124. package/pp-core/workflows/verify-phase.md +2 -0
  125. package/pp-core/workflows/verify-work.md +2 -0
  126. package/scripts/affected-tests-lib.cjs +26 -12
  127. package/scripts/ci-release-only.cjs +158 -0
  128. package/scripts/live-runs/driver.cjs +326 -0
  129. package/scripts/live-runs/run.cjs +906 -0
  130. package/scripts/live-runs/scenarios.cjs +326 -0
  131. package/scripts/live-runs/scratch-project.cjs +132 -0
  132. package/scripts/live-runs/scrub.cjs +291 -0
  133. package/scripts/live-runs/turn-guard.cjs +107 -0
  134. package/scripts/live-runs/walk-setup.cjs +198 -0
  135. package/scripts/run-tests.cjs +151 -132
  136. package/scripts/test-env.cjs +64 -0
@@ -0,0 +1,119 @@
1
+ # Audience moments
2
+
3
+ The business and engineer forms for five moments (Next Up, a stopped check, a verification result, the fallback-standards question and a confirmation before an irreversible action) plus the discovery narration rule. Read from `audience.md`'s pointer line, never `@`-included.
4
+
5
+ ## When to use this
6
+
7
+ Use a form below only when the payload (or `pp_run query audience fields`) carries `audience`; pick the section for that audience. A developer never reads this file, and a developer's text stays as it is.
8
+
9
+ Fill every `{…}` from facts you hold (the `ROADMAP.md` goal, the plan's objective, `VERIFICATION.md`, the check's own output) and never invent one. Keep commands, file names, IDs and paths in backticks, unchanged (`audience.md`, Never reword). When the CLI already printed a card (a `GATE_CARDS=` line, or the lines `vault admission --explain` printed), relay that card word for word and never compose a second one.
10
+
11
+ ## Business user forms
12
+
13
+ ### Next Up
14
+
15
+ ```
16
+ Next: {plain action}, because {reason}. Start a fresh conversation first (`/clear`) so the assistant has its full working memory, then type `{command}`.
17
+ ```
18
+
19
+ - {plain action} names the step and the plan by its name, taken from the plan's objective. Never show a plan ID.
20
+ - {reason} is one clause from that stage's `ROADMAP.md` goal or from the result just shown.
21
+ - Say "stage N of the work", never the internal word for it.
22
+ - A line that would show a command to print a report file becomes "Ask me to show the full report."
23
+ - Several options become one Next line plus "Also possible:" lines in the same shape.
24
+
25
+ ### Stopped check
26
+
27
+ `The {name} check stopped this step: {why}. What to do: {action}.`
28
+
29
+ Then `Ref: {code}`, then `Details:` followed by the check's own message exactly as printed. An advisory says the step carries on. Use the card the CLI printed; compose this shape only when none was printed (an older engine).
30
+
31
+ ### Verification result
32
+
33
+ Status line: `Done` when the report status is `passed`, `Not finished yet` for `gaps_found`, `Needs your check` for `human_needed`. Show the internal names only inside backticks.
34
+
35
+ Then three headed lists, each item one plain sentence:
36
+
37
+ - What works ({N} of {M})
38
+ - What is missing
39
+ - What needs your own test
40
+
41
+ End with the Next Up line.
42
+
43
+ ### Vault fallback question
44
+
45
+ Your organisation's own standards could not be loaded ({reason}). May the build follow the general Pareto standards instead?
46
+
47
+ Then: Type `confirmed` to go ahead. This answer is never given for the person and never assumed in an unattended run. {reason} is the plain reason, for example "the connection to your organisation's standards did not answer".
48
+
49
+ ### Irreversible action
50
+
51
+ Say the action and its target before the person answers, and keep the workflow's own way of answering: its options, or the typed name for `remove-workspace`. One row per action:
52
+
53
+ - `undo`: This will undo `{commits}`, the saved changes of `{plan name}`; they stay in the history. Then ask exactly as the workflow does, with the same options.
54
+ - `remove-workspace`: This will delete the folder `{workspace path}` and every file in it; it cannot be undone. Type `{workspace name}` to go ahead.
55
+ - `complete-milestone`: In the workflow's question, describe its "Delete without merging" option as: This will delete `{branch}`, the separate line of work for this release; use it when that work is already on the main line or not needed. Keep all of the workflow's options.
56
+ - `transition`: This will skip `{plan names}`, which are then not built in this stage of the work. Then ask exactly as the workflow does, with the same options.
57
+ - `vault-write-back`: This will write `{file}` into your organisation's standards at `{target}`, where others will see it. Then ask exactly as the workflow does, with the same options.
58
+ - `discovery-redo`: This will replace the notes of session {n} in `session-{nn}.md` and hold the session again. Then ask exactly as the workflow does, with the same options.
59
+ - `charter-redraft`: This will reopen `PROJECT-CHARTER.md` as version `{version}`; it must be signed again. Then ask exactly as the workflow does, with the same options.
60
+ - `init-compose`: This will write `.platform-bindings.json` with the answers you gave. Then ask exactly as the workflow does, with the same options.
61
+
62
+ ### Discovery narration
63
+
64
+ In a discovery session with a business user, never show file paths, internal ID counts (a tally per prefix), check codes or the `vault:` lines. Never ask them to design ID prefixes: choose the prefixes yourself from the people and areas they named and say the split in one plain sentence. Refer to a recorded item as "decision 3" or "open item 2". Keep `/pp-discovery N` commands in backticks.
65
+
66
+ ## Business engineer forms
67
+
68
+ ### Next Up
69
+
70
+ ```
71
+ Next: {plain action} (phase {N}), because {reason}. Run `/clear` first so the assistant starts with a fresh context window, then run `{command}`.
72
+ ```
73
+
74
+ - {plain action} names the step and the plan by its name from the plan's objective; never a plan ID.
75
+ - {reason} is one clause from the phase goal in `ROADMAP.md` or from the result just shown.
76
+ - Explain a real term such as "context window" once, with its line from the Explain once table in `audience.md`.
77
+ - A line that would show a command to print a report file becomes "Ask me to show the full report."
78
+ - Several options become one Next line plus "Also possible:" lines in the same shape.
79
+
80
+ ### Stopped check
81
+
82
+ `The {name} check stopped this step: {why}. What to do: {action}.`
83
+
84
+ Then `Ref: {code}`, then `Details:` followed by the check's own message exactly as printed. An advisory says the step carries on. Use the card the CLI printed, word for word; its `Ref:` line already names the query. Compose this shape only when none was printed (an older engine), and then name the check by its query, for example `vault.trace`.
85
+
86
+ ### Verification result
87
+
88
+ Status line: `Done` for `passed`, `Not finished yet` for `gaps_found` (a required outcome is missing; name the status once in backticks), `Needs your check` for `human_needed`.
89
+
90
+ Then three headed lists, each item one plain sentence:
91
+
92
+ - What works ({N} of {M})
93
+ - What is missing
94
+ - What needs your own test
95
+
96
+ End with the Next Up line.
97
+
98
+ ### Vault fallback question
99
+
100
+ Your client's standards vault could not be loaded ({reason}); the fallback tier would apply the general Pareto standards instead. Proceed with the fallback? Type `confirmed` to go ahead.
101
+
102
+ This answer is never given for the person and never assumed in an unattended run.
103
+
104
+ ### Irreversible action
105
+
106
+ Say the action and its target before the person answers, and keep the workflow's own way of answering: its options, or the typed name for `remove-workspace`. One row per action:
107
+
108
+ - `undo`: This will revert `{commits}` with `git revert`; history is kept. Then ask exactly as the workflow does, with the same options.
109
+ - `remove-workspace`: This will delete the folder `{workspace path}` and every file in it; it cannot be undone. Type `{workspace name}` to go ahead.
110
+ - `complete-milestone`: In the workflow's question, describe its "Delete without merging" option as: This will delete the branch `{branch}` of this milestone. Keep all of the workflow's options.
111
+ - `transition`: This will skip `{plan names}`; they are not built in phase {N}. Then ask exactly as the workflow does, with the same options.
112
+ - `vault-write-back`: This will write `{file}` to the repository `{repo}` at `{target}`, visible to everyone with access. Then ask exactly as the workflow does, with the same options.
113
+ - `discovery-redo`: This will overwrite the notes of session {n} in `session-{nn}.md` and run the session again. Then ask exactly as the workflow does, with the same options.
114
+ - `charter-redraft`: This will reopen `PROJECT-CHARTER.md` as version `{version}`; it must be signed again. Then ask exactly as the workflow does, with the same options.
115
+ - `init-compose`: This will write `.platform-bindings.json` with the answers you gave. Then ask exactly as the workflow does, with the same options.
116
+
117
+ ### Discovery narration
118
+
119
+ Show an ID next to its meaning ("decision D-03-2: one database"). Paths and check codes may appear in backticks. Keep `/pp-discovery N` commands in backticks.
@@ -0,0 +1,114 @@
1
+ # Audience reference
2
+
3
+ How pp-core talks to business users and business engineers. Tables below are parsed by `tests/jargon-denylist.test.cjs`; this file is the only copy of these lists.
4
+
5
+ ## When to read this
6
+
7
+ Read this file only when the `init.*` payload carries `audience` (`business` or `engineer`). The workflow's pointer line sends you here with a Read, never an `@`-include, so a developer run never loads it.
8
+
9
+ Follow the section for that audience in every message the person sees. That includes what a subagent returned: agents' own prompts stay as they are, and you reword their results when you pass them on. Reply in `response_language`. Keep everything on the Never reword list exactly as written.
10
+
11
+ At five moments, also Read `audience-moments.md` in this folder and use its form for this audience: a Next Up block, a stopped check, a verification result, the vault fallback question and a confirmation before an irreversible action. In a discovery session, follow its Discovery narration rule as well.
12
+
13
+ ## Business users
14
+
15
+ Write for someone who runs the work and decides, but does not read code.
16
+
17
+ - Short sentences. Everyday words. Say what happened, then what to do.
18
+ - Name a thing plus its number: "decision 3", "screen 7", "requirement 4". Never a bare code.
19
+ - Use the Business user column of the glossary for every internal word. Never show anything on the hide list.
20
+ - Keep the words sprint and MVP as they are.
21
+ - Steer away from version-control topics. Do not explain saving, sharing or reviewing code; say pp-core takes care of it.
22
+ - Leave out how files work inside, such as front matter or a change's hash. Say what the file or change is for.
23
+ - Show commands, file names, paths and IDs in backticks, unchanged, next to a plain description.
24
+ - When something fails, use two short sentences: what happened, what to do next.
25
+
26
+ ## Business engineers
27
+
28
+ Plain English. The person knows the technology.
29
+
30
+ - Real external terms stay as they are. Explain each once, the first time it comes up in a conversation, with its line from the Explain once table. Never replace one.
31
+ - pp-core's own words use the Business engineer column of the glossary.
32
+ - Keep a code next to its meaning: "decision D-03: use one database".
33
+ - Never show a term the hide list marks both. Terms marked business are hidden from business users only.
34
+ - Say what happened, what it means, what to do next.
35
+
36
+ ## Glossary
37
+
38
+ `(hide)` means the term is also on the hide list for that audience. `(keep)` means the word stays as it is.
39
+
40
+ | Internal term | Business user | Business engineer |
41
+ |---|---|---|
42
+ | vault | your organisation's standards | standards vault (the client's coding standards) |
43
+ | milestone | release | milestone (one release) |
44
+ | phase | stage of the work | phase |
45
+ | wave | (hide) | build round |
46
+ | worktree | (hide) | (hide) |
47
+ | agent, subagent, spawn, orchestrator | (hide) | (hide) |
48
+ | gate | the {name} check | the {name} check |
49
+ | checkpoint | needs you | needs you (check, choose or do) |
50
+ | must-haves, must_haves, truths | what must be true when this is done | required outcomes |
51
+ | gaps_found | not finished yet | missing outcome |
52
+ | verify-work | your acceptance test | UAT (you try the feature yourself) |
53
+ | drift | out of date | out of date |
54
+ | binding | platform connection | platform connection |
55
+ | slug | short name | short name (URL-safe) |
56
+ | Nyquist, Dimension 8 | (hide) | test coverage plan |
57
+ | threat model | security risks | security risks |
58
+ | model profile | (hide) | quality and cost level |
59
+ | YOLO | run on its own | run automatically |
60
+ | deviation | change from the standard | change from the plan |
61
+ | accession | document number | document number |
62
+ | artifact | document | document or output |
63
+ | entity | core data | (keep) |
64
+ | register | list | (keep) |
65
+ | persona | user profile | (keep) |
66
+ | Pre-Filled | prepared from your documents | pre-filled from documents |
67
+
68
+ ## Hide list
69
+
70
+ | Term | Hidden from |
71
+ |---|---|
72
+ | wave | business |
73
+ | worktree | both |
74
+ | agent | both |
75
+ | subagent | both |
76
+ | spawn | both |
77
+ | orchestrator | both |
78
+ | Nyquist | business |
79
+ | Dimension 8 | business |
80
+ | model profile | business |
81
+ | `.planning` | both |
82
+ | `pp_run` | both |
83
+ | Mermaid | business |
84
+
85
+ A hidden thing is not shown. If it must be shown, show it unchanged in backticks.
86
+
87
+ ## Never reword
88
+
89
+ | Kind | Examples |
90
+ |---|---|
91
+ | IDs | `D-03`, `REACH-01`, `03-02` |
92
+ | File names | `ROADMAP.md`, `session-04.md` |
93
+ | Commands | `/pp-discovery 4`, `/pp-plan-phase 3` |
94
+ | Paths | `docs/discovery/PROJECT-CHARTER.md` |
95
+ | Config keys | `workflow.research` |
96
+
97
+ ## Explain once
98
+
99
+ | Term | Aliases | One-line explanation |
100
+ |---|---|---|
101
+ | branch | — | A named line of work, kept apart from the main one until it is ready. |
102
+ | commit | — | A saved set of changes with a short note about why. |
103
+ | pull request | PR, MR, merge request | A request for others to review changes before they join the main line. |
104
+ | merge | — | Bringing the changes from one line of work into another. |
105
+ | repository | repo | The folder of project files together with its full history. |
106
+ | push | — | Sending saved changes to the shared copy of the repository. |
107
+ | SHA | commit hash, sha | The unique code that names one commit. |
108
+ | front matter | frontmatter | The settings block at the top of a document, between two `---` lines. |
109
+ | CI | continuous integration | Automatic checks that run on every change. |
110
+ | TDD | test-driven development, test-first | Writing the test first, then the code that makes it pass. |
111
+ | UAT | user acceptance test | You try the feature yourself and say whether it does what you need. |
112
+ | NFR | non-functional requirement | A quality the system must have, such as speed or security. |
113
+ | MoSCoW | — | Sorting requirements into must, should, could and won't have now. |
114
+ | ASVS | — | A security checklist with three levels of depth. |
@@ -43,6 +43,7 @@ blocked by it. The verifier takes the acceptance criteria of the extract's `_req
43
43
  | `_screens.md` § Screens, § No screen (still MVP) | screens whose `Requirements` cites one; no-screen rows keyed by one | ui-phase (exists); planner |
44
44
  | `_roles.md` § Permissions, § Roles, § Screens | the permission rows whose `Requirements` cites one; the § Roles row of every role those permissions name; the § Screens rows of those roles and of the phase's screens (`references/discovery-access.md`) | planner auth phase; forbidden-path tests |
45
45
  | `_integrations.md` § Interfaces, § Contract, § Errors | the interface rows whose `Requirements` cites one or that a selected step names in its `Integration` cell (`IF-nn`); their contract and error rows (`references/discovery-integrations.md`) | planner integration phases |
46
+ | `_tests.md` § Process risk, § Focus areas, § Acceptance | the risk rows with `End-to-end` `yes` of the main processes touched; the focus-area rows whose `Requirements` cites one; the acceptance rows of the selected stories (`references/discovery-tests.md`) | planner end-to-end and extra test tasks; verifier UAT (role and test data per story) |
46
47
  | `_migration.md`, `_deviations.md` | generic: every table carrying a `Requirements` (or `Requirement IDs`) column contributes its citing rows. A table with no requirement column is listed as *not filterable* in the extract, never silently dropped — `_deviations.md § Deviations` always is | planner migration phase; `pp-vault-review` reads `_deviations.md` whole (§ Deviations read contract) |
47
48
  | `_phases.md` § Phases | the phase's requirement IDs when ROADMAP.md has none yet | ROADMAP.md (handoff 5f, verbatim); `for-phase` |
48
49
 
@@ -69,7 +70,7 @@ table must carry a `Requirements` column; the column name is the join, not the p
69
70
  | `Requirements` | comma list of `_requirements.md` IDs (`[A-Z][A-Z0-9]*-\d+`), at least one |
70
71
  | `Story` | free text — `As a <persona>, I want <goal> so that <benefit>`; pipes escaped `\|` |
71
72
  | `Acceptance criteria` | free text, non-empty, and a criterion — never a pointer such as `As in F-01`; the verifier reads it verbatim as the UAT |
72
- | `Source step` | comma list of `MP-<nn> #<cell>` — the main process and the `#` cell of the step-matrix row the story was derived from, copied verbatim (`MP-05 #05.1`, `MP-01 #3`) — or `—` |
73
+ | `Source step` | comma list of `MP-<nn> #<cell>` — the main process and the `#` cell of the step-matrix row the story was derived from, copied verbatim (`MP-05 #05.1`, `MP-01 #3`); never `—` — a story comes from a step |
73
74
 
74
75
  ### Parser contract — `pp_run query discovery.stories-check`
75
76
 
@@ -82,7 +83,9 @@ table must carry a `Requirements` column; the column name is the join, not the p
82
83
  | `empty_cell` | `Story` or `Acceptance criteria` is empty (the cell is named) |
83
84
  | `acceptance_is_pointer` | `Acceptance criteria` starts with `As in`, `See`, `Zie` or `Idem` — a pointer, not a criterion the verifier can run |
84
85
  | `no_requirement` / `unknown_requirement_id` | no requirement cited, or one of the wrong shape or absent from `_requirements.md` (resolution skipped when that file is absent) |
85
- | `bad_source_step` / `unknown_process_id` / `unknown_process_step` | a `Source step` token is neither `—` nor `MP-nn #<cell>`; the main process is not in `_processes.md` § To-be; the step row is not in its matrix (both resolutions skipped when `_processes.md` is absent) |
86
+ | `bad_source_step` / `unknown_process_id` / `unknown_process_step` | a `Source step` token is not `MP-nn #<cell>`; the main process is not in `_processes.md` § To-be; the step row is not in its matrix (both resolutions skipped when `_processes.md` is absent) |
87
+ | `no_source_step` | `Source step` is `—` or empty — every story is tied to the step it came from |
88
+ | `step_without_story` | a step row whose actor is a persona and that cites at least one `MVP` requirement (not `N-`/`T-`) is no story's source step — the stories do not cover the process. Without a parseable `_requirements.md` every persona step needs one |
86
89
  | `mvp_requirement_without_story` | an `MVP` requirement that at least one persona-actor step row cites has no story. Mirrors Step 5E: stories come from the step rows whose actor is not `System`, so a requirement realised only by `System` steps, or cited by no step at all (engagement process rows), needs none; `N-`/`T-` rows never do. Without `_processes.md` only the prefix exemption applies |
87
90
  | `requirements_unparseable` / `artifact_unreadable` | `_requirements.md` present but failing `rollup --check`; an artifact present but unreadable |
88
91
 
@@ -63,7 +63,7 @@ Column order is fixed; column headings may be translated.
63
63
 
64
64
  1. Session 1 § Sprint Logistics, row **Charter language** — a BCP-47 code (`nl`, `en`, `nl-BE`).
65
65
  2. Else `discovery.language` in `.planning/config.json` (`pp_run query config-get discovery.language --default "" --raw`).
66
- 3. Else the language the sprint was facilitated in (Flow 2 Step 5's rule).
66
+ 3. Else English (`en`). A Dutch conversation does not make the charter Dutch; only rung 1 or 2 does.
67
67
 
68
68
  The resolved code is written to the frontmatter `language` field. `und` is the template's placeholder
69
69
  and is replaced at draft time.
@@ -100,7 +100,7 @@ fault code emitted; a rule that is **not** mechanically checked says so.
100
100
  | `_requirements.md` present but unparseable | the rollup grammar is owned by `discovery rollup` | `requirements_unparseable`, once — run `discovery rollup --check` for the detail; requirement IDs and counts are then not resolved |
101
101
  | any source under `.planning/discovery/` that exists but cannot be read | present-and-readable | `artifact_unreadable` naming the path — an unreadable source is a fault, never a silent skip |
102
102
  | `--require-signed` | `status` is `Signed` or `Signed with conditions` | `charter_unsigned`; when it is the only fault the exit identity is `discovery_charter_unsigned`, so the handoff can tell "unsigned" from "malformed" |
103
- | prose, table cells other than IDs and enums | free text in the sprint language | **not mechanically checked** — never validated, never echoed |
103
+ | prose, table cells other than IDs and enums | free text in the charter language | **not mechanically checked** — never validated, never echoed |
104
104
 
105
105
  **Posture (D-43 / D-53).** At Session 13 the check reports: an unsigned charter is not a fault, and a
106
106
  `Draft` with `Pending` is the expected state before topic 3. The hard block lives at
@@ -102,7 +102,7 @@ Non-functional requirements are not in this list: they are `N-` rows of
102
102
 
103
103
  The canonical artifacts — `_requirements.md`, `_screens.md`, `_feedback.md`, `_sweep.md`,
104
104
  `_processes.md`, `_entities.md`, `_rules.md`, `_glossary.md`, `_stories.md`, `_phases.md`,
105
- `_roles.md`, `_integrations.md`, `_migration.md`, `_deviations.md`, the research registers and
105
+ `_roles.md`, `_integrations.md`, `_migration.md`, `_deviations.md`, `_tests.md`, the research registers and
106
106
  the Project Charter — are the single source of truth for the life of the engagement, through the
107
107
  build and after it. The session files are the facilitation record behind them.
108
108
 
@@ -11,7 +11,7 @@ lazily; it is never `@`-imported.
11
11
  | Session | `_processes.md` | `_rules.md` | `_glossary.md` |
12
12
  |---|---|---|---|
13
13
  | 2 | created from the template; `## As-is` rows (`PRC-`) from topic 1 | — | created from the template; terms the client used for the same thing |
14
- | 3 | Step 5A `## To-be` rows (`MP-`, each with `Replaces`); 5B one swimlane per main process under `## Flows`; 5C one step matrix per main process under `## Steps`, `Exception` column filled; 5D back-fills `Requirements` | Step 5D′ mints `BR-` rows from the step matrices | topic 1 glossary sweep: one row per term, synonyms under `Do not use` |
14
+ | 3 | Step 5B `## To-be` rows (`MP-`, each with `Replaces`) — the full process inventory; per main process, Step 5C its swimlane under `## Flows` with every step node labelled with its `#`, its `## Sub-processes` rows (`MP-nn.k`) and its step matrix under `## Steps`, `Exception` column filled; 5D back-fills `Requirements` | Step 5D′ mints `BR-` rows from the step matrices | topic 1 glossary sweep: one row per term, synonyms under `Do not use` |
15
15
  | 8 | `process-check` and `rules-check` in the Closing Step (reporting) | | |
16
16
  | 13 | both in the Step 0 gates (reporting) | | |
17
17
  | handoff | `process-check --require-cited` and `rules-check` hard-block | | |
@@ -48,13 +48,17 @@ Illustration only — not part of the template, names invented:
48
48
  |---|---|---|---|---|---|---|---|
49
49
  | 01.1 | Create task | Team member | Task form | Task [C] | — | Title missing → form error, nothing saved | K-06 |
50
50
 
51
+ | ID | Sub-process | Steps |
52
+ |---|---|---|
53
+ | MP-01.1 | Register the request | 01.1, 01.2 |
54
+
51
55
  Bootstrap template — Session 2 copies it verbatim to `.planning/discovery/_processes.md`, replacing
52
56
  `[PROJECT_NAME]`:
53
57
 
54
58
  ```markdown
55
59
  # Processes — [PROJECT_NAME]
56
60
 
57
- **Conventions:** pp-core reference `references/discovery-processes.md`. `PRC-` rows are the as-is processes (Session 2), `MP-` rows the to-be main processes (Session 3) with the as-is processes each replaces or `new`. One swimlane and one step matrix per main process. Nothing is renumbered or deleted; a change after sign-off edits the row in place and appends `→ amended by D-<ss>-<n>`.
61
+ **Conventions:** pp-core reference `references/discovery-processes.md`. `PRC-` rows are the as-is processes (Session 2), `MP-` rows the to-be main processes (Session 3) with the as-is processes each replaces or `new`. Every main process has sub-processes `MP-nn.k`, each listing its steps by `#`; every step belongs to exactly one. One swimlane and one step matrix per main process; the swimlane labels every step node with its `#`. Nothing is renumbered or deleted; a change after sign-off edits the row in place and appends `→ amended by D-<ss>-<n>`.
58
62
 
59
63
  ## As-is
60
64
 
@@ -66,12 +70,23 @@ Bootstrap template — Session 2 copies it verbatim to `.planning/discovery/_pro
66
70
  | ID | Main process | Replaces | Trigger | End state | Primary actor | EPICs |
67
71
  |----|--------------|----------|---------|-----------|---------------|-------|
68
72
 
73
+ ## Sub-processes
74
+
75
+ | ID | Sub-process | Steps |
76
+ |----|-------------|-------|
77
+
69
78
  ## Flows
70
79
 
71
80
  ## Steps
72
81
  ```
73
82
 
74
- Under `## Flows`, Step 5B adds one `### MP-nn — <name>` heading per main process holding a swimlane:
83
+ An engagement whose `_processes.md` predates the Session 3 rework has no `## Sub-processes`
84
+ section; `process-check` then skips the sub-process and flow-coverage rules below. Adding the
85
+ section (empty) opts the engagement in.
86
+
87
+ Under `## Flows`, Step 5C adds one `### MP-nn — <name>` heading per main process holding a swimlane.
88
+ Every step node carries its matrix `#` at the start of its label, so the diagram and the matrix
89
+ describe the same steps; decisions and end states need no number:
75
90
 
76
91
  ````markdown
77
92
  ### MP-01 — Handle a task
@@ -79,12 +94,14 @@ Under `## Flows`, Step 5B adds one `### MP-nn — <name>` heading per main proce
79
94
  ```mermaid
80
95
  flowchart LR
81
96
  subgraph Team member
82
- S1[Create task] --> S2[Assign]
97
+ S1["01.1 Create task"] --> S2["01.2 Assign"]
98
+ S2 --> D1{Urgent?}
83
99
  end
84
100
  subgraph System
85
- S3[Notify assignee]
101
+ S3["01.3 Notify assignee"]
86
102
  end
87
- S2 --> S3
103
+ D1 -->|yes| S3
104
+ D1 -->|no| E1([Task queued])
88
105
  ```
89
106
  ````
90
107
 
@@ -117,6 +134,13 @@ column name and the reason code — never cell prose. Absent `_processes.md` →
117
134
  | `### MP-nn — <name>` under Flows and Steps | names a To-be row | `unknown_process` |
118
135
  | a main process without a `### MP-nn` under Flows / Steps | one swimlane and one matrix each | `flow_missing`, `steps_missing` naming the MP |
119
136
  | a flow body | a ```` ```mermaid ```` block opening with `flowchart` and holding at least one `subgraph` | `flow_not_swimlane` |
137
+ | `## Sub-processes` (optional — absent on engagements that predate it) | one table with the template's columns | `bad_table_shape (Sub-processes)` |
138
+ | Sub-processes `ID` | `MP-nn.k` — a To-be main process and `k` from 1, unique, contiguous per main process | `bad_subprocess`, `duplicate_id`, `unknown_process`, `sequence_gap` naming `MP-nn.k` |
139
+ | Sub-processes `Sub-process` | non-empty | `empty_cell (Sub-process)` |
140
+ | Sub-processes `Steps` | a comma list of `#` cells of that main process's step matrix | `subprocess_without_steps`, `unknown_step`, `step_in_two_subprocesses` naming `MP-nn #<cell>` |
141
+ | every main process, when the section is on file | at least one sub-process | `subprocess_missing` |
142
+ | every step row, when the section is on file | listed by exactly one sub-process | `step_without_subprocess` naming `MP-nn #<cell>` |
143
+ | every step row, when the section is on file | its `#` appears as a whole token in its main process's flow | `step_not_in_flow` naming `MP-nn #<cell>` |
120
144
  | step `#`, `Step` | non-empty | `empty_cell (Step)` |
121
145
  | `UI`, `Integration`, `Exception` | free text (`—` allowed) | **not mechanically checked** — the Exception column must exist, its content is the facilitator's |
122
146
  | `Data objects` | `—`, or a comma list of `Name [C/R/U/D]` tokens | `bad_data_object`; whether each name is an entity is `entity-check`'s `unknown_entity` |
@@ -126,7 +150,7 @@ column name and the reason code — never cell prose. Absent `_processes.md` →
126
150
 
127
151
  **Exit identity.** `discovery_process_check_failed` for structural faults;
128
152
  `discovery_process_steps_uncited` when every fault is an `uncited_step`. Payload: `ok`, `present`,
129
- `file`, `as_is`, `to_be`, `flows`, `steps`, `uncited`.
153
+ `file`, `as_is`, `to_be`, `flows`, `steps`, `sub_processes`, `uncited`.
130
154
 
131
155
  ## `_rules.md`
132
156
 
@@ -61,7 +61,7 @@ before setting the score; it exits 0 before a session may read 100.
61
61
 
62
62
  The session files and the registers they point at (`_requirements.md`, `_entities.md`,
63
63
  `_processes.md`, `_rules.md`, `_glossary.md`, `_screens.md`, `_roles.md`,
64
- `_integrations.md`, `_migration.md`, `_deviations.md`) are the only record of what a session
64
+ `_integrations.md`, `_migration.md`, `_deviations.md`, `_tests.md`) are the only record of what a session
65
65
  produced. Nothing is summarised into a second file at session close: later sessions read the
66
66
  earlier session's Notes Template sections (the **Context-Awareness Rules** table names
67
67
  which), the Session 13 cross-reference reads the session files, and `/pp-discovery-to-build`
@@ -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.
@@ -20,9 +20,8 @@ table columns. A section with nothing to report stays in place and says so; it i
20
20
  or renumbered. That is what lets a reader compare two charters side by side, and what lets
21
21
  `pp_run query discovery.charter-check` verify one.
22
22
 
23
- **Language.** The charter is written in the sprint language — the `Charter language` row of Session 1's
24
- Sprint Logistics, else `discovery.language` in `.planning/config.json`, else the language the sprint
25
- was facilitated in. Headings, labels and prose are translated; the `<!-- charter:<key> -->` heading
23
+ **Language.** The charter is written in the charter language — the `Charter language` row of Session 1's
24
+ Sprint Logistics, else `discovery.language` in `.planning/config.json`, else English. Headings, labels and prose are translated; the `<!-- charter:<key> -->` heading
26
25
  keys, the frontmatter fields and every enum cell (`status`, `go_no_go`, `Green / Amber / Red`,
27
26
  `Approve / Approve with conditions / Reject`, `Yes / No`) stay in English, because the check reads them.
28
27
  Column order is fixed; column headings may be translated.
@@ -273,7 +272,7 @@ source of truth; the charter only condenses them.
273
272
  Aim for a charter that reads in about fifteen minutes.
274
273
  - **Fixed shape.** Keep all 20 sections, their keys, their order and their table columns. An empty table
275
274
  stays in place with no rows, and the section's prose says `None identified in Discovery.` (in the
276
- sprint language). The **Source files** footer names only the files that exist in this engagement.
275
+ charter language). The **Source files** footer names only the files that exist in this engagement.
277
276
  - **Go / No-Go is recorded, not re-judged.** § 17 copies Session 13's assessment verbatim and the
278
277
  frontmatter `go_no_go` equals its overall recommendation; `Pending` is allowed only while `status`
279
278
  is `Draft`.
@@ -34,6 +34,8 @@ INIT=$(pp_run query init.phase-op "0")
34
34
  if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
35
35
  ```
36
36
 
37
+ **Audience:** if `audience` is set, Read and follow `{audience_ref}`. Reply in any `response_language` and pass it to subagents; code and paths stay as is.
38
+
37
39
  Check `roadmap_exists` from init JSON. If false:
38
40
  ```
39
41
  ERROR: No roadmap found (.planning/ROADMAP.md)
@@ -38,6 +38,8 @@ INIT=$(pp_run query init.phase-op "${PHASE_ARG}")
38
38
  if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
39
39
  ```
40
40
 
41
+ **Audience:** if `audience` is set, Read and follow `{audience_ref}`. Reply in any `response_language` and pass it to subagents; code and paths stay as is.
42
+
41
43
  Extract from init JSON: `phase_dir`, `phase_number`, `phase_name`.
42
44
 
43
45
  Verify the phase directory exists. If not:
@@ -17,6 +17,8 @@ INIT=$(pp_run query init.todos)
17
17
  if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
18
18
  ```
19
19
 
20
+ **Audience:** if `audience` is set, Read and follow `{audience_ref}`. Reply in any `response_language` and pass it to subagents; code and paths stay as is.
21
+
20
22
  Extract from init JSON: `commit_docs`, `date`, `timestamp`, `todo_count`, `todos`, `pending_dir`, `todos_dir_exists`.
21
23
 
22
24
  Ensure directories exist: