@emiliosp/pi-maestro 0.10.1 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/ADR.md +94 -18
  2. package/CHANGELOG.md +87 -33
  3. package/MISSION.md +4 -4
  4. package/README.md +66 -22
  5. package/ROADMAP.md +141 -112
  6. package/TECH_STACK.md +12 -11
  7. package/agents/builder.md +53 -57
  8. package/agents/simplifier.md +232 -0
  9. package/agents/verifier.md +52 -79
  10. package/docs/configuration.md +27 -16
  11. package/docs/glossary.md +47 -39
  12. package/docs/subagent-integration.md +22 -13
  13. package/docs/workflow.md +207 -103
  14. package/extensions/maestro-subagent.ts +4 -1
  15. package/extensions/maestro.ts +15 -26
  16. package/package.json +38 -39
  17. package/src/MaestroPaths.ts +26 -35
  18. package/src/artifacts/builder-handoff/assertBuilderHandoff.ts +6 -15
  19. package/src/artifacts/builder-handoff/schema.ts +3 -6
  20. package/src/artifacts/simplifier-handoff/assertSimplifierHandoff.ts +56 -0
  21. package/src/artifacts/simplifier-handoff/readSimplifierHandoff.ts +29 -0
  22. package/src/artifacts/simplifier-handoff/schema.ts +27 -0
  23. package/src/artifacts/verifier-handoff/assertVerifierHandoff.ts +4 -10
  24. package/src/artifacts/verifier-handoff/schema.ts +3 -6
  25. package/src/artifacts/verifier-handoff/writeVerifierHandoff.ts +1 -3
  26. package/src/config/assertConfiguration.ts +4 -7
  27. package/src/config/defaults.ts +8 -5
  28. package/src/config/loadConfiguration.ts +5 -11
  29. package/src/config/schema.ts +4 -2
  30. package/src/ids/createSpecId.ts +1 -2
  31. package/src/ids/isValidSpecId.ts +1 -2
  32. package/src/maestro/checks/assertEnvironment.ts +21 -48
  33. package/src/maestro/instructions/getMaestroInstructions.ts +59 -30
  34. package/src/maestro/status/formatMaestroStatus.ts +7 -13
  35. package/src/maestro/status/refreshMaestroStatus.ts +3 -7
  36. package/src/specs/create.ts +14 -4
  37. package/src/specs/template.ts +10 -14
  38. package/src/tools/child/record-builder-handoff.ts +1 -0
  39. package/src/tools/child/record-simplifier-handoff.ts +73 -0
  40. package/src/tools/child/record-verifier-handoff.ts +2 -3
  41. package/src/tools/child/utils/resolveWorkflowContext.ts +1 -4
  42. package/src/tools/main/create-spec.ts +3 -2
  43. package/src/tools/main/mark-spec-ready.ts +2 -1
  44. package/src/tools/main/resolve-escalations.ts +1 -0
  45. package/src/tools/main/resolve-findings.ts +7 -21
  46. package/src/tools/main/run-builder.ts +37 -57
  47. package/src/tools/main/run-simplifier.ts +172 -0
  48. package/src/tools/main/run-verifier.ts +34 -58
  49. package/src/tools/utils/pi-subagent-delegation.ts +13 -22
  50. package/src/tools/utils/resolveToolRunContext.ts +2 -3
  51. package/src/utils/is-errno-exception.ts +1 -3
  52. package/src/utils/path-exists.ts +1 -0
  53. package/src/utils/path-strictly-within.ts +3 -6
  54. package/src/utils/path-within-or-equal.ts +1 -4
  55. package/src/utils/read-json.ts +1 -4
  56. package/src/utils/write-json.ts +1 -4
  57. package/src/workflow/builder/completeBuilderPass.ts +3 -2
  58. package/src/workflow/builder/prepareBuilderRun.ts +3 -8
  59. package/src/workflow/builder/resolveEscalations.ts +2 -6
  60. package/src/workflow/builder/utils/getWorkflowEventByBuilderHandoff.ts +1 -3
  61. package/src/workflow/roles.ts +2 -1
  62. package/src/workflow/simplifier/completeSimplifierPass.ts +56 -0
  63. package/src/workflow/spec/markSpecReady.ts +10 -4
  64. package/src/workflow/state/readWorkflowState.ts +2 -7
  65. package/src/workflow/state/schema.ts +9 -10
  66. package/src/workflow/state/writeWorkflowState.ts +1 -4
  67. package/src/workflow/transitions.ts +12 -12
  68. package/src/workflow/utils/assertSpecAcceptanceCriteria.ts +2 -1
  69. package/src/workflow/utils/getAgentRole.ts +6 -4
  70. package/src/workflow/verifier/completeVerifierPass.ts +1 -0
  71. package/src/workflow/verifier/resolveFindings.ts +9 -29
  72. package/src/workflow/verifier/utils/getWorkflowEventByVerifierHandoff.ts +5 -20
  73. package/templates/design.md +20 -0
  74. package/templates/proposal.md +23 -0
  75. package/templates/spec.md +21 -50
package/docs/workflow.md CHANGED
@@ -2,40 +2,42 @@
2
2
 
3
3
  `Maestro` manages one spec-driven workflow in the current Pi session. The `owner` works directly with `Maestro`.
4
4
 
5
- The approved `spec.md` defines behavior, scope, constraints, technical decisions, and `acceptance criteria` for the change.
5
+ The approved `spec` is one document set: `proposal.md` explains motivation and scope, `spec.md` defines behavior and `acceptance criteria`, and optional `design.md`
6
+ records significant technical decisions. The set forms one contract for the change.
6
7
 
7
- An `acceptance criterion` contains a coverage label, a `probe`, an `expected result`, and an example. A `probe` is a scenario used to test behavior.
8
+ An `acceptance criterion` contains a `probe`, an `expected result`, and an example. A `probe` is a scenario used to test behavior.
8
9
 
9
- A `handoff` is a saved report from a `builder` or `verifier` `run`. It records the result, `probe` outcomes, and notes.
10
+ A `handoff` is a saved agent report. `Builder` and `verifier` reports contain `probe` outcomes. The simplifier's report records refactored files, a summary, and notes.
10
11
 
11
- A `builder` `handoff` can contain `escalations`, which are questions that need `owner` decisions.
12
- A `verifier` `handoff` can contain `findings`, which are technical issues.
12
+ A `builder` `handoff` can contain `escalations`, which are questions that need `owner` decisions. A `verifier` `handoff` can contain `findings`, which are technical
13
+ issues.
13
14
 
14
15
  ## Roles
15
16
 
16
- | Role | Responsibility |
17
- |---|---|
18
- | `Owner` | Decides requirements, scope, technical decisions, `spec` approval, `escalation` answers, and `finding` decisions. Performs the final review. |
19
- | `Maestro` | Prepares the `spec` with the `owner`, records workflow progress, runs agents, presents issues, and saves `owner` decisions. |
20
- | `Builder` | Implements the approved `spec` and runs every `probe`. Reports completion or an `escalation`, including technical problems that prevent completion. |
21
- | `Verifier` | Independently runs every `probe` against the live project files. Reports `findings` without repairing product code. |
17
+ | Role | Responsibility |
18
+ | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------- |
19
+ | `Owner` | Decides requirements, scope, technical decisions, `spec` approval, `escalation` answers, and `finding` decisions. Performs the final review. |
20
+ | `Maestro` | Prepares the `spec` with the `owner`, records workflow progress, runs agents, presents issues, and saves `owner` decisions. |
21
+ | `Builder` | Implements the approved `spec` and runs every `probe`. Reports completion or an `escalation`, including technical problems that prevent completion. |
22
+ | `Verifier` | Independently runs every `probe` against the live project files. Reports `findings` without repairing product code. |
23
+ | `Simplifier` | Refactors accepted code for clarity without changing behavior or introducing check failures. |
22
24
 
23
- `Builder` and `verifier` `runs` are sequential foreground operations. Each starts with a fresh conversation and reads the `spec` and saved `artifacts`.
25
+ `Builder`, `verifier`, and `simplifier` `runs` are sequential foreground operations. Each starts with a fresh conversation and reads the `spec` and saved `artifacts`.
24
26
 
25
27
  ## Observability
26
28
 
27
- `Observability` is the owner's ability to inspect workflow progress and reported results.
29
+ `Observability` is the owner's ability to inspect workflow progress and reported results.
28
30
 
29
- Maestro's Pi status shows the current phase.
31
+ Maestro's Pi status shows the current phase.
30
32
 
31
33
  `pi-subagents` FleetView and `/subagents-fleet` show live agent activity and transcripts.
32
34
 
33
- Saved `handoffs` provide a structured account of each reported `run`.
34
- The `builder` reports its outcome, `probe` results, notes, and any `escalation` questions.
35
- The `verifier` reports its independent checks, results, and `findings`.
36
- Recorded `owner` decisions explain how questions and issues were resolved. Earlier numbered reports remain available for inspection.
35
+ Saved `handoffs` provide a structured account of each reported `run`. The `builder` reports its outcome, `probe` results, notes, and any `escalation` questions. The
36
+ `verifier` reports its independent checks, results, and `findings`. The `simplifier` reports its refactoring separately. Recorded `owner` decisions explain how questions
37
+ and issues were resolved. Earlier numbered reports remain available for inspection.
37
38
 
38
- For example, the `owner` can read `B1.json` to see what the `builder` reports implementing and which `probes` it ran. `V1.json` shows what the `verifier` reports checking independently and which issues it found.
39
+ For example, the `owner` can read `B1.json` to see what the `builder` reports implementing and which `probes` it ran. `V1.json` shows what the `verifier` reports checking
40
+ independently and which issues it found.
39
41
 
40
42
  ## Main flow
41
43
 
@@ -49,94 +51,171 @@ flowchart TD
49
51
  buildOutcome{Builder outcome}
50
52
  verify[Verifier checks live project files]
51
53
  findings{Findings?}
54
+ simplify[Simplifier refactors accepted code]
52
55
  candidate[Candidate ready]
53
56
  summary[Maestro summarizes results]
54
57
  review[Owner performs the final review]
55
-
56
58
  spec --> approval
57
59
  approval --> build
58
60
  build --> buildOutcome
59
61
  buildOutcome -->|Done| verify
60
62
  verify --> findings
61
- findings -->|None| candidate
62
-
63
+ findings -->|None| simplify
63
64
  buildOutcome -->|Escalation| ownerEscalation{Owner decides every question}
64
65
  ownerEscalation --> recordEscalation[Maestro records all answers]
65
66
  recordEscalation -->|Spec unchanged| build
66
67
  recordEscalation -->|Spec changes| reviseSpec[Owner and Maestro revise the spec]
67
68
  reviseSpec --> approval
68
-
69
69
  findings -->|One or more| ownerFindings[Owner decides every finding]
70
70
  ownerFindings --> recordFindings[Maestro records all decisions]
71
- recordFindings -->|Reject all with reasons| candidate
71
+ recordFindings -->|Reject all with reasons| simplify
72
72
  recordFindings -->|Fix code without spec changes| build
73
73
  recordFindings -->|Spec changes| reviseSpec
74
-
74
+ simplify --> candidate
75
75
  candidate --> summary
76
76
  summary --> review
77
-
78
- linkStyle 0,1,2,3,4,5,16,17 stroke:#2e7d32,stroke-width:3px
77
+ linkStyle 0,1,2,3,4,5,16,17,18 stroke: #2e7d32, stroke-width: 3px
79
78
  ```
80
79
 
81
80
  ## Workflow phases
82
81
 
83
- Each `spec` has a `workflow.json` file that records its identity and current phase. The saved phase controls the next permitted workflow action. An agent's final message alone does not establish a completed action.
82
+ Each `spec` has a `workflow.json` file that records its identity and current phase. The saved phase controls the next permitted workflow action. An agent's final message
83
+ alone does not establish a completed action.
84
84
 
85
85
  The default path is `.specs/<spec-id>/workflow.json`. The `spec` directory is [configurable](configuration.md).
86
86
 
87
- | Phase | Meaning |
88
- |---|---|
89
- | `drafting-spec` | The `owner` and `Maestro` prepare the initial `spec` or revise it after recorded `escalation` answers or `finding` decisions. |
90
- | `ready-for-builder` | The approved `spec` or recorded `owner` decisions permit a `builder` `run`. |
91
- | `builder-running` | A `builder` `run` is active. |
92
- | `escalation-decisions` | The `owner` must decide how to handle every `escalation` question. |
93
- | `ready-for-verifier` | The `builder` completed the work and the `verifier` can start. |
94
- | `verifier-running` | A `verifier` `run` is active. |
95
- | `finding-decisions` | The `owner` must decide how to handle every current `finding`. |
96
- | `candidate-ready` | The `verifier` reported no `findings`, or the `owner` rejected every `finding` with a reason. The workflow is complete. |
87
+ | Phase | Meaning |
88
+ | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
89
+ | `drafting-spec` | The `owner` and `Maestro` prepare the initial `spec` or revise it after recorded `escalation` answers or `finding` decisions. |
90
+ | `ready-for-builder` | The approved `spec` or recorded `owner` decisions permit a `builder` `run`. |
91
+ | `builder-running` | A `builder` `run` is active. |
92
+ | `escalation-decisions` | The `owner` must decide how to handle every `escalation` question. |
93
+ | `ready-for-verifier` | The `builder` completed the work and the `verifier` can start. |
94
+ | `verifier-running` | A `verifier` `run` is active. |
95
+ | `finding-decisions` | The `owner` must decide how to handle every current `finding`. |
96
+ | `simplifier-running` | Verification succeeded or the `owner` rejected all current `findings`. The `simplifier` can run or skip if Git is unavailable. |
97
+ | `candidate-ready` | Simplification completed. The workflow is complete. |
98
+
99
+ ## Specification documents
100
+
101
+ Each new `spec` uses these documents in the same directory:
102
+
103
+ | Document | Content | Presence |
104
+ | ------------- | ------------------------------------------------------------------------------------------------- | -------------------------------------------------------------- |
105
+ | `proposal.md` | Problem, goal, scope, and exclusions. | Always created. |
106
+ | `spec.md` | Required behavior, constraints, deltas, and `acceptance criteria` next to their requirements. | Always created. |
107
+ | `design.md` | Approved technical decisions, brief reasons, relevant contracts, risks, and prototype references. | Only when significant technical decisions need to be recorded. |
97
108
 
98
109
  ## Spec approval
99
110
 
100
111
  For the initial `spec`:
101
112
 
102
- 1. `Maestro` creates `spec.md` and `workflow.json` in `drafting-spec` and prepares the `spec` with the `owner`.
103
- 2. The `owner` reviews the requirements, scope, technical decisions, and `acceptance criteria`.
104
- 3. `Maestro` asks the `owner` to inspect the current `spec.md` and reply `GREEN FLAG` to approve it and start the `builder`.
113
+ 1. `Maestro` creates `proposal.md`, `spec.md`, and `workflow.json` in `drafting-spec`, then prepares the documents with the `owner`. It adds `design.md` only when needed.
114
+ 2. The `owner` reviews the complete document set: motivation, scope, requirements, `acceptance criteria`, and any approved technical decisions.
115
+ 3. `Maestro` asks the `owner` to inspect `proposal.md`, `spec.md`, and `design.md` when present and reply `GREEN FLAG` once to approve the entire set and start the
116
+ `builder`.
105
117
  4. After that reply, `Maestro` saves `ready-for-builder` and starts the `builder` in the foreground.
106
118
 
107
- Approval freezes the `spec`. The `spec` and its visual prototypes remain unchanged during `builder` and `verifier` execution. See [Spec revision](#spec-revision) for permitted revisions.
119
+ Approval freezes all present `spec` documents and visual prototypes together. None may change during `builder`, `verifier`, or `simplifier` execution. See
120
+ [Spec revision](#spec-revision) for permitted revisions.
121
+
122
+ ## Requirement deltas
123
+
124
+ Each requirement has exactly one `Delta` field. It describes the impact of the requirement against the current system's behavior.
125
+
126
+ | Value | Meaning |
127
+ | ---------- | ------------------------------------------------------------------------- |
128
+ | `added` | Introduces behavior or a constraint that did not exist before the change. |
129
+ | `modified` | Changes existing behavior or a constraint. |
130
+ | `removed` | Removes behavior that must no longer be available. |
131
+
132
+ The `spec` describes only requirements added, modified, or removed by the change. Existing behavior must continue working unless explicitly changed or removed. Unchanged
133
+ behavior is implicit, not an inventory of requirements to repeat in every `spec`.
134
+
135
+ For `modified` or `removed` requirements, a short `Before` description is included only when it helps explain the change. For example,
136
+ `Before: Tokens expire 30 minutes after issuance.`
137
+
138
+ ## Requirement coverage
139
+
140
+ Each requirement has its own section and a unique, stable ID, such as `REQ1`. Its `Verified by` field links to the `acceptance criteria` or existing tests that verify it.
141
+ The mapping appears only under the requirement, not again inside each `acceptance criterion`. Requirements use `### REQ<number>:` headings; their criteria immediately
142
+ follow as `#### AC<number>:` subsections. Each requirement-associated AC is defined once under its primary requirement; other requirements can link to it. AC numbering is
143
+ continuous across the whole document, including standalone regression criteria, not restarted for each requirement or section.
144
+
145
+ For example, a change that introduces persistent item titles can describe its requirement and linked `acceptance criterion` in `spec.md` as follows:
146
+
147
+ ```markdown
148
+ ### REQ1: Persist saved titles
149
+
150
+ Delta: added
151
+
152
+ Saving and reopening an item must preserve its title.
153
+
154
+ Verified by: [AC1](#ac1-saved-title-is-persisted)
155
+
156
+ #### AC1: Saved title is persisted
157
+
158
+ 1. Probe: Save a change to an item's title, then reopen the item.
159
+ 2. Expected result: The saved title is still present.
160
+ 3. Example: Change the title from "Draft" to "Ready", save, and reopen the item. The title is "Ready".
161
+ ```
162
+
163
+ A requirement can link to several `acceptance criteria`, and one criterion can verify several requirements (1:N). When an existing test covers the exact starting
164
+ conditions, action, and `expected result`, `Verified by` links to the test file relative to `spec.md` and includes the exact scenario name. No duplicate criterion is
165
+ needed. A requirement can reference both criteria and existing tests.
166
+
167
+ Before approval, `Maestro` follows the links and checks that their combined scenarios verify the whole requirement. Missing, partial, or uncertain coverage must be
168
+ resolved with an appropriate criterion or a confirmed existing test. References are updated when criterion headings or test locations change, including during `spec`
169
+ revisions.
108
170
 
109
171
  ## Acceptance criteria
110
172
 
111
- Each `acceptance criterion` has a unique ID and describes one observable result.
173
+ Each `acceptance criterion` has a unique ID and describes one observable result. A criterion can verify a changed requirement or check a relevant regression in existing
174
+ behavior without an associated requirement.
175
+
176
+ Standalone regression criteria belong in an optional `## Regression checks` section, with `### AC<number>:` headings. They do not need a `REQ` heading, `Delta`, or an
177
+ artificial requirement association. Only regressions relevant to the change belong here; unchanged requirements are not listed. The section is omitted when unnecessary.
178
+
179
+ For example, if saving item descriptions already works, adding title persistence may warrant this regression check without a new requirement for descriptions:
180
+
181
+ ```markdown
182
+ ## Regression checks
112
183
 
113
- Each criterion contains these parts:
184
+ ### AC2: Existing descriptions remain saved
114
185
 
115
- | Part | Content |
116
- |---|---|
117
- | Coverage | One label that states the scenario's purpose: `success`, `failure`, or `unchanged`. |
118
- | `Probe` | Starting conditions and the action or observation that checks the behavior. |
119
- | `Expected result` | The measurable result the `probe` observes. |
120
- | Example | Concrete starting conditions, an input or action, and the exact `expected result`. |
186
+ 1. Probe: Change and save the title of an item with a saved description, then reopen it.
187
+ 2. Expected result: The description is unchanged.
188
+ 3. Example: An item's saved description is "Buy milk". Change its title from "Draft" to "Shopping", save, and reopen it. Its description is still "Buy milk".
189
+ ```
190
+
191
+ Both nested and standalone criteria share one continuous AC sequence and are checked by the `builder` and `verifier`. Standalone criteria have the same fields as
192
+ requirement-associated criteria:
193
+
194
+ | Part | Content |
195
+ | ----------------- | ---------------------------------------------------------------------------------- |
196
+ | `Probe` | Starting conditions and the action or observation that checks the behavior. |
197
+ | `Expected result` | The measurable result the `probe` observes. |
198
+ | Example | Concrete starting conditions, an input or action, and the exact `expected result`. |
121
199
 
122
200
  ## Escalations
123
201
 
124
- An `escalation` returns an implementation decision or a technical problem to the `owner`.
125
- For instance a technical failure, an undefined behavior, a conflict with the `spec`, or a possible scope change.
202
+ An `escalation` returns an implementation decision or a technical problem to the `owner`. For instance a technical failure, an undefined behavior, a conflict with the
203
+ `spec`, or a possible scope change.
126
204
 
127
- The `builder` saves all questions from one `pass` in the `escalations` list of its numbered `handoff`. `Maestro` identifies each question with both report and `escalation` IDs, such as `B1/E1`. See [Escalation references](glossary.md#escalation-references) for their scope.
205
+ The `builder` saves all questions from one `pass` in the `escalations` list of its numbered `handoff`. `Maestro` identifies each question with both report and
206
+ `escalation` IDs, such as `B1/E1`. See [Escalation references](glossary.md#escalation-references) for their scope.
128
207
 
129
208
  `Maestro` presents each question, evidence, options, consequences, and next steps. The workflow pauses in `escalation-decisions` while the `owner` decides how to proceed.
130
209
 
131
- The `owner` gives `Maestro` an answer and reason for every current question, whether or not the `spec` must change.
132
- The `owner` can select a listed option or give a different decision.
210
+ The `owner` gives `Maestro` an answer and reason for every current question, whether or not the `spec` must change. The `owner` can select a listed option or give a
211
+ different decision.
133
212
 
134
213
  `Maestro` saves all answers in the current `builder` `handoff` before the workflow continues.
135
214
 
136
- | `Owner` choice | Result |
137
- |---|---|
138
- | Keep the current `spec` | `Maestro` starts another `builder` `run` without renewed approval. |
139
- | Change the `spec` | The `owner` and `Maestro` revise the same `spec`. The `owner` reviews it and replies `GREEN FLAG` before another `builder` `run`. |
215
+ | `Owner` choice | Result |
216
+ | ----------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
217
+ | Keep the current `spec` | `Maestro` starts another `builder` `run` without renewed approval. |
218
+ | Change the `spec` | The `owner` and `Maestro` revise the same `spec`. The `owner` reviews it and replies `GREEN FLAG` before another `builder` `run`. |
140
219
 
141
220
  `Owner` decisions update only the questions' `resolution` fields. The handoff's other content and earlier `handoffs` remain unchanged.
142
221
 
@@ -144,71 +223,86 @@ The `owner` can select a listed option or give a different decision.
144
223
 
145
224
  Every current `finding` requires an `owner` decision, regardless of severity. `Maestro` explains the issue, evidence, practical effect, and available choices.
146
225
 
147
- `Maestro` identifies each `finding` with its report and `finding` IDs. For example, `V1/F2` means `finding` 2 in `verifier` report `V1.json`. The `finding` is an entry in that file's `findings` list, not a separate `F2.json` file. `Finding` numbers restart at `F1` in each `verifier` report. See [Finding references](glossary.md#finding-references) for a worked example.
226
+ `Maestro` identifies each `finding` with its report and `finding` IDs. For example, `V1/F2` means `finding` 2 in `verifier` report `V1.json`. The `finding` is an entry in
227
+ that file's `findings` list, not a separate `F2.json` file. `Finding` numbers restart at `F1` in each `verifier` report. See
228
+ [Finding references](glossary.md#finding-references) for a worked example.
148
229
 
149
- `Maestro` records `owner` decisions in the same `verifier` report, e.g. decisions about `V1/F2` update `V1.json`, not a new `V2.json`. A new `verifier` result creates the next report (`V2.json`).
230
+ `Maestro` records `owner` decisions in the same `verifier` report, e.g. decisions about `V1/F2` update `V1.json`, not a new `V2.json`. A new `verifier` result creates the
231
+ next report (`V2.json`).
150
232
 
151
- | Decision | Result |
152
- |---|---|
153
- | `reject` | Records the owner's reason. If every `finding` is rejected, the workflow reaches `candidate-ready`. |
154
- | `fix-code` | Keeps the current `spec` and returns to `ready-for-builder` for code fixes when no decision requires revision. |
155
- | `revise-spec` | Records the owner's reason and agreed requirement change, then returns to `drafting-spec`. |
233
+ | Decision | Result |
234
+ | ------------- | -------------------------------------------------------------------------------------------------------------- |
235
+ | `reject` | Records the owner's reason. If every `finding` is rejected, the workflow reaches `simplifier-running`. |
236
+ | `fix-code` | Keeps the current `spec` and returns to `ready-for-builder` for code fixes when no decision requires revision. |
237
+ | `revise-spec` | Records the owner's reason and agreed requirement change, then returns to `drafting-spec`. |
156
238
 
157
- `Maestro` saves every current decision together before the phase changes.
158
- If any `finding` requires revision, revision takes priority over code fixes and rejections. See [Spec revision](#spec-revision).
239
+ `Maestro` saves every current decision together before the phase changes. If any `finding` requires revision, revision takes priority over code fixes and rejections. See
240
+ [Spec revision](#spec-revision).
159
241
 
160
- Without revision, any `fix-code` decision requires another `builder` `run`, including when other `findings` are rejected.
161
- After the `builder` completes the fixes, the `verifier` checks the work again.
242
+ Without revision, any `fix-code` decision requires another `builder` `run`, including when other `findings` are rejected. After the `builder` completes the fixes, the
243
+ `verifier` checks the work again.
162
244
 
163
245
  ## Spec revision
164
246
 
165
- For either `escalation` answers or `finding` decisions, `Maestro` records the complete batch before the workflow returns to `drafting-spec`.
166
- This decision does not approve the `spec` or start an agent.
167
- The `owner` and `Maestro` then revise the same `spec` together in `drafting-spec`.
247
+ For either `escalation` answers or `finding` decisions, `Maestro` records the complete batch before the workflow returns to `drafting-spec`. This decision does not
248
+ approve the `spec` or start an agent. The `owner` and `Maestro` then revise the same `spec` together in `drafting-spec`.
168
249
 
169
- The `owner` reviews the changes and replies `GREEN FLAG` again.
170
- `Maestro` records that renewed approval separately, moves to `ready-for-builder`, and starts another `builder` `run`.
171
- Approval is permitted only in `drafting-spec`, not directly from either decision phase.
250
+ The `owner` reviews the complete revised set of `proposal.md`, `spec.md`, and `design.md` when present and replies `GREEN FLAG` once again. `Maestro` records that renewed
251
+ approval separately, moves to `ready-for-builder`, and starts another `builder` `run`. Approval is permitted only in `drafting-spec`, not directly from either decision
252
+ phase.
172
253
 
173
- The revised `spec` controls subsequent work.
174
- Earlier `escalations`, `findings`, and their decisions remain historical context.
254
+ The revised `spec` controls subsequent work. Earlier `escalations`, `findings`, and their decisions remain historical context.
175
255
 
176
256
  ## Verification boundary
177
257
 
178
- The `verifier` can make temporary changes for `probes`. Before submitting its `handoff`, it restores the exact original contents of affected files and removes only files it created.
258
+ The `verifier` can make temporary changes for `probes`. Before submitting its `handoff`, it restores the exact original contents of affected files and removes only files
259
+ it created.
179
260
 
180
261
  Cleanup relies on the `verifier`. If cleanup cannot finish safely, the `verifier` stops and reports the remaining changes.
181
262
 
263
+ ## Simplification
264
+
265
+ After a successful verification, Maestro starts the `simplifier`. The `simplifier` runs only if Git is available, if not, a warning is displayed:
266
+ `Simplifier skipped: Git repository unavailable.`
267
+
268
+ The `simplifier` starts from all staged, unstaged, and untracked code changes, including pre-existing changes. It preserves observable behavior and introduces no new
269
+ check failures. If no code needs refactoring, the `simplifier` does not make any change.
270
+
182
271
  ## Workflow completion
183
272
 
184
- The workflow ends at `candidate-ready`. `Maestro` summarizes the changes, verification results, rejected `findings` and reasons, and relevant `builder` notes from the saved `artifacts`.
273
+ The workflow ends at `candidate-ready`. `Maestro` summarizes the changes, verification results, rejected `findings` and reasons, relevant `builder` notes from the saved
274
+ `artifacts`, and simplifier's summary and notes
185
275
 
186
276
  The `owner` performs the final review and controls any later Git use, pull request, or merge. Changes after completion are outside the completed verification.
187
277
 
188
278
  ## Stored artifacts
189
279
 
190
- An `artifact` is a saved workflow file. `Maestro` creates the `spec` directory with `spec.md`, `workflow.json`, and an empty `prototypes/` directory. `Builder` and `verifier` `handoff` directories appear when those results are saved.
280
+ An `artifact` is a saved workflow file. `Maestro` creates the `spec` directory with `proposal.md`, `spec.md`, `workflow.json`, and an empty `prototypes/` directory.
281
+ `design.md` is created during drafting only when needed. `Builder`, `verifier`, and `simplifier` `handoff` directories appear when those results are saved.
191
282
 
192
- The agents submit results through `Maestro` tools instead of writing the reports directly. A successful submission saves the result and updates the phase in `workflow.json` before the agent returns.
283
+ The agents submit results through `Maestro` tools instead of writing the reports directly. A successful submission saves the result and updates the phase in
284
+ `workflow.json` before the agent returns.
193
285
 
194
- `Builder` (`B`) and `verifier` (`V`) numbers count saved `handoffs` within one `spec`. Each sequence starts at 1 and advances independently. Every saved `builder` outcome, including `escalation`, creates the next `B` report. Revising the same `spec` keeps these sequences. A new `spec` starts new sequences.
286
+ `Builder` (`B`) and `verifier` (`V`) numbers count saved `handoffs` within one `spec`. Each sequence starts at 1 and advances independently. Every saved `builder`
287
+ outcome, including `escalation`, creates the next `B` report. Revising the same `spec` keeps these sequences. A new `spec` starts new sequences.
195
288
 
196
289
  `Escalation` (`E`) numbers identify questions within a `builder` `handoff`. They restart at `E1` in each `handoff`.
197
290
 
198
291
  For example, a repair cycle with successful `builder` results produces these files:
199
292
 
200
- | Step | Action | Report saved or updated |
201
- |---|---|---|
202
- | 1 | The `builder` completes the implementation. | Creates `handoffs/builder/B1.json`. |
203
- | 2 | The `verifier` checks it and reports `findings`. | Creates `handoffs/verifier/V1.json`. |
204
- | 3 | The `owner` decides every `finding` and requests a code fix. | Updates decisions in the existing `V1.json`. |
205
- | 4 | A new `builder` `run` completes the fixes. | Creates `handoffs/builder/B2.json`. |
206
- | 5 | A new `verifier` `run` checks the work again and reports no `findings`. | Creates `handoffs/verifier/V2.json`. The workflow reaches `candidate-ready`. |
293
+ | Step | Action | Report saved or updated |
294
+ | ---- | ----------------------------------------------------------------------- | ------------------------------------------------------------------------------- |
295
+ | 1 | The `builder` completes the implementation. | Creates `handoffs/builder/B1.json`. |
296
+ | 2 | The `verifier` checks it and reports `findings`. | Creates `handoffs/verifier/V1.json`. |
297
+ | 3 | The `owner` decides every `finding` and requests a code fix. | Updates decisions in the existing `V1.json`. |
298
+ | 4 | A new `builder` `run` completes the fixes. | Creates `handoffs/builder/B2.json`. |
299
+ | 5 | A new `verifier` `run` checks the work again and reports no `findings`. | Creates `handoffs/verifier/V2.json`. The workflow reaches `simplifier-running`. |
300
+ | 6 | The `simplifier` completes its refactoring. | Creates `handoffs/simplifier/S.json`, then saves `candidate-ready`. |
207
301
 
208
302
  If the first `builder` `run` escalates, it creates `B1.json` with its questions. `Owner` answers update `B1.json`. The next saved `builder` result creates `B2.json`.
209
303
 
210
- A `builder` report has `status: done` or `status: escalation`. A `done` report requires every recorded `probe` to pass and an empty `escalations` list.
211
- An `escalation` retains actual `probe` results: `passed`, `failed`, or `not-run`.
304
+ A `builder` report has `status: done` or `status: escalation`. A `done` report requires every recorded `probe` to pass and an empty `escalations` list. An `escalation`
305
+ retains actual `probe` results: `passed`, `failed`, or `not-run`.
212
306
 
213
307
  Execution errors or missing or invalid saved results stop the workflow. See [Limitations](#limitations).
214
308
 
@@ -216,32 +310,42 @@ The default layout after multiple `runs` is:
216
310
 
217
311
  ```text
218
312
  .specs/<spec-id>/
313
+ ├── proposal.md
219
314
  ├── spec.md
315
+ ├── design.md # only when needed
220
316
  ├── workflow.json
221
317
  ├── handoffs/
222
318
  │ ├── builder/
223
319
  │ │ ├── B1.json
224
320
  │ │ └── B2.json
225
- │ └── verifier/
226
- │ ├── V1.json
227
- │ └── V2.json
321
+ │ ├── verifier/
322
+ │ │ ├── V1.json
323
+ │ │ └── V2.json
324
+ │ └── simplifier/
325
+ │ └── S.json
228
326
  └── prototypes/
229
327
  ```
230
328
 
231
- `Maestro` uses the latest saved `handoff` in each role's sequence as the active result. New results do not replace earlier numbered reports. Earlier reports remain available as context, not as proof for the current `run`. `Owner` decisions update the active `builder` or `verifier` `handoff` without creating another numbered report.
329
+ `Maestro` uses the latest saved `builder` and `verifier` `handoffs` as their active results. New results do not replace earlier numbered reports. Earlier reports remain
330
+ available as context, not as proof for the current `run`. `Owner` decisions update the active `builder` or `verifier` `handoff` without creating another numbered report.
232
331
 
233
332
  ## Limitations
234
333
 
235
334
  ### No small models
236
- The `owner` must not use small models with a `low` thinking level for this workflow. These combinations cannot reliably follow the workflow rules.
237
- One example is `gpt-luna-6` with `thinking: "low"`.
238
335
 
239
- Moreover, the workflow works well with a defined harness: tests, lint for code rules, anti-slop checks for unwanted patterns, and `AGENTS.md`. `Maestro` does not supply these project-specific checks.
336
+ The `owner` must not use small models with a `low` thinking level for this workflow. These combinations cannot reliably follow the workflow rules. One example is
337
+ `gpt-luna-6` with `thinking: "low"`.
338
+
339
+ Moreover, the workflow works well with a defined harness: tests, lint for code rules, anti-slop checks for unwanted patterns, and `AGENTS.md`. `Maestro` does not supply
340
+ these project-specific checks.
240
341
 
241
342
  ### No automatic rollback
242
- Launch errors, delegation failures, timeouts, interruptions, cancellations, and missing or invalid `handoffs` stop the workflow without a recovery transition.
243
- If a `run` saves no completed transition, its saved running phase remains unchanged. Partial protocol writes require manual `owner` follow-up.
244
- `Maestro` provides no automatic rollback, repair, or recovery for these errors. The files that remain are available for `owner` inspection.
343
+
344
+ Launch errors, delegation failures, timeouts, interruptions, cancellations, and missing or invalid `handoffs` stop the workflow without a recovery transition. If a `run`
345
+ saves no completed transition, its saved running phase remains unchanged. Partial protocol writes require manual `owner` follow-up. `Maestro` provides no automatic
346
+ rollback, repair, or recovery for these errors. The files that remain are available for `owner` inspection.
245
347
 
246
348
  ### No reconciliation
247
- Disabling `Maestro`, restarting Pi, or using `/resume` clears live `Maestro` session state and leaves project files unchanged. `Maestro` starts disabled in a new or resumed session. Reactivating it does not reconstruct or resume a saved workflow.
349
+
350
+ Disabling `Maestro`, restarting Pi, or using `/resume` clears live `Maestro` session state and leaves project files unchanged. `Maestro` starts disabled in a new or
351
+ resumed session. Reactivating it does not reconstruct or resume a saved workflow.
@@ -1,13 +1,16 @@
1
1
  /**
2
- * Objective: Compose the Maestro extension for builder and verifier subagent sessions.
2
+ * Objective: Compose the Maestro extension for builder, verifier, and simplifier subagent sessions.
3
3
  * Used: When Pi starts a Maestro subagent session.
4
4
  */
5
5
 
6
6
  import type { ExtensionAPI } from '@earendil-works/pi-coding-agent';
7
+
7
8
  import { registerRecordBuilderHandoffTool } from '#tools/child/record-builder-handoff.ts';
9
+ import { registerRecordSimplifierHandoffTool } from '#tools/child/record-simplifier-handoff.ts';
8
10
  import { registerRecordVerifierHandoffTool } from '#tools/child/record-verifier-handoff.ts';
9
11
 
10
12
  export default (pi: ExtensionAPI): void => {
11
13
  registerRecordBuilderHandoffTool(pi);
12
14
  registerRecordVerifierHandoffTool(pi);
15
+ registerRecordSimplifierHandoffTool(pi);
13
16
  };
@@ -4,19 +4,14 @@
4
4
  */
5
5
 
6
6
  import type { ExtensionAPI } from '@earendil-works/pi-coding-agent';
7
+
7
8
  import { loadConfiguration } from '#config/loadConfiguration.ts';
8
9
  import { assertEnvironment } from '#maestro/checks/assertEnvironment.ts';
9
10
  import { getMaestroInstructions } from '#maestro/instructions/getMaestroInstructions.ts';
10
11
  import maestroSessionState from '#maestro/session/MaestroSessionState.ts';
11
12
  import { refreshMaestroStatus } from '#maestro/status/refreshMaestroStatus.ts';
12
- import {
13
- CREATE_SPEC_TOOL,
14
- registerCreateSpecTool,
15
- } from '#tools/main/create-spec.ts';
16
- import {
17
- MARK_SPEC_READY_TOOL,
18
- registerMarkSpecReadyTool,
19
- } from '#tools/main/mark-spec-ready.ts';
13
+ import { CREATE_SPEC_TOOL, registerCreateSpecTool } from '#tools/main/create-spec.ts';
14
+ import { MARK_SPEC_READY_TOOL, registerMarkSpecReadyTool } from '#tools/main/mark-spec-ready.ts';
20
15
  import {
21
16
  RESOLVE_ESCALATIONS_TOOL,
22
17
  registerResolveEscalationsTool,
@@ -25,14 +20,9 @@ import {
25
20
  RESOLVE_FINDINGS_TOOL,
26
21
  registerResolveFindingsTool,
27
22
  } from '#tools/main/resolve-findings.ts';
28
- import {
29
- RUN_BUILDER_TOOL,
30
- registerRunBuilderTool,
31
- } from '#tools/main/run-builder.ts';
32
- import {
33
- RUN_VERIFIER_TOOL,
34
- registerRunVerifierTool,
35
- } from '#tools/main/run-verifier.ts';
23
+ import { RUN_BUILDER_TOOL, registerRunBuilderTool } from '#tools/main/run-builder.ts';
24
+ import { RUN_SIMPLIFIER_TOOL, registerRunSimplifierTool } from '#tools/main/run-simplifier.ts';
25
+ import { RUN_VERIFIER_TOOL, registerRunVerifierTool } from '#tools/main/run-verifier.ts';
36
26
 
37
27
  const MAIN_TOOL_NAMES: readonly string[] = [
38
28
  CREATE_SPEC_TOOL.NAME,
@@ -41,6 +31,7 @@ const MAIN_TOOL_NAMES: readonly string[] = [
41
31
  RESOLVE_ESCALATIONS_TOOL.NAME,
42
32
  RUN_VERIFIER_TOOL.NAME,
43
33
  RESOLVE_FINDINGS_TOOL.NAME,
34
+ RUN_SIMPLIFIER_TOOL.NAME,
44
35
  ];
45
36
 
46
37
  export default (pi: ExtensionAPI): void => {
@@ -50,16 +41,13 @@ export default (pi: ExtensionAPI): void => {
50
41
  registerResolveEscalationsTool(pi);
51
42
  registerRunVerifierTool(pi);
52
43
  registerResolveFindingsTool(pi);
44
+ registerRunSimplifierTool(pi);
53
45
 
54
46
  const syncMainTools = (): void => {
55
- const foreignTools = pi
56
- .getActiveTools()
57
- .filter((name) => !MAIN_TOOL_NAMES.includes(name));
47
+ const foreignTools = pi.getActiveTools().filter((name) => !MAIN_TOOL_NAMES.includes(name));
58
48
 
59
49
  pi.setActiveTools(
60
- maestroSessionState.isActive()
61
- ? [...foreignTools, ...MAIN_TOOL_NAMES]
62
- : foreignTools,
50
+ maestroSessionState.isActive() ? [...foreignTools, ...MAIN_TOOL_NAMES] : foreignTools,
63
51
  );
64
52
  };
65
53
 
@@ -104,14 +92,15 @@ export default (pi: ExtensionAPI): void => {
104
92
  'accent',
105
93
  `Verifier (${config.verifier.model} ${config.verifier.thinking})`,
106
94
  ),
95
+ context.ui.theme.fg(
96
+ 'accent',
97
+ `Simplifier (${config.simplifier.model} ${config.simplifier.thinking})`,
98
+ ),
107
99
  ].join('\n'),
108
100
  'info',
109
101
  );
110
102
  } catch (error) {
111
- context.ui.notify(
112
- error instanceof Error ? error.message : String(error),
113
- 'error',
114
- );
103
+ context.ui.notify(error instanceof Error ? error.message : String(error), 'error');
115
104
 
116
105
  return;
117
106
  }