@pareto4/pp-core 1.22.0 → 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.
- package/.claude-plugin/plugin.json +1 -1
- package/bin/install.js +205 -28
- package/commands/pp-help.md +2 -1
- package/gemini-extension.json +1 -1
- package/hooks/dist/pp-check-update-worker.js +1 -1
- package/hooks/dist/pp-context-monitor.js +3 -3
- package/hooks/dist/pp-statusline.js +88 -14
- package/hooks/dist/pp-update-banner.js +44 -4
- package/hooks/dist/pp-workflow-guard.js +3 -3
- package/hooks/pp-check-update-worker.js +1 -1
- package/hooks/pp-context-monitor.js +3 -3
- package/hooks/pp-statusline.js +88 -14
- package/hooks/pp-update-banner.js +44 -4
- package/hooks/pp-workflow-guard.js +3 -3
- package/package.json +1 -1
- package/pp-core/bin/lib/audience-command.cjs +271 -0
- package/pp-core/bin/lib/audience.cjs +293 -0
- package/pp-core/bin/lib/commands.cjs +26 -17
- package/pp-core/bin/lib/discovery-charter.cjs +13 -1
- package/pp-core/bin/lib/discovery-input-check.cjs +11 -11
- package/pp-core/bin/lib/discovery-session-check.cjs +7 -7
- package/pp-core/bin/lib/discovery-status.cjs +419 -0
- package/pp-core/bin/lib/explain-command.cjs +48 -0
- package/pp-core/bin/lib/gate-card.cjs +97 -0
- package/pp-core/bin/lib/hook-messages.cjs +132 -0
- package/pp-core/bin/lib/init-contract.cjs +116 -76
- package/pp-core/bin/lib/init-interactive.cjs +110 -49
- package/pp-core/bin/lib/init.cjs +44 -3
- package/pp-core/bin/lib/io.cjs +33 -0
- package/pp-core/bin/lib/message-labels.cjs +75 -0
- package/pp-core/bin/lib/messages/core.cjs +20 -0
- package/pp-core/bin/lib/messages/discovery.cjs +267 -0
- package/pp-core/bin/lib/messages/gate.cjs +257 -0
- package/pp-core/bin/lib/messages/hook.cjs +114 -0
- package/pp-core/bin/lib/messages/init.cjs +513 -0
- package/pp-core/bin/lib/messages/progress.cjs +110 -0
- package/pp-core/bin/lib/messages.cjs +208 -0
- package/pp-core/bin/lib/vault-command-router.cjs +16 -3
- package/pp-core/bin/lib/violation-render.cjs +78 -0
- package/pp-core/bin/pp-tools.cjs +68 -23
- package/pp-core/bin/shared/config-schema.manifest.json +1 -0
- package/pp-core/references/audience-moments.md +119 -0
- package/pp-core/references/audience.md +114 -0
- package/pp-core/references/discovery-charter.md +2 -2
- package/pp-core/templates/project-charter.md +3 -4
- package/pp-core/workflows/add-phase.md +2 -0
- package/pp-core/workflows/add-tests.md +2 -0
- package/pp-core/workflows/add-todo.md +2 -0
- package/pp-core/workflows/ai-integration-phase.md +2 -0
- package/pp-core/workflows/audit-milestone.md +2 -0
- package/pp-core/workflows/autonomous.md +2 -0
- package/pp-core/workflows/check-todos.md +2 -0
- package/pp-core/workflows/code-review-fix.md +2 -0
- package/pp-core/workflows/code-review.md +2 -0
- package/pp-core/workflows/complete-milestone.md +10 -1
- package/pp-core/workflows/discovery-sprint/charter.md +3 -2
- package/pp-core/workflows/discovery-sprint/prefill.md +3 -0
- package/pp-core/workflows/discovery-sprint/prototype.md +14 -0
- package/pp-core/workflows/discovery-sprint/sessions/01-kick-off.md +4 -1
- package/pp-core/workflows/discovery-sprint/sessions/13-wrap-up.md +1 -1
- package/pp-core/workflows/discovery-sprint/vault-context.md +15 -0
- package/pp-core/workflows/discovery-sprint.md +14 -0
- package/pp-core/workflows/discovery-to-build.md +8 -2
- package/pp-core/workflows/discuss-phase-assumptions.md +2 -0
- package/pp-core/workflows/discuss-phase.md +1 -1
- package/pp-core/workflows/edit-phase.md +2 -0
- package/pp-core/workflows/eval-review.md +2 -0
- package/pp-core/workflows/execute-phase/steps/check-query-gate.md +25 -1
- package/pp-core/workflows/execute-phase/steps/vault-fetch.md +1 -0
- package/pp-core/workflows/execute-phase/steps/vault-load-gate.md +2 -0
- package/pp-core/workflows/execute-phase.md +1 -1
- package/pp-core/workflows/execute-plan.md +2 -0
- package/pp-core/workflows/extract-learnings.md +2 -0
- package/pp-core/workflows/help/modes/business.md +56 -0
- package/pp-core/workflows/help.md +12 -2
- package/pp-core/workflows/import.md +10 -1
- package/pp-core/workflows/ingest-docs.md +2 -0
- package/pp-core/workflows/init.md +17 -1
- package/pp-core/workflows/insert-phase.md +2 -0
- package/pp-core/workflows/list-workspaces.md +2 -0
- package/pp-core/workflows/manager.md +2 -0
- package/pp-core/workflows/map-codebase.md +2 -0
- package/pp-core/workflows/milestone-summary.md +2 -0
- package/pp-core/workflows/new-milestone.md +10 -1
- package/pp-core/workflows/new-project.md +12 -2
- package/pp-core/workflows/new-workspace.md +2 -0
- package/pp-core/workflows/next.md +8 -0
- package/pp-core/workflows/plan-milestone-gaps.md +10 -1
- package/pp-core/workflows/plan-phase.md +2 -1
- package/pp-core/workflows/plan-review-convergence.md +1 -1
- package/pp-core/workflows/progress.md +10 -0
- package/pp-core/workflows/quick.md +11 -1
- package/pp-core/workflows/remove-phase.md +2 -0
- package/pp-core/workflows/remove-workspace.md +2 -0
- package/pp-core/workflows/resume-project.md +25 -0
- package/pp-core/workflows/review.md +2 -0
- package/pp-core/workflows/scan.md +2 -0
- package/pp-core/workflows/secure-phase.md +2 -0
- package/pp-core/workflows/settings.md +41 -0
- package/pp-core/workflows/ship.md +2 -0
- package/pp-core/workflows/spec-phase.md +1 -1
- package/pp-core/workflows/ui-phase.md +2 -0
- package/pp-core/workflows/ui-review.md +2 -0
- package/pp-core/workflows/ultraplan-phase.md +2 -0
- package/pp-core/workflows/validate-phase.md +2 -0
- package/pp-core/workflows/vault-review.md +2 -0
- package/pp-core/workflows/verify-phase.md +2 -0
- package/pp-core/workflows/verify-work.md +2 -0
- package/scripts/affected-tests-lib.cjs +26 -12
- package/scripts/ci-release-only.cjs +158 -0
- package/scripts/live-runs/driver.cjs +326 -0
- package/scripts/live-runs/run.cjs +906 -0
- package/scripts/live-runs/scenarios.cjs +326 -0
- package/scripts/live-runs/scratch-project.cjs +132 -0
- package/scripts/live-runs/scrub.cjs +291 -0
- package/scripts/live-runs/turn-guard.cjs +107 -0
- package/scripts/live-runs/walk-setup.cjs +198 -0
- package/scripts/run-tests.cjs +151 -135
- package/scripts/test-env.cjs +64 -0
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Catalog slice: discovery messages (Phase 41, plan 41-06). Data only.
|
|
4
|
+
*
|
|
5
|
+
* ADR-457 build-at-publish: compiles to the gitignored
|
|
6
|
+
* `pp-core/bin/lib/messages/discovery.cjs`. Imports nothing but the entry type.
|
|
7
|
+
*
|
|
8
|
+
* The `developer` text of every entry is the wording the untouched code printed
|
|
9
|
+
* (tests/fixtures/message-oracle.json pins it byte for byte). `engineer` and
|
|
10
|
+
* `business` follow pp-core/references/audience.md: what happened, then what to
|
|
11
|
+
* do; the session by its number, the section by its title, the line, and the
|
|
12
|
+
* file in backticks. Slots a reworded text uses beyond the developer text are
|
|
13
|
+
* listed in `params` and supplied by `src/violation-render.cts`:
|
|
14
|
+
* session_number the session as a number ("3")
|
|
15
|
+
* none the literal a section holds when a session found nothing
|
|
16
|
+
* marker the open-topic marker the checks count
|
|
17
|
+
* status_word the canonical status word, always shown in backticks
|
|
18
|
+
* status the same word relabelled for the audience (label())
|
|
19
|
+
* The text a person must write stays canonical (D-13); only `status` is a label.
|
|
20
|
+
* `Ref:` lines are added by the engine at render time, never written here.
|
|
21
|
+
*
|
|
22
|
+
* The `discovery.status*` entries (Phase 42, D-07) are the sprint view that
|
|
23
|
+
* `pp-tools discovery status` prints; `src/discovery-status.cts` supplies every
|
|
24
|
+
* slot, already cleaned of control and format characters:
|
|
25
|
+
* project, done, total, in_progress, pre_filled, not_started the headline
|
|
26
|
+
* session, name, status a session by number, name and relabelled status
|
|
27
|
+
* command the command to run next, always shown in backticks
|
|
28
|
+
* charter_status the Project Charter's status word, or a fallback phrase
|
|
29
|
+
* sessions the session numbers with an unrecognised status
|
|
30
|
+
* file the progress sheet's path (developer text only)
|
|
31
|
+
* Only `discovery.status` carries `explain`; the rest are parts of that view.
|
|
32
|
+
*/
|
|
33
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
34
|
+
exports.discovery = void 0;
|
|
35
|
+
exports.discovery = Object.freeze({
|
|
36
|
+
// ─── Session check: one entry per violation reason ─────────────────────────
|
|
37
|
+
'discovery.session.session_missing': {
|
|
38
|
+
reach: 'business',
|
|
39
|
+
developer: ' - {artifact}: session_missing',
|
|
40
|
+
engineer: 'Session {session_number} has no notes file at `{artifact}`. The check needs the file to exist. Run the session so it writes the file, then run the check again.',
|
|
41
|
+
business: 'Session {session_number} has no notes file yet (`{artifact}`). Hold that session first, then run the check again.',
|
|
42
|
+
explain: 'The discovery check reads the notes file each session leaves behind. This one does not exist, so there is nothing to check. Run the session, let it write its notes, and check again.',
|
|
43
|
+
params: ['session_number'],
|
|
44
|
+
},
|
|
45
|
+
'discovery.session.template_missing': {
|
|
46
|
+
reach: 'business',
|
|
47
|
+
developer: ' - {artifact}: template_missing ({id})',
|
|
48
|
+
engineer: 'The outline for session {session_number} was not found (`{artifact}`). The check reads each session outline from the pp-core install, so the install is incomplete. Reinstall pp-core, then run the check again.',
|
|
49
|
+
business: 'The outline for session {session_number} could not be found (`{artifact}`). Ask Pareto to repair your pp-core installation, then run the check again.',
|
|
50
|
+
explain: 'Each session has an outline that lists the sections its notes must hold. The check could not find the outline for this session, which means the pp-core installation is missing a file. Reinstalling pp-core fixes it.',
|
|
51
|
+
params: ['session_number'],
|
|
52
|
+
},
|
|
53
|
+
'discovery.session.missing_section': {
|
|
54
|
+
reach: 'business',
|
|
55
|
+
developer: ' - {artifact}: missing_section ({id})',
|
|
56
|
+
engineer: 'Session {session_number} has no section titled "{id}" in `{artifact}`. The session outline requires every section exactly once. Add the section under its bold title, then run the check again.',
|
|
57
|
+
business: 'Session {session_number} has no section called "{id}" in `{artifact}`. Add that section with exactly that title, then run the check again.',
|
|
58
|
+
explain: 'Every session outline lists sections the notes must hold, each under its own bold title. A section that is not there counts as not covered, so the session cannot score full marks. Add the section with the exact title from the outline.',
|
|
59
|
+
params: ['session_number'],
|
|
60
|
+
},
|
|
61
|
+
'discovery.session.duplicate_section': {
|
|
62
|
+
reach: 'business',
|
|
63
|
+
developer: ' - {artifact}:{line}: duplicate_section ({id})',
|
|
64
|
+
engineer: 'Session {session_number} holds the section "{id}" more than once; the second copy starts at line {line} of `{artifact}`. The outline allows each section once. Merge or delete the extra copy, then run the check again.',
|
|
65
|
+
business: 'Session {session_number} has the section "{id}" twice; the second one starts at line {line} of `{artifact}`. Merge the two into one, then run the check again.',
|
|
66
|
+
explain: 'Each section may appear once in a session file, so the check knows which one to read. A second copy makes that unclear. Keep one copy that holds everything, and remove the other.',
|
|
67
|
+
params: ['session_number'],
|
|
68
|
+
},
|
|
69
|
+
'discovery.session.bad_table_shape': {
|
|
70
|
+
reach: 'business',
|
|
71
|
+
developer: ' - {artifact}:{line}: bad_table_shape ({id})',
|
|
72
|
+
engineer: 'The table in section "{id}" of session {session_number} (line {line} of `{artifact}`) does not match the outline: its columns differ from the header the outline defines. Make the header row match the outline, then run the check again.',
|
|
73
|
+
business: 'The table in section "{id}" of session {session_number} (line {line} of `{artifact}`) has the wrong columns. Make its columns match the session outline, then run the check again.',
|
|
74
|
+
explain: 'Tables in the session notes are read by column, so their columns must be the ones the outline names, in the same order. Compare the header row with the outline of the session and correct it.',
|
|
75
|
+
params: ['session_number'],
|
|
76
|
+
},
|
|
77
|
+
'discovery.session.empty_section': {
|
|
78
|
+
reach: 'business',
|
|
79
|
+
developer: ' - {artifact}:{line}: empty_section ({id})',
|
|
80
|
+
engineer: 'Section "{id}" of session {session_number} is empty (line {line} of `{artifact}`). The check needs at least one row or line of text, or `{none}` on its own line under the title. Fill the section, then run the check again.',
|
|
81
|
+
business: 'Section "{id}" of session {session_number} has nothing in it (line {line} of `{artifact}`). Add what the session found, or write `{none}` under the title, then run the check again.',
|
|
82
|
+
explain: 'A section that is empty is counted as not covered. If the session found nothing to record, say so with the exact sentence the check expects, on its own line under the section title. Otherwise add what the session found.',
|
|
83
|
+
params: ['session_number', 'none'],
|
|
84
|
+
},
|
|
85
|
+
'discovery.session.artifact_unreadable': {
|
|
86
|
+
reach: 'business',
|
|
87
|
+
developer: ' - {artifact}: artifact_unreadable',
|
|
88
|
+
engineer: 'The notes file `{artifact}` for session {session_number} exists but could not be read. It may be a folder or lack read permission. Fix that, then run the check again.',
|
|
89
|
+
business: 'The notes file for session {session_number} (`{artifact}`) could not be opened. Check that it is a normal file you can open, then run the check again.',
|
|
90
|
+
explain: 'The check found something at the place where the session notes belong, but could not read it. This usually means it is a folder instead of a file, or its permissions block reading. Put the notes file back in place.',
|
|
91
|
+
params: ['session_number'],
|
|
92
|
+
},
|
|
93
|
+
discovery_session_check_failed: {
|
|
94
|
+
reach: 'business',
|
|
95
|
+
developer: 'discovery session-check: {count} violation(s):\n{lines}',
|
|
96
|
+
engineer: 'The discovery session check found {count} problem(s):\n{lines}\nFix each one in its session file, then run the check again.',
|
|
97
|
+
business: 'Your discovery notes have {count} to fix:\n{lines}\nFix each one, then run the check again.',
|
|
98
|
+
explain: 'The session check reads the notes of each discovery session and compares them with the session outline. Each problem above names the session, the section and the file. Fix them one by one and run the check again until none are left.',
|
|
99
|
+
rawParams: ['lines'],
|
|
100
|
+
},
|
|
101
|
+
// ─── Input check ───────────────────────────────────────────────────────────
|
|
102
|
+
'discovery.input.completed_with_unconfirmed': {
|
|
103
|
+
reach: 'business',
|
|
104
|
+
developer: ' {session}: completed_with_unconfirmed (markers: {markers})',
|
|
105
|
+
engineer: 'Session {session_number} (`{session}`) is {status}, but `{marker}` still appears {markers} time(s) in it. The file says `{status_word}`. Resolve each open topic and remove its `{marker}`, then run the check again.',
|
|
106
|
+
business: 'Session {session_number} (`{session}`) counts as {status}, but `{marker}` still appears {markers} time(s) in it. The file says `{status_word}`; settle each open topic and remove its `{marker}`, then run the check again.',
|
|
107
|
+
explain: 'A session may only be closed when nothing in it is still waiting for confirmation. The marker shows a topic someone has not confirmed yet. Confirm each topic and remove the marker, then check again.',
|
|
108
|
+
params: ['session_number', 'marker', 'status', 'status_word'],
|
|
109
|
+
},
|
|
110
|
+
'discovery.input.score_counts_unconfirmed': {
|
|
111
|
+
reach: 'business',
|
|
112
|
+
developer: ' {session}: score_counts_unconfirmed (score: {score}, markers: {markers})',
|
|
113
|
+
engineer: 'Session {session_number} (`{session}`) scores {score} while topics are still unconfirmed (`{marker}` count: {markers}, or the session is still pre-filled). Confirm what is open and complete the session, or lower the score, then run the check again.',
|
|
114
|
+
business: 'Session {session_number} (`{session}`) scores {score} but still counts topics nobody has confirmed (`{marker}` count: {markers}). Confirm what is open and complete the session, or lower the score, then run the check again.',
|
|
115
|
+
explain: 'A full score means every topic of the session is confirmed. A topic still waiting for confirmation, or a session that was only prepared from documents, cannot count as covered. Confirm the open topics before the session scores full marks.',
|
|
116
|
+
params: ['session_number', 'marker'],
|
|
117
|
+
},
|
|
118
|
+
'discovery.input.confidential_tracked': {
|
|
119
|
+
reach: 'business',
|
|
120
|
+
developer: ' {file}: confidential_tracked',
|
|
121
|
+
engineer: 'The confidential input file `{file}` is tracked by git, so it would travel with the repository. Remove it from tracking (for example with `git rm --cached`) and keep it ignored, then run the check again.',
|
|
122
|
+
business: 'The private file `{file}` has been added to the project, and private files must stay out of it. Ask an engineer to take it out again; your own copy stays where it is.',
|
|
123
|
+
explain: 'Files in the confidential input folder must never be saved with the project, because everyone who gets the project would get them too. Take the file out of the project but keep your copy, and the check passes.',
|
|
124
|
+
},
|
|
125
|
+
discovery_input_check_failed: {
|
|
126
|
+
reach: 'business',
|
|
127
|
+
developer: 'discovery input-check: {count} violation(s):\n{lines}',
|
|
128
|
+
engineer: 'The discovery input check found {count} problem(s):\n{lines}\nFix each one, then run the check again.',
|
|
129
|
+
business: 'Your discovery input has {count} to fix:\n{lines}\nFix each one, then run the check again.',
|
|
130
|
+
explain: 'The input check looks at the discovery sessions that are closed or scored, and at the private input folder. Each problem above names the file to look at. Fix them one by one and run the check again until none are left.',
|
|
131
|
+
rawParams: ['lines'],
|
|
132
|
+
},
|
|
133
|
+
// ─── discovery status view (Phase 42, D-07) ────────────────────────────────
|
|
134
|
+
'discovery.status': {
|
|
135
|
+
reach: 'business',
|
|
136
|
+
developer: '## Discovery Sprint — {project}',
|
|
137
|
+
engineer: '## Discovery Sprint: {project}',
|
|
138
|
+
business: '## Discovery Sprint — {project}',
|
|
139
|
+
explain: 'This view shows where the Discovery Sprint stands: how many sessions are done, the state of each session, where the work stopped, and the step to take next. The next step is the one `/pp-discovery` recommends when you run it without a number.',
|
|
140
|
+
},
|
|
141
|
+
'discovery.status.counts': {
|
|
142
|
+
reach: 'business',
|
|
143
|
+
developer: 'Completed: {done}/{total} · In Progress: {in_progress} · Pre-Filled: {pre_filled} · Not Started: {not_started}',
|
|
144
|
+
engineer: '{done} of {total} sessions completed · {in_progress} in progress · {pre_filled} pre-filled from documents · {not_started} not started',
|
|
145
|
+
business: '{done} of {total} sessions done · {in_progress} being worked on · {pre_filled} prepared from your documents · {not_started} not started yet',
|
|
146
|
+
part: true,
|
|
147
|
+
},
|
|
148
|
+
'discovery.status.header': {
|
|
149
|
+
reach: 'business',
|
|
150
|
+
developer: '| # | Session | Status |\n|---|---------|--------|',
|
|
151
|
+
engineer: '| # | Session | Status |\n|---|---------|--------|',
|
|
152
|
+
business: '| # | Session | Where it stands |\n|---|---------|-----------------|',
|
|
153
|
+
part: true,
|
|
154
|
+
},
|
|
155
|
+
'discovery.status.stopped.in_progress': {
|
|
156
|
+
reach: 'business',
|
|
157
|
+
developer: 'Stopped at: Session {session} — {name} ({status})',
|
|
158
|
+
engineer: 'Stopped at session {session}, {name} ({status}).',
|
|
159
|
+
business: 'You stopped in session {session}, {name} ({status}).',
|
|
160
|
+
part: true,
|
|
161
|
+
},
|
|
162
|
+
'discovery.status.stopped.completed': {
|
|
163
|
+
reach: 'business',
|
|
164
|
+
developer: 'Last completed: Session {session} — {name}',
|
|
165
|
+
engineer: 'The last completed session is session {session}, {name}.',
|
|
166
|
+
business: 'The last session finished was session {session}, {name}.',
|
|
167
|
+
part: true,
|
|
168
|
+
},
|
|
169
|
+
'discovery.status.stopped.none': {
|
|
170
|
+
reach: 'business',
|
|
171
|
+
developer: 'Stopped at: not started yet',
|
|
172
|
+
engineer: 'No session has been started yet.',
|
|
173
|
+
business: 'No session has been held yet.',
|
|
174
|
+
part: true,
|
|
175
|
+
},
|
|
176
|
+
'discovery.status.next.resume': {
|
|
177
|
+
reach: 'business',
|
|
178
|
+
developer: 'Next: resume Session {session} — {name}. Run `{command}`.',
|
|
179
|
+
engineer: 'Next: resume session {session}, {name}, which is in progress. Run `{command}` to continue.',
|
|
180
|
+
business: 'Next: carry on with session {session}, {name}. Type `{command}` to continue.',
|
|
181
|
+
part: true,
|
|
182
|
+
},
|
|
183
|
+
'discovery.status.next.confirm': {
|
|
184
|
+
reach: 'business',
|
|
185
|
+
developer: 'Next: confirm Session {session} — {name} (Pre-Filled). Run `{command}` to walk its open markers.',
|
|
186
|
+
engineer: 'Next: confirm session {session}, {name}, which was pre-filled from documents. Run `{command}` to walk its open markers.',
|
|
187
|
+
business: 'Next: check session {session}, {name}, which was prepared from your documents. Type `{command}` to go through what still needs your confirmation.',
|
|
188
|
+
part: true,
|
|
189
|
+
},
|
|
190
|
+
'discovery.status.next.start': {
|
|
191
|
+
reach: 'business',
|
|
192
|
+
developer: 'Next: start Session {session} — {name}. Run `{command}`.',
|
|
193
|
+
engineer: 'Next: start session {session}, {name}. Run `{command}`.',
|
|
194
|
+
business: 'Next: start session {session}, {name}. Type `{command}` to begin.',
|
|
195
|
+
part: true,
|
|
196
|
+
},
|
|
197
|
+
'discovery.status.next.charter_draft': {
|
|
198
|
+
reach: 'business',
|
|
199
|
+
developer: 'Next: every session is done and there is no Project Charter. Run `{command}` to draft it.',
|
|
200
|
+
engineer: 'Next: every session is completed, but the Project Charter has not been drafted. Run `{command}` to draft it.',
|
|
201
|
+
business: 'Next: every session is done. The Project Charter has not been written yet. Type `{command}` to draft it.',
|
|
202
|
+
part: true,
|
|
203
|
+
},
|
|
204
|
+
'discovery.status.next.charter_sign': {
|
|
205
|
+
reach: 'business',
|
|
206
|
+
developer: 'Next: the Project Charter is {charter_status}, not signed. Run `{command}` to record signatures.',
|
|
207
|
+
engineer: "Next: the Project Charter's status is {charter_status}, so it still needs signing. Run `{command}` to record the signatures.",
|
|
208
|
+
business: 'Next: the Project Charter is not signed yet (it says: {charter_status}). Type `{command}` to record the signatures.',
|
|
209
|
+
part: true,
|
|
210
|
+
},
|
|
211
|
+
'discovery.status.next.to_build': {
|
|
212
|
+
reach: 'business',
|
|
213
|
+
developer: 'Next: the Project Charter is signed. Run `{command}`.',
|
|
214
|
+
engineer: "Next: the Project Charter is signed. Run `{command}` to set the build up from the sprint's results.",
|
|
215
|
+
business: 'Next: the Project Charter is signed. Type `{command}` to start building from what the sprint agreed.',
|
|
216
|
+
part: true,
|
|
217
|
+
},
|
|
218
|
+
'discovery.status.next.check_sheet': {
|
|
219
|
+
reach: 'business',
|
|
220
|
+
developer: 'Next: correct the unrecognised status first, then run `{command}`.',
|
|
221
|
+
engineer: 'Next: correct the unrecognised status in the tracker first, so a finished session is not run again. Then run `{command}` to carry on.',
|
|
222
|
+
business: 'Next: check the unexpected state in the progress sheet first, so a session already held is not held again. Then type `{command}` to carry on.',
|
|
223
|
+
part: true,
|
|
224
|
+
},
|
|
225
|
+
'discovery.status.unknown_status': {
|
|
226
|
+
reach: 'business',
|
|
227
|
+
developer: 'Unrecognised status in session(s) {sessions}; counted as not started.',
|
|
228
|
+
engineer: 'Session(s) {sessions} have a status this view does not recognise; they are counted as not started.',
|
|
229
|
+
business: 'The progress sheet shows an unexpected state for session(s) {sessions}; they are counted as not started yet.',
|
|
230
|
+
part: true,
|
|
231
|
+
},
|
|
232
|
+
'discovery.status.project_unknown': {
|
|
233
|
+
reach: 'business',
|
|
234
|
+
developer: '(unnamed project)',
|
|
235
|
+
engineer: 'unnamed project',
|
|
236
|
+
business: 'your project',
|
|
237
|
+
part: true,
|
|
238
|
+
},
|
|
239
|
+
'discovery.status.session_unnamed': {
|
|
240
|
+
reach: 'business',
|
|
241
|
+
developer: '(no name)',
|
|
242
|
+
engineer: '(no name in the tracker)',
|
|
243
|
+
business: '(no name given)',
|
|
244
|
+
part: true,
|
|
245
|
+
},
|
|
246
|
+
'discovery.status.charter_no_status': {
|
|
247
|
+
reach: 'business',
|
|
248
|
+
developer: 'without a status',
|
|
249
|
+
engineer: 'missing',
|
|
250
|
+
business: 'no status yet',
|
|
251
|
+
part: true,
|
|
252
|
+
},
|
|
253
|
+
'discovery.status.unreadable': {
|
|
254
|
+
reach: 'business',
|
|
255
|
+
developer: 'Discovery Sprint tracker `{file}` could not be read (no Session Progress table). Run `{command}`.',
|
|
256
|
+
engineer: 'This project is in the Discovery Sprint, but the session table in its sprint tracker could not be read, so the sessions cannot be shown. Run `{command}` to see the sprint and carry on.',
|
|
257
|
+
business: 'This project is in the Discovery Sprint, but its progress sheet could not be read, so the sessions cannot be shown here. Type `{command}` to see where the sprint stands and carry on.',
|
|
258
|
+
explain: 'The sprint keeps one progress sheet with a table of its sessions. The sheet exists, but the table is missing or damaged, so this view cannot count the sessions. The project still counts as being in the Discovery Sprint, and `/pp-discovery` shows the sprint directly.',
|
|
259
|
+
},
|
|
260
|
+
'discovery.status.none': {
|
|
261
|
+
reach: 'business',
|
|
262
|
+
developer: 'No Discovery Sprint in this project (no `{file}`). Run `{command}` to start one.',
|
|
263
|
+
engineer: 'This project has no Discovery Sprint: there is no sprint tracker yet. Run `{command}` to start one.',
|
|
264
|
+
business: 'This project has no Discovery Sprint yet. Type `{command}` to start one.',
|
|
265
|
+
explain: 'The progress sheet is how a project shows it is in the Discovery Sprint. This project has none, so there is no sprint to show. `/pp-discovery 1` starts the sprint and creates the sheet.',
|
|
266
|
+
},
|
|
267
|
+
});
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Catalog slice: stopped-check cards (Phase 43, TPL-02; D-09, D-10). Data only.
|
|
4
|
+
*
|
|
5
|
+
* ADR-457 build-at-publish: this TypeScript file is the SOURCE OF TRUTH. It
|
|
6
|
+
* compiles to the gitignored `pp-core/bin/lib/messages/gate.cjs`; do NOT
|
|
7
|
+
* hand-edit the compiled output. Imports nothing but the entry type.
|
|
8
|
+
*
|
|
9
|
+
* One facts table (`GATE_FACTS`) holds, per quality check, its name, the reason
|
|
10
|
+
* it stops a step and what to do about it, once for a business user and once
|
|
11
|
+
* for a business engineer. The catalog entries are built from it with three
|
|
12
|
+
* frames written once, so every card reads the same way (D-10):
|
|
13
|
+
*
|
|
14
|
+
* blocked: The {name} check stopped this step: {why}. What to do: {action}.
|
|
15
|
+
* advisory: The {name} check found something to look at, and this step carries on: {why}. What to do: {action}.
|
|
16
|
+
* error: The {name} check could not run, so its answer is missing. What to do: if this step stopped, run it again; ...
|
|
17
|
+
*
|
|
18
|
+
* The error frame reads true on both command-error paths: the step stopped
|
|
19
|
+
* (`onError: halt`) or it carried on without the answer (`onError: skip`).
|
|
20
|
+
*
|
|
21
|
+
* The `developer` text of every entry is the line the shipped workflow prints
|
|
22
|
+
* today, byte for byte, glyph included: check-query-gate.md (blocked, advisory
|
|
23
|
+
* and command-error lines), the vault-fetch.md STRICT-03 line, the plan-phase.md
|
|
24
|
+
* decision-coverage fallback and the `vault admission --explain` repair line.
|
|
25
|
+
* The capability lines keep `{point}` as the only slot; the query name is
|
|
26
|
+
* inserted at build time.
|
|
27
|
+
*
|
|
28
|
+
* Business and engineer text uses no slot: the check's name, reason and next step
|
|
29
|
+
* are fixed words, so nothing typed or read from a file reaches the card. Business
|
|
30
|
+
* text follows pp-core/references/audience.md (no hidden term, no glossary
|
|
31
|
+
* term); engineer text keeps real terms and never a term hidden from both.
|
|
32
|
+
*/
|
|
33
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
34
|
+
exports.gate = exports.GATE_QUERIES = exports.GATE_FACTS = exports.GATE_STATES = void 0;
|
|
35
|
+
exports.GATE_STATES = ['blocked', 'advisory', 'error'];
|
|
36
|
+
const ALL = exports.GATE_STATES;
|
|
37
|
+
const BLOCKED_ONLY = ['blocked'];
|
|
38
|
+
exports.GATE_FACTS = Object.freeze([
|
|
39
|
+
{
|
|
40
|
+
query: 'vault.trace',
|
|
41
|
+
states: ALL,
|
|
42
|
+
business: {
|
|
43
|
+
name: 'standards record',
|
|
44
|
+
why: "some of the work does not say which of your organisation's standards it followed",
|
|
45
|
+
action: 'ask me to list what is missing, then plan that part again',
|
|
46
|
+
},
|
|
47
|
+
engineer: {
|
|
48
|
+
name: 'standards record',
|
|
49
|
+
why: "a plan has no valid standards block, or a summary's Standards Consulted section does not match the standards that were loaded",
|
|
50
|
+
action: "fix the plan's standards block or the summary's section named in the details, then run this step again",
|
|
51
|
+
},
|
|
52
|
+
explain: "This check looks at each plan and each finished summary and asks whether it says which of your organisation's standards the work followed. It stops the step when a record is missing or does not match what was loaded, because the standards are only a promise if every piece of work shows it used them.",
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
query: 'vault.status',
|
|
56
|
+
states: ALL,
|
|
57
|
+
business: {
|
|
58
|
+
name: 'organisation standards',
|
|
59
|
+
why: "your organisation's standards are missing, out of date or did not load",
|
|
60
|
+
action: 'ask me to load them again, or ask your Pareto contact to fix the connection',
|
|
61
|
+
},
|
|
62
|
+
engineer: {
|
|
63
|
+
name: 'standards vault',
|
|
64
|
+
why: 'the standards vault is missing, stale or did not load, and `vault.required` is on',
|
|
65
|
+
action: 'load the vault again, or check the vault connection and `vault.cache_ttl_hours`',
|
|
66
|
+
},
|
|
67
|
+
explain: "This check looks at whether your organisation's standards are present, recent and loaded for this project. When the project requires them and they are not there, the step stops, so work is never built without the standards it was meant to follow.",
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
query: 'ship.platform-drift',
|
|
71
|
+
states: ALL,
|
|
72
|
+
business: {
|
|
73
|
+
name: 'platform version',
|
|
74
|
+
why: 'the platform version this project uses is behind the newest one by more than your settings allow',
|
|
75
|
+
action: 'ask me to update it, or ask your Pareto contact whether to carry on with this version',
|
|
76
|
+
},
|
|
77
|
+
engineer: {
|
|
78
|
+
name: 'platform version',
|
|
79
|
+
why: 'the platform tag pinned in `.platform-bindings.json` is behind the latest by at least the level set in `pareto.drift_block_on`',
|
|
80
|
+
action: 'update the pinned tag, or raise `pareto.drift_block_on` if staying on this version is intended',
|
|
81
|
+
},
|
|
82
|
+
explain: 'This check compares the platform version your project uses with the newest one. A small gap is only noted; a gap larger than your settings allow stops the step, so you do not ship on a version that is far behind.',
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
query: 'verify.schema-drift',
|
|
86
|
+
states: ALL,
|
|
87
|
+
business: {
|
|
88
|
+
name: 'data structure',
|
|
89
|
+
why: 'the data structure files changed but the matching update was not applied',
|
|
90
|
+
action: 'ask me to apply the update before testing',
|
|
91
|
+
},
|
|
92
|
+
engineer: {
|
|
93
|
+
name: 'schema',
|
|
94
|
+
why: 'schema or ORM files changed and the matching migration or push was not applied',
|
|
95
|
+
action: 'apply the migration, then run the verification again',
|
|
96
|
+
},
|
|
97
|
+
explain: 'This check notices when the files that describe your data structure changed but the update that applies them to the database was not run. Testing against a database that does not match the code gives answers that cannot be trusted, so the step stops until the update is applied.',
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
query: 'verify.codebase-drift',
|
|
101
|
+
states: ALL,
|
|
102
|
+
business: {
|
|
103
|
+
name: 'code map',
|
|
104
|
+
why: 'the saved map of the code is out of date',
|
|
105
|
+
action: 'ask me to refresh the map',
|
|
106
|
+
},
|
|
107
|
+
engineer: {
|
|
108
|
+
name: 'codebase map',
|
|
109
|
+
why: 'files or folders were added or moved since `STRUCTURE.md` was written, so it no longer matches the code',
|
|
110
|
+
action: 'refresh the map with `/pp-map-codebase`',
|
|
111
|
+
},
|
|
112
|
+
explain: 'This check compares the saved map of your code with what is in the project now. When new files or folders appeared that the map does not show, it stops the step, because later work leans on that map to find its way around.',
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
query: 'ui.safety-gate',
|
|
116
|
+
states: ALL,
|
|
117
|
+
business: {
|
|
118
|
+
name: 'screen design',
|
|
119
|
+
why: 'screens were built without a screen design',
|
|
120
|
+
action: 'create the screen design first, or tell me to carry on without one',
|
|
121
|
+
},
|
|
122
|
+
engineer: {
|
|
123
|
+
name: 'UI design contract',
|
|
124
|
+
why: 'UI files changed in a frontend phase and no `UI-SPEC.md` exists',
|
|
125
|
+
action: 'run `/pp-ui-phase` to write `UI-SPEC.md`, or choose to continue without it',
|
|
126
|
+
},
|
|
127
|
+
explain: 'This check looks at stages that build screens. If screen files were changed and there is no screen design for the stage, it stops the step, so the screens are built against an agreed design and not guessed.',
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
query: 'ui.plan-gate',
|
|
131
|
+
states: ALL,
|
|
132
|
+
business: {
|
|
133
|
+
name: 'screen design',
|
|
134
|
+
why: 'screens are being planned without a screen design',
|
|
135
|
+
action: 'design the screens first, or tell me to plan without a design',
|
|
136
|
+
},
|
|
137
|
+
engineer: {
|
|
138
|
+
name: 'UI design contract',
|
|
139
|
+
why: 'a frontend phase is being planned and no `UI-SPEC.md` exists',
|
|
140
|
+
action: 'run `/pp-ui-phase` to write `UI-SPEC.md` first, or choose to plan without it',
|
|
141
|
+
},
|
|
142
|
+
explain: 'This check looks at stages that include screens. If the stage has no screen design yet, it stops planning, so the plan is written against an agreed design and not against a guess.',
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
query: 'tdd.review-checkpoint',
|
|
146
|
+
states: ALL,
|
|
147
|
+
business: {
|
|
148
|
+
name: 'test-first',
|
|
149
|
+
why: 'some work meant to be built test-first is missing its test step or its build step',
|
|
150
|
+
action: 'ask me which plans, then decide whether to add the missing step',
|
|
151
|
+
},
|
|
152
|
+
engineer: {
|
|
153
|
+
name: 'TDD review',
|
|
154
|
+
why: 'a `type: tdd` plan lacks its `test(...)` commit or its `feat(...)` commit',
|
|
155
|
+
action: 'see which plans in the details, then decide whether to add the missing commit',
|
|
156
|
+
},
|
|
157
|
+
explain: 'This check looks at plans that are meant to be built test-first: a test is written and seen to fail, then the code is written to make it pass. When a plan is missing one of those two steps, the check tells you, so you can decide whether to add it.',
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
query: 'gap-analysis.plan-post',
|
|
161
|
+
states: ALL,
|
|
162
|
+
business: {
|
|
163
|
+
name: 'requirement coverage',
|
|
164
|
+
why: 'some requirements or decisions are not in any plan yet',
|
|
165
|
+
action: 'ask me to add them to a plan or move them to a later stage',
|
|
166
|
+
},
|
|
167
|
+
engineer: {
|
|
168
|
+
name: 'requirement coverage',
|
|
169
|
+
why: 'some requirement or decision IDs from `REQUIREMENTS.md` and `CONTEXT.md` appear in no `PLAN.md`',
|
|
170
|
+
action: 'add them to a plan, or move them to a later phase',
|
|
171
|
+
},
|
|
172
|
+
explain: 'After a stage is planned, this check lists every requirement and decision and shows which ones no plan mentions. It only tells you; it never stops the work by itself.',
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
query: 'vault.admission',
|
|
176
|
+
states: BLOCKED_ONLY,
|
|
177
|
+
business: {
|
|
178
|
+
name: 'standards connection',
|
|
179
|
+
why: 'a project settings file the standards connection needs cannot be read',
|
|
180
|
+
action: 'ask your Pareto contact to repair that file, then run this again',
|
|
181
|
+
},
|
|
182
|
+
engineer: {
|
|
183
|
+
name: 'standards vault admission',
|
|
184
|
+
why: 'a settings file it must read, named under Details, is not valid JSON, so the check refuses to pass having checked nothing',
|
|
185
|
+
action: 'fix the JSON in that file or remove the key that broke it, then run this again',
|
|
186
|
+
},
|
|
187
|
+
explain: "Before any step that uses your organisation's standards, this check reads the project settings that say whether the standards apply. If one of those files is broken it cannot tell, and it stops instead of letting the work through unchecked. The file and the problem are listed under Details.",
|
|
188
|
+
developer: '{file}: {error} — repair: fix the JSON in {file} (or remove the key that broke it) and re-run; ' +
|
|
189
|
+
'the gate cannot read this file and refuses to pass having checked nothing',
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
query: 'vault.fetch',
|
|
193
|
+
states: BLOCKED_ONLY,
|
|
194
|
+
business: {
|
|
195
|
+
name: 'organisation standards',
|
|
196
|
+
why: "your organisation's standards could not be loaded, and this project requires them",
|
|
197
|
+
action: 'run this step again; if it fails again, ask your Pareto contact',
|
|
198
|
+
},
|
|
199
|
+
engineer: {
|
|
200
|
+
name: 'standards vault',
|
|
201
|
+
why: 'the vault could not be fetched or its summary could not be written, and `vault.required` is on',
|
|
202
|
+
action: 'run this step again; if it fails again, check the vault connection or ask your Pareto contact',
|
|
203
|
+
},
|
|
204
|
+
explain: "This check runs when a step starts. If your organisation's standards could not be loaded and the project says they are required, the step stops, so nothing is built without them.",
|
|
205
|
+
developer: '✗ vault could not be loaded and vault.required is true (STRICT-03)',
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
query: 'decision-coverage',
|
|
209
|
+
states: BLOCKED_ONLY,
|
|
210
|
+
business: {
|
|
211
|
+
name: 'decisions',
|
|
212
|
+
why: 'some decisions you made are not used in any plan yet',
|
|
213
|
+
action: 'ask me to plan again so each decision is covered, or mark it as one the assistant may decide',
|
|
214
|
+
},
|
|
215
|
+
engineer: {
|
|
216
|
+
name: 'decision coverage',
|
|
217
|
+
why: 'some decisions in `CONTEXT.md` are cited by no plan',
|
|
218
|
+
action: "cite each as `D-NN` in a plan, or move it to the Claude's Discretion section of `CONTEXT.md`",
|
|
219
|
+
},
|
|
220
|
+
explain: 'After a stage is planned, this check compares the decisions you made with the plans. If one of your decisions is not used in any plan, planning stops, so a decision you took is never quietly dropped.',
|
|
221
|
+
developer: 'Decision coverage gate failed.',
|
|
222
|
+
},
|
|
223
|
+
]);
|
|
224
|
+
exports.GATE_QUERIES = Object.freeze(exports.GATE_FACTS.map((f) => f.query));
|
|
225
|
+
const DEV_FRAMES = {
|
|
226
|
+
blocked: (q) => `⚠ Gate blocked at {point} (${q}). Resolve before continuing.`,
|
|
227
|
+
advisory: (q) => `ℹ Gate advisory at {point} (${q}). Continuing.`,
|
|
228
|
+
error: (q) => `⚠ Gate check command failed ({point} / ${q}): command error. Resolve before continuing.`,
|
|
229
|
+
};
|
|
230
|
+
function card(state, w, who) {
|
|
231
|
+
if (state === 'blocked')
|
|
232
|
+
return `The ${w.name} check stopped this step: ${w.why}. What to do: ${w.action}.`;
|
|
233
|
+
if (state === 'advisory') {
|
|
234
|
+
return `The ${w.name} check found something to look at, and this step carries on: ${w.why}. What to do: ${w.action}.`;
|
|
235
|
+
}
|
|
236
|
+
return who === 'business'
|
|
237
|
+
? `The ${w.name} check could not run, so its answer is missing. What to do: if this step stopped, run it again; if it stops the same way, give your Pareto contact the code below.`
|
|
238
|
+
: `The ${w.name} check could not run, so its answer is missing. What to do: if this step stopped, run it again; if it stops the same way, run \`pp-tools explain\` with the code below and share what it prints with your Pareto contact.`;
|
|
239
|
+
}
|
|
240
|
+
function build() {
|
|
241
|
+
const out = {};
|
|
242
|
+
for (const f of exports.GATE_FACTS) {
|
|
243
|
+
for (const state of f.states) {
|
|
244
|
+
out[`gate.${f.query}.${state}`] = {
|
|
245
|
+
reach: 'business',
|
|
246
|
+
developer: f.developer ?? DEV_FRAMES[state](f.query),
|
|
247
|
+
engineer: card(state, f.engineer, 'engineer'),
|
|
248
|
+
business: card(state, f.business, 'business'),
|
|
249
|
+
explain: f.explain,
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
for (const code of Object.keys(out))
|
|
254
|
+
Object.freeze(out[code]);
|
|
255
|
+
return Object.freeze(out);
|
|
256
|
+
}
|
|
257
|
+
exports.gate = build();
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Catalog slice: the statusline and the update banner (Phase 43, MSG-06; D-17..D-20). Data only.
|
|
4
|
+
*
|
|
5
|
+
* ADR-457 build-at-publish: this TypeScript file is the SOURCE OF TRUTH. It
|
|
6
|
+
* compiles to the gitignored `pp-core/bin/lib/messages/hook.cjs`; do NOT
|
|
7
|
+
* hand-edit the compiled output. Imports nothing but the entry type.
|
|
8
|
+
*
|
|
9
|
+
* The `developer` text of every entry is the string the hooks print today,
|
|
10
|
+
* byte for byte (PR #36's command names included), so a developer's statusline
|
|
11
|
+
* and update notice do not change (D-17). The statusline entries are fragments
|
|
12
|
+
* (`part: true`): they never carry a `Ref:` line, because the statusline is one
|
|
13
|
+
* line of a status bar. The two banner entries are whole messages and end with
|
|
14
|
+
* a `Ref:` line for a business user and an engineer.
|
|
15
|
+
*
|
|
16
|
+
* The hooks load this slice through the light entry `hook-messages.cjs`, never
|
|
17
|
+
* through `messages.cjs` (D-18), and fall back to the developer text when the
|
|
18
|
+
* slice cannot load (D-20). ANSI colour codes stay in the hooks, never here.
|
|
19
|
+
*
|
|
20
|
+
* Business wording follows pp-core/references/audience.md: "stage" for phase
|
|
21
|
+
* and "release" for milestone, no internal word. The lifecycle words and next
|
|
22
|
+
* actions that fill `{stage}` and `{action}` are relabelled by the hook before
|
|
23
|
+
* they reach this slice (`state.status`, `state.next_action` in message-labels).
|
|
24
|
+
*/
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.hook = void 0;
|
|
27
|
+
exports.hook = Object.freeze({
|
|
28
|
+
// ─── statusline fragments ──────────────────────────────────────────────────
|
|
29
|
+
'hook.statusline.update': {
|
|
30
|
+
reach: 'business',
|
|
31
|
+
developer: '⬆ /pp-update',
|
|
32
|
+
engineer: '⬆ update ready: /pp-update',
|
|
33
|
+
business: '⬆ new version ready: /pp-update',
|
|
34
|
+
part: true,
|
|
35
|
+
},
|
|
36
|
+
'hook.statusline.stale': {
|
|
37
|
+
reach: 'business',
|
|
38
|
+
developer: '⚠ stale hooks — run /pp-update',
|
|
39
|
+
engineer: '⚠ pp-core hooks out of date — run /pp-update',
|
|
40
|
+
business: '⚠ pp-core needs an update — run /pp-update',
|
|
41
|
+
part: true,
|
|
42
|
+
},
|
|
43
|
+
'hook.statusline.dev_install': {
|
|
44
|
+
reach: 'business',
|
|
45
|
+
developer: '⚠ dev install — re-run installer to sync hooks',
|
|
46
|
+
engineer: '⚠ development install — re-run the installer to sync hooks',
|
|
47
|
+
business: '⚠ pp-core needs reinstalling — ask your Pareto contact',
|
|
48
|
+
part: true,
|
|
49
|
+
},
|
|
50
|
+
'hook.statusline.phase': {
|
|
51
|
+
reach: 'business',
|
|
52
|
+
developer: 'Phase {number}',
|
|
53
|
+
engineer: 'Phase {number}',
|
|
54
|
+
business: 'Stage {number}',
|
|
55
|
+
part: true,
|
|
56
|
+
},
|
|
57
|
+
'hook.statusline.phase_stage': {
|
|
58
|
+
reach: 'business',
|
|
59
|
+
developer: 'Phase {number} {stage}',
|
|
60
|
+
engineer: 'Phase {number}: {stage}',
|
|
61
|
+
business: 'Stage {number}: {stage}',
|
|
62
|
+
part: true,
|
|
63
|
+
},
|
|
64
|
+
'hook.statusline.next': {
|
|
65
|
+
reach: 'business',
|
|
66
|
+
developer: 'next {action} {numbers}',
|
|
67
|
+
engineer: 'next: {action} {numbers}',
|
|
68
|
+
business: 'next: {action} {numbers}',
|
|
69
|
+
part: true,
|
|
70
|
+
},
|
|
71
|
+
'hook.statusline.milestone_complete': {
|
|
72
|
+
reach: 'business',
|
|
73
|
+
developer: 'milestone complete',
|
|
74
|
+
engineer: 'milestone complete (all phases done)',
|
|
75
|
+
business: 'release complete',
|
|
76
|
+
part: true,
|
|
77
|
+
},
|
|
78
|
+
'hook.statusline.phase_count': {
|
|
79
|
+
reach: 'business',
|
|
80
|
+
developer: 'ph {num}/{total}',
|
|
81
|
+
engineer: 'phase {num}/{total}',
|
|
82
|
+
business: 'stage {num} of {total}',
|
|
83
|
+
part: true,
|
|
84
|
+
},
|
|
85
|
+
'hook.statusline.phase_named': {
|
|
86
|
+
reach: 'business',
|
|
87
|
+
developer: '{name} ({num}/{total})',
|
|
88
|
+
engineer: '{name} (phase {num}/{total})',
|
|
89
|
+
business: '{name} (stage {num} of {total})',
|
|
90
|
+
part: true,
|
|
91
|
+
},
|
|
92
|
+
'hook.statusline.status_shipped': {
|
|
93
|
+
reach: 'business',
|
|
94
|
+
developer: 'Phase {number} shipped — PR #{pr}',
|
|
95
|
+
engineer: 'phase {number} shipped (PR #{pr})',
|
|
96
|
+
business: 'stage {number} sent for review (#{pr})',
|
|
97
|
+
part: true,
|
|
98
|
+
},
|
|
99
|
+
// ─── update banner ─────────────────────────────────────────────────────────
|
|
100
|
+
'hook.banner.update_available': {
|
|
101
|
+
reach: 'business',
|
|
102
|
+
developer: 'pp-core update available: {installed} → {latest}. Run /pp-update.',
|
|
103
|
+
engineer: 'pp-core {latest} is available (you have {installed}). Run /pp-update to install it.',
|
|
104
|
+
business: 'A new version of pp-core is ready ({installed} → {latest}). Type /pp-update to install it.',
|
|
105
|
+
explain: 'A newer version of pp-core is available. Nothing has changed on your machine yet: typing /pp-update installs it, and your work stays as it is.',
|
|
106
|
+
},
|
|
107
|
+
'hook.banner.check_failed': {
|
|
108
|
+
reach: 'business',
|
|
109
|
+
developer: 'pp-core update check failed.',
|
|
110
|
+
engineer: 'pp-core could not check for updates; it tries again next session.',
|
|
111
|
+
business: 'pp-core could not check for a new version. You can carry on; it will try again next time.',
|
|
112
|
+
explain: 'pp-core looks for a newer version when a session starts, and this time it could not reach the answer. Nothing is wrong with your work, and the notice appears at most once a day.',
|
|
113
|
+
},
|
|
114
|
+
});
|