@emiliosp/pi-maestro 0.14.0 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ADR.md +155 -0
- package/CHANGELOG.md +19 -0
- package/README.md +33 -19
- package/ROADMAP.md +176 -40
- package/agents/simplifier.md +2 -1
- package/agents/verifier.md +2 -1
- package/docs/configuration.md +49 -26
- package/docs/glossary.md +1 -1
- package/docs/subagent-integration.md +8 -6
- package/docs/workflow.md +32 -23
- package/extensions/maestro.ts +11 -13
- package/package.json +3 -3
- package/src/artifacts/builder-handoff/schema.ts +1 -2
- package/src/config/assertConfiguration.ts +0 -6
- package/src/config/defaults.ts +3 -5
- package/src/config/schema.ts +2 -14
- package/src/maestro/checks/assertEnvironment.ts +24 -9
- package/src/maestro/instructions/getMaestroInstructions.ts +19 -11
- package/src/tools/child/record-builder-handoff.ts +2 -6
- package/src/tools/child/record-simplifier-handoff.ts +2 -1
- package/src/tools/child/record-verifier-handoff.ts +2 -6
- package/src/tools/child/utils/resolveWorkflowContext.ts +2 -2
- package/src/tools/main/mark-spec-ready.ts +8 -3
- package/src/tools/main/resolve-escalations.ts +2 -1
- package/src/tools/main/resolve-findings.ts +9 -10
- package/src/tools/main/run-builder.ts +47 -15
- package/src/tools/main/run-simplifier.ts +3 -3
- package/src/tools/main/run-verifier.ts +19 -8
- package/src/tools/utils/pi-subagent-delegation.ts +3 -0
- package/src/workflow/builder/completeBuilderPass.ts +4 -0
- package/src/workflow/builder/prepareBuilderRun.ts +7 -1
- package/src/workflow/builder/resolveEscalations.ts +4 -0
- package/src/workflow/simplifier/completeSimplifierPass.ts +4 -0
- package/src/workflow/spec/markSpecReady.ts +4 -0
- package/src/workflow/transitions.ts +28 -7
- package/src/workflow/verifier/completeVerifierPass.ts +4 -0
- package/src/workflow/verifier/prepareVerifierRun.ts +7 -1
- package/src/workflow/verifier/resolveFindings.ts +4 -0
package/docs/configuration.md
CHANGED
|
@@ -15,41 +15,41 @@ For example, if Pi starts in `/work/app/src`, `Maestro` reads `/work/app/src/.pi
|
|
|
15
15
|
"version": "1.0.0",
|
|
16
16
|
"specDirectory": ".specs",
|
|
17
17
|
"builder": {
|
|
18
|
+
"required": true,
|
|
18
19
|
"model": "openai-codex/gpt-5.6-luna",
|
|
19
|
-
"thinking": "max"
|
|
20
|
-
"timeoutMinutes": 60
|
|
20
|
+
"thinking": "max"
|
|
21
21
|
},
|
|
22
22
|
"simplifier": {
|
|
23
|
+
"required": true,
|
|
23
24
|
"model": "openai-codex/gpt-6.1-sol",
|
|
24
|
-
"thinking": "high"
|
|
25
|
-
"timeoutMinutes": 60
|
|
25
|
+
"thinking": "high"
|
|
26
26
|
},
|
|
27
27
|
"verifier": {
|
|
28
|
+
"required": true,
|
|
28
29
|
"model": "openai-codex/gpt-6.1-sol",
|
|
29
|
-
"thinking": "high"
|
|
30
|
-
"timeoutMinutes": 60
|
|
30
|
+
"thinking": "high"
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
```
|
|
34
34
|
|
|
35
35
|
## Fields
|
|
36
36
|
|
|
37
|
-
| Field
|
|
38
|
-
|
|
|
39
|
-
| `version`
|
|
40
|
-
| `specDirectory`
|
|
41
|
-
| `builder`
|
|
42
|
-
| `builder.
|
|
43
|
-
| `builder.
|
|
44
|
-
| `builder.
|
|
45
|
-
| `verifier`
|
|
46
|
-
| `verifier.
|
|
47
|
-
| `verifier.
|
|
48
|
-
| `verifier.
|
|
49
|
-
| `simplifier`
|
|
50
|
-
| `simplifier.
|
|
51
|
-
| `simplifier.
|
|
52
|
-
| `simplifier.
|
|
37
|
+
| Field | Required | Default | Rules |
|
|
38
|
+
| --------------------- | ------------------------: | --------------------------- | -------------------------------------------------------- |
|
|
39
|
+
| `version` | Yes, when the file exists | `1.0.0` | Configuration format version. Only `1.0.0` is supported. |
|
|
40
|
+
| `specDirectory` | No | `.specs` | Relative path below the project root. |
|
|
41
|
+
| `builder` | No | `Builder` defaults | Overrides supported `builder` fields. |
|
|
42
|
+
| `builder.required` | No | `true` | Boolean selecting the `builder` phase. |
|
|
43
|
+
| `builder.model` | No | `openai-codex/gpt-5.6-luna` | Model string passed unchanged to Pi. |
|
|
44
|
+
| `builder.thinking` | No | `max` | One supported thinking level. |
|
|
45
|
+
| `verifier` | No | `Verifier` defaults | Overrides supported `verifier` fields. |
|
|
46
|
+
| `verifier.required` | No | `true` | Boolean selecting the `verifier` phase. |
|
|
47
|
+
| `verifier.model` | No | `openai-codex/gpt-6.1-sol` | Model string passed unchanged to Pi. |
|
|
48
|
+
| `verifier.thinking` | No | `high` | One supported thinking level. |
|
|
49
|
+
| `simplifier` | No | `Simplifier` defaults | Overrides supported `simplifier` fields. |
|
|
50
|
+
| `simplifier.required` | No | `true` | Boolean selecting the `simplifier` phase. |
|
|
51
|
+
| `simplifier.model` | No | `openai-codex/gpt-6.1-sol` | Model string passed unchanged to Pi. |
|
|
52
|
+
| `simplifier.thinking` | No | `high` | One supported thinking level. |
|
|
53
53
|
|
|
54
54
|
Model values use the full `provider/model` identifier supplied by Pi's model registry, such as `openrouter/~openai/gpt-mini-latest`. Model IDs may contain additional
|
|
55
55
|
slashes. `Maestro` does not apply a separate format rule; it matches the complete identifier against Pi's available models and passes it unchanged through `pi-subagents`.
|
|
@@ -74,12 +74,31 @@ Only `version` is required when the file exists. Each other field overrides its
|
|
|
74
74
|
{
|
|
75
75
|
"version": "1.0.0",
|
|
76
76
|
"builder": {
|
|
77
|
-
"
|
|
77
|
+
"thinking": "high"
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
80
|
```
|
|
81
81
|
|
|
82
|
-
This example keeps every default except the `builder`
|
|
82
|
+
This example keeps every default except the `builder` thinking level.
|
|
83
|
+
|
|
84
|
+
## Phase selection
|
|
85
|
+
|
|
86
|
+
Set each agent's `required` boolean before activation and leave configuration unchanged until the workflow completes. Omitted flags default to `true`, even when an agent
|
|
87
|
+
section or the entire file is absent. Strings, numbers, and `null` are invalid.
|
|
88
|
+
|
|
89
|
+
With `builder.required: false`, approval completes the workflow with an approved `spec` and no agent execution, regardless of the other flags. The approved `spec` can be
|
|
90
|
+
used for implementation in another workflow. With `builder` enabled, `verifier` and `simplifier` can each be disabled independently. Neither runs without `builder`.
|
|
91
|
+
|
|
92
|
+
| `builder.required` | `verifier.required` | `simplifier.required` | Selected phases after approval |
|
|
93
|
+
| ------------------ | ------------------- | --------------------- | ------------------------------ |
|
|
94
|
+
| `false` | Any | Any | None; approved `spec` only |
|
|
95
|
+
| `true` | `false` | `false` | `Builder` only |
|
|
96
|
+
| `true` | `true` | `false` | `Builder`, then `verifier` |
|
|
97
|
+
| `true` | `false` | `true` | `Builder`, then `simplifier` |
|
|
98
|
+
| `true` | `true` | `true` | All three, in order |
|
|
99
|
+
|
|
100
|
+
Disabled phases do not require agent or model availability and produce no `handoff`. The final summary identifies skipped work rather than claiming it was performed.
|
|
101
|
+
Enabled simplification can still be skipped if Git is unavailable.
|
|
83
102
|
|
|
84
103
|
## Schema version
|
|
85
104
|
|
|
@@ -98,8 +117,12 @@ For example, `specDirectory: "planning/specs"` places `specs` in `<project-root>
|
|
|
98
117
|
|
|
99
118
|
## Model access
|
|
100
119
|
|
|
101
|
-
During activation, `Maestro` checks
|
|
102
|
-
availability; `Maestro` does not maintain a separate model list or authentication check. A missing model stops activation and identifies the full
|
|
120
|
+
During activation, `Maestro` checks only enabled agents and their configured models against `context.modelRegistry.getAvailable()`. Pi's registry is the source of truth
|
|
121
|
+
for model availability; `Maestro` does not maintain a separate model list or authentication check. A missing enabled model stops activation and identifies the full
|
|
122
|
+
configured identifier.
|
|
123
|
+
|
|
124
|
+
With `builder` disabled, activation checks only project trust and configuration, with no agent checks, model lookup, or `pi-subagents` ping. With `builder` enabled, the
|
|
125
|
+
availability ping remains required.
|
|
103
126
|
|
|
104
127
|
The `owner` can correct the identifier or authenticate the provider in Pi, then retry `/maestro`. Authentication or provider errors during delegation still appear as
|
|
105
128
|
`run` failures. Agent names and context are described in [Subagent integration](subagent-integration.md#roles-and-context).
|
package/docs/glossary.md
CHANGED
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
| `Candidate` | The project files created by agents after a workflow `run` |
|
|
21
21
|
| `Finding` | A technical issue that the `verifier` records for an `owner` decision. |
|
|
22
22
|
| `Escalation` | An implementation question or reportable technical problem that the `builder` records in its `handoff` for an `owner` decision. |
|
|
23
|
-
| `GREEN FLAG` | The owner's explicit reply that approves the current `spec` and
|
|
23
|
+
| `GREEN FLAG` | The owner's explicit reply that approves the current `spec` and proceeds through the selected phases. |
|
|
24
24
|
| `fix-code` | An `owner` decision that requests code fixes without changing the approved `spec`. |
|
|
25
25
|
| `revise-spec` | An `owner` decision that records a reason and agreed requirement change, then returns to `drafting-spec` for revision and renewed approval. |
|
|
26
26
|
| `reject` | An `owner` decision that declines a `finding` and records a reason. It does not mean that verification passed. |
|
|
@@ -16,11 +16,12 @@ The package supplies all three roles and the tools that save their results:
|
|
|
16
16
|
Each `run` starts with a fresh conversation, not the main session's conversation history. All three agents inherit project instructions, the owner's global `AGENTS.md`,
|
|
17
17
|
and available skills. The global file normally lives at `~/.pi/agent/AGENTS.md`.
|
|
18
18
|
|
|
19
|
-
`Maestro` supplies the `spec` ID, project directory, model, thinking level
|
|
20
|
-
|
|
19
|
+
`Maestro` supplies the `spec` ID, project directory, model, and thinking level. The agents read all approved documents (`proposal.md`, `spec.md`, and `design.md` when
|
|
20
|
+
present) and saved `artifacts` to understand the work. Earlier `artifacts` provide context, not proof.
|
|
21
21
|
|
|
22
|
-
The `owner` does not call agent tools directly. `Maestro` starts the `builder` after `GREEN FLAG` approval. The `verifier` starts after successful
|
|
23
|
-
|
|
22
|
+
The `owner` does not call agent tools directly. `Maestro` starts the enabled `builder` after `GREEN FLAG` approval. The enabled `verifier` starts after successful
|
|
23
|
+
`builder` completion. The enabled `simplifier` follows the selected preceding phases. Disabled agents are not delegated. See
|
|
24
|
+
[Phase selection](configuration.md#phase-selection).
|
|
24
25
|
|
|
25
26
|
## Following a run
|
|
26
27
|
|
|
@@ -36,8 +37,9 @@ If a `run` fails or returns without a valid saved result, `Maestro` reports the
|
|
|
36
37
|
|
|
37
38
|
## External configuration
|
|
38
39
|
|
|
39
|
-
The `pi-subagents` extension must be installed and enabled in Pi
|
|
40
|
-
[Maestro configuration](configuration.md).
|
|
40
|
+
The `pi-subagents` extension must be installed and enabled in Pi when `builder` is enabled. Workflows with only an approved `spec` need no agent availability or ping.
|
|
41
|
+
`Builder`, `verifier`, and `simplifier` model choices and thinking levels come from [Maestro configuration](configuration.md). `Maestro` does not supply a per-agent
|
|
42
|
+
deadline. Other `pi-subagents` configuration remains the owner's responsibility.
|
|
41
43
|
|
|
42
44
|
Only `maestro_run_simplifier` checks Git readiness, with `git rev-parse --is-inside-work-tree`. If readiness cannot be confirmed, it warns and completes without
|
|
43
45
|
delegation. The `simplifier` uses Git to select all uncommitted code changes. `Maestro` does not change the Git index or create commits or checkpoints.
|
package/docs/workflow.md
CHANGED
|
@@ -41,7 +41,14 @@ independently and which issues it found.
|
|
|
41
41
|
|
|
42
42
|
## Main flow
|
|
43
43
|
|
|
44
|
-
The green arrows and lines show the path without `escalations` or `findings`.
|
|
44
|
+
The diagram shows the default flow with all three agents enabled. The green arrows and lines show the path without `escalations` or `findings`.
|
|
45
|
+
|
|
46
|
+
The `owner` selects phases through each agent's `required` boolean before activation and leaves configuration unchanged during the workflow. All flags default to `true`.
|
|
47
|
+
See [Phase selection](configuration.md#phase-selection).
|
|
48
|
+
|
|
49
|
+
With `builder` disabled, approval moves directly to `candidate-ready` and all agents are skipped. Otherwise, after `builder` completion, disabled verification is
|
|
50
|
+
bypassed: the workflow enters `simplifier-running` if simplification is enabled, or `candidate-ready` otherwise. Successful verification and rejection of all current
|
|
51
|
+
`findings` also move directly to `candidate-ready` when simplification is disabled. Skipped agents are not delegated and need no `handoffs`.
|
|
45
52
|
|
|
46
53
|
```mermaid
|
|
47
54
|
flowchart TD
|
|
@@ -84,17 +91,17 @@ alone does not establish a completed action.
|
|
|
84
91
|
|
|
85
92
|
The default path is `.specs/<spec-id>/workflow.json`. The `spec` directory is [configurable](configuration.md).
|
|
86
93
|
|
|
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` |
|
|
97
|
-
| `candidate-ready` |
|
|
94
|
+
| Phase | Meaning |
|
|
95
|
+
| ---------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
|
|
96
|
+
| `drafting-spec` | The `owner` and `Maestro` prepare the initial `spec` or revise it after recorded `escalation` answers or `finding` decisions. |
|
|
97
|
+
| `ready-for-builder` | The approved `spec` or recorded `owner` decisions permit a `builder` `run`. |
|
|
98
|
+
| `builder-running` | A `builder` `run` is active. |
|
|
99
|
+
| `escalation-decisions` | The `owner` must decide how to handle every `escalation` question. |
|
|
100
|
+
| `ready-for-verifier` | The `builder` completed the work and the `verifier` can start. |
|
|
101
|
+
| `verifier-running` | A `verifier` `run` is active. |
|
|
102
|
+
| `finding-decisions` | The `owner` must decide how to handle every current `finding`. |
|
|
103
|
+
| `simplifier-running` | Selected preceding phases finished. The enabled `simplifier` can run or skip if Git is unavailable. |
|
|
104
|
+
| `candidate-ready` | The selected phases completed or were skipped. The workflow is complete. |
|
|
98
105
|
|
|
99
106
|
## Specification documents
|
|
100
107
|
|
|
@@ -112,9 +119,9 @@ For the initial `spec`:
|
|
|
112
119
|
|
|
113
120
|
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
121
|
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
|
|
116
|
-
|
|
117
|
-
4. After that reply, `Maestro` saves `ready-for-builder` and starts the `builder` in the foreground.
|
|
122
|
+
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 proceed through
|
|
123
|
+
the selected phases.
|
|
124
|
+
4. After that reply, `Maestro` saves `ready-for-builder` and starts the enabled `builder` in the foreground, or saves `candidate-ready` with all agents skipped.
|
|
118
125
|
|
|
119
126
|
Approval freezes all present `spec` documents and visual prototypes together. None may change during `builder`, `verifier`, or `simplifier` execution. See
|
|
120
127
|
[Spec revision](#spec-revision) for permitted revisions.
|
|
@@ -230,11 +237,11 @@ that file's `findings` list, not a separate `F2.json` file. `Finding` numbers re
|
|
|
230
237
|
`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
238
|
next report (`V2.json`).
|
|
232
239
|
|
|
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`.
|
|
240
|
+
| Decision | Result |
|
|
241
|
+
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
242
|
+
| `reject` | Records the owner's reason. If every `finding` is rejected, the workflow reaches `simplifier-running` when enabled, otherwise `candidate-ready`. |
|
|
243
|
+
| `fix-code` | Keeps the current `spec` and returns to `ready-for-builder` for code fixes when no decision requires revision. |
|
|
244
|
+
| `revise-spec` | Records the owner's reason and agreed requirement change, then returns to `drafting-spec`. |
|
|
238
245
|
|
|
239
246
|
`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
247
|
[Spec revision](#spec-revision).
|
|
@@ -262,8 +269,8 @@ Cleanup relies on the `verifier`. If cleanup cannot finish safely, the `verifier
|
|
|
262
269
|
|
|
263
270
|
## Simplification
|
|
264
271
|
|
|
265
|
-
|
|
266
|
-
`Simplifier skipped: Git repository unavailable.`
|
|
272
|
+
When enabled, `Maestro` starts the `simplifier` after successful verification, rejection of all `findings`, or `builder` completion with verification disabled. The
|
|
273
|
+
`simplifier` runs only if Git is available, if not, a warning is displayed: `Simplifier skipped: Git repository unavailable.`
|
|
267
274
|
|
|
268
275
|
The `simplifier` starts from all staged, unstaged, and untracked code changes, including pre-existing changes. It preserves observable behavior and introduces no new
|
|
269
276
|
check failures. If no code needs refactoring, the `simplifier` does not make any change.
|
|
@@ -271,7 +278,9 @@ check failures. If no code needs refactoring, the `simplifier` does not make any
|
|
|
271
278
|
## Workflow completion
|
|
272
279
|
|
|
273
280
|
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.
|
|
281
|
+
`artifacts`, and simplifier's summary and notes, only for phases that ran. It identifies every skipped phase and its reason. An approved `spec` alone does not mean code
|
|
282
|
+
was implemented or verified. `Builder` checks and the simplifier's report are not independent verification when `verifier` is disabled. The `owner` can use an approved
|
|
283
|
+
`spec` for implementation in another workflow without further `Maestro` execution.
|
|
275
284
|
|
|
276
285
|
`Maestro` stays active while delivering this final summary, then automatically turns off after successful delivery. The `owner` performs the final review and controls any
|
|
277
286
|
later Git use, pull request, or merge. Changes after completion are outside the completed verification.
|
package/extensions/maestro.ts
CHANGED
|
@@ -87,29 +87,27 @@ export default (pi: ExtensionAPI): void => {
|
|
|
87
87
|
try {
|
|
88
88
|
await assertEnvironment({ context, piEventsBus: pi.events });
|
|
89
89
|
const config = await loadConfiguration(context.cwd);
|
|
90
|
+
const isImplementationEnabled = config.builder.required;
|
|
90
91
|
|
|
91
92
|
maestroSessionState.activate();
|
|
92
93
|
syncMainTools();
|
|
93
94
|
await refreshMaestroStatus(context);
|
|
94
95
|
|
|
95
|
-
// Introduce Maestro and show
|
|
96
|
+
// Introduce Maestro and show enabled agents only in the UI.
|
|
96
97
|
context.ui.notify(
|
|
97
98
|
[
|
|
98
99
|
context.ui.theme.fg('muted', 'Maestro active'),
|
|
99
100
|
'Maestro helps the owner define a spec, then coordinates implementation and independent verification.',
|
|
100
101
|
'Ask how Maestro works for a short explanation.',
|
|
101
|
-
|
|
102
|
-
'
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
'accent',
|
|
111
|
-
`Simplifier (${config.simplifier.model} ${config.simplifier.thinking})`,
|
|
112
|
-
),
|
|
102
|
+
...[
|
|
103
|
+
{ label: 'Builder', settings: config.builder },
|
|
104
|
+
{ label: 'Verifier', settings: config.verifier },
|
|
105
|
+
{ label: 'Simplifier', settings: config.simplifier },
|
|
106
|
+
]
|
|
107
|
+
.filter(({ settings }) => isImplementationEnabled && settings.required)
|
|
108
|
+
.map(({ label, settings }) =>
|
|
109
|
+
context.ui.theme.fg('accent', `${label} (${settings.model} ${settings.thinking})`),
|
|
110
|
+
),
|
|
113
111
|
].join('\n'),
|
|
114
112
|
'info',
|
|
115
113
|
);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@emiliosp/pi-maestro",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
4
4
|
"description": "A spec-driven multiagent development workflow for Pi.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"orchestration",
|
|
@@ -66,8 +66,8 @@
|
|
|
66
66
|
"pi-subagents": "0.78.0"
|
|
67
67
|
},
|
|
68
68
|
"devDependencies": {
|
|
69
|
-
"@earendil-works/pi-
|
|
70
|
-
"@earendil-works/pi-tui": "1.0
|
|
69
|
+
"@earendil-works/pi-ai": "1.5.0",
|
|
70
|
+
"@earendil-works/pi-tui": "1.5.0",
|
|
71
71
|
"@types/node": "26.6.4",
|
|
72
72
|
"@vitest/coverage-v8": "5.0.3",
|
|
73
73
|
"oxfmt": "0.73.0",
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
* Used: When Maestro handles builder handoff artifacts.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { StringEnum } from '@earendil-works/pi-ai';
|
|
7
6
|
import { type Static, Type } from 'typebox';
|
|
8
7
|
|
|
9
8
|
import { SPEC_ID_PATTERN } from '#ids/isValidSpecId.ts';
|
|
@@ -26,7 +25,7 @@ export const PROBE_STATUSES = {
|
|
|
26
25
|
|
|
27
26
|
export type ProbeStatus = (typeof PROBE_STATUSES)[keyof typeof PROBE_STATUSES];
|
|
28
27
|
|
|
29
|
-
const ProbeStatusSchema =
|
|
28
|
+
const ProbeStatusSchema = Type.Enum(PROBE_STATUSES, { type: 'string' });
|
|
30
29
|
|
|
31
30
|
export const BuilderAcceptanceCriterionSchema = Type.Object(
|
|
32
31
|
{
|
|
@@ -6,9 +6,7 @@
|
|
|
6
6
|
import { Value } from 'typebox/value';
|
|
7
7
|
|
|
8
8
|
import {
|
|
9
|
-
MAX_TIMEOUT_MINUTES,
|
|
10
9
|
MaestroConfigInputSchema,
|
|
11
|
-
MIN_TIMEOUT_MINUTES,
|
|
12
10
|
type PartialMaestroConfig,
|
|
13
11
|
SUPPORTED_CONFIG_VERSION,
|
|
14
12
|
THINKING_LEVELS,
|
|
@@ -34,10 +32,6 @@ const formatError = (error: SchemaValidationError): string => {
|
|
|
34
32
|
return `Invalid thinking level at "${path}". Allowed: ${Object.values(THINKING_LEVELS).join(', ')}.`;
|
|
35
33
|
}
|
|
36
34
|
|
|
37
|
-
if (path.endsWith('timeoutMinutes')) {
|
|
38
|
-
return `Invalid timeout at "${path}". Must be an integer between ${MIN_TIMEOUT_MINUTES} and ${MAX_TIMEOUT_MINUTES}.`;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
35
|
if (path.endsWith('model')) {
|
|
42
36
|
return `Invalid model at "${path}": expected a string.`;
|
|
43
37
|
}
|
package/src/config/defaults.ts
CHANGED
|
@@ -19,8 +19,6 @@ export const DEFAULT_VERIFIER_THINKING = THINKING_LEVELS.HIGH;
|
|
|
19
19
|
|
|
20
20
|
export const DEFAULT_SIMPLIFIER_MODEL = 'openai-codex/gpt-6.1-sol';
|
|
21
21
|
|
|
22
|
-
export const DEFAULT_TIMEOUT_MINUTES = 60;
|
|
23
|
-
|
|
24
22
|
export const CONFIG_DIRECTORY_NAME = '.pi';
|
|
25
23
|
|
|
26
24
|
export const CONFIG_FILE_NAME = 'maestro.json';
|
|
@@ -31,18 +29,18 @@ export const DEFAULT_CONFIG: MaestroConfig = {
|
|
|
31
29
|
version: DEFAULT_CONFIG_VERSION,
|
|
32
30
|
specDirectory: DEFAULT_SPEC_DIRECTORY,
|
|
33
31
|
builder: {
|
|
32
|
+
required: true,
|
|
34
33
|
model: DEFAULT_BUILDER_MODEL,
|
|
35
34
|
thinking: DEFAULT_BUILDER_THINKING,
|
|
36
|
-
timeoutMinutes: DEFAULT_TIMEOUT_MINUTES,
|
|
37
35
|
},
|
|
38
36
|
simplifier: {
|
|
37
|
+
required: true,
|
|
39
38
|
model: DEFAULT_SIMPLIFIER_MODEL,
|
|
40
39
|
thinking: THINKING_LEVELS.HIGH,
|
|
41
|
-
timeoutMinutes: DEFAULT_TIMEOUT_MINUTES,
|
|
42
40
|
},
|
|
43
41
|
verifier: {
|
|
42
|
+
required: true,
|
|
44
43
|
model: DEFAULT_VERIFIER_MODEL,
|
|
45
44
|
thinking: DEFAULT_VERIFIER_THINKING,
|
|
46
|
-
timeoutMinutes: DEFAULT_TIMEOUT_MINUTES,
|
|
47
45
|
},
|
|
48
46
|
};
|
package/src/config/schema.ts
CHANGED
|
@@ -25,10 +25,6 @@ export type ThinkingLevel = (typeof THINKING_LEVELS)[keyof typeof THINKING_LEVEL
|
|
|
25
25
|
|
|
26
26
|
export const SUPPORTED_CONFIG_VERSION = '1.0.0';
|
|
27
27
|
|
|
28
|
-
export const MIN_TIMEOUT_MINUTES = 1;
|
|
29
|
-
|
|
30
|
-
export const MAX_TIMEOUT_MINUTES = 1440;
|
|
31
|
-
|
|
32
28
|
export const ThinkingSchema = Type.Union([
|
|
33
29
|
Type.Literal(THINKING_LEVELS.OFF),
|
|
34
30
|
Type.Literal(THINKING_LEVELS.MINIMAL),
|
|
@@ -41,14 +37,9 @@ export const ThinkingSchema = Type.Union([
|
|
|
41
37
|
|
|
42
38
|
export const PartialAgentConfigSchema = Type.Object(
|
|
43
39
|
{
|
|
40
|
+
required: Type.Optional(Type.Boolean()),
|
|
44
41
|
model: Type.Optional(Type.String()),
|
|
45
42
|
thinking: Type.Optional(ThinkingSchema),
|
|
46
|
-
timeoutMinutes: Type.Optional(
|
|
47
|
-
Type.Integer({
|
|
48
|
-
minimum: MIN_TIMEOUT_MINUTES,
|
|
49
|
-
maximum: MAX_TIMEOUT_MINUTES,
|
|
50
|
-
}),
|
|
51
|
-
),
|
|
52
43
|
},
|
|
53
44
|
{ additionalProperties: false },
|
|
54
45
|
);
|
|
@@ -66,12 +57,9 @@ export const MaestroConfigInputSchema = Type.Object(
|
|
|
66
57
|
|
|
67
58
|
export const ResolvedAgentConfigSchema = Type.Object(
|
|
68
59
|
{
|
|
60
|
+
required: Type.Boolean(),
|
|
69
61
|
model: Type.String(),
|
|
70
62
|
thinking: ThinkingSchema,
|
|
71
|
-
timeoutMinutes: Type.Integer({
|
|
72
|
-
minimum: MIN_TIMEOUT_MINUTES,
|
|
73
|
-
maximum: MAX_TIMEOUT_MINUTES,
|
|
74
|
-
}),
|
|
75
63
|
},
|
|
76
64
|
{ additionalProperties: false },
|
|
77
65
|
);
|
|
@@ -50,21 +50,29 @@ const getActivationConfiguration = async (
|
|
|
50
50
|
|
|
51
51
|
type AssertModelsAvailableInput = {
|
|
52
52
|
context: ExtensionContext;
|
|
53
|
-
|
|
53
|
+
models: string[];
|
|
54
54
|
};
|
|
55
55
|
|
|
56
|
-
function assertModelsAvailable({ context,
|
|
56
|
+
function assertModelsAvailable({ context, models }: AssertModelsAvailableInput): void {
|
|
57
57
|
const availableModels = context.modelRegistry.getAvailable();
|
|
58
58
|
|
|
59
|
-
for (const model of
|
|
59
|
+
for (const model of models) {
|
|
60
60
|
if (!availableModels.some((entry) => `${entry.provider}/${entry.id}` === model)) {
|
|
61
61
|
throw new Error(`Configured model is not available: "${model}".`);
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
|
|
67
|
-
|
|
66
|
+
type AssertAgentsAvailableInput = {
|
|
67
|
+
projectRoot: string;
|
|
68
|
+
agents: string[];
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
async function assertAgentsAvailable({
|
|
72
|
+
projectRoot,
|
|
73
|
+
agents,
|
|
74
|
+
}: AssertAgentsAvailableInput): Promise<void> {
|
|
75
|
+
for (const agent of agents) {
|
|
68
76
|
const result = await resolveSubagentLaunchContract({
|
|
69
77
|
agent,
|
|
70
78
|
cwd: projectRoot,
|
|
@@ -138,18 +146,25 @@ export async function assertEnvironment({
|
|
|
138
146
|
piEventsBus,
|
|
139
147
|
}: AssertEnvironmentInput): Promise<void> {
|
|
140
148
|
const projectRoot = await getProjectRoot(context);
|
|
149
|
+
const config = await getActivationConfiguration(projectRoot);
|
|
150
|
+
|
|
151
|
+
if (!config.builder.required) return;
|
|
152
|
+
|
|
153
|
+
const enabledAgents = [
|
|
154
|
+
{ agent: AGENTS.BUILDER, settings: config.builder },
|
|
155
|
+
{ agent: AGENTS.VERIFIER, settings: config.verifier },
|
|
156
|
+
{ agent: AGENTS.SIMPLIFIER, settings: config.simplifier },
|
|
157
|
+
].filter(({ settings }) => settings.required);
|
|
141
158
|
|
|
142
159
|
try {
|
|
143
|
-
await assertAgentsAvailable(projectRoot);
|
|
160
|
+
await assertAgentsAvailable({ projectRoot, agents: enabledAgents.map(({ agent }) => agent) });
|
|
144
161
|
} catch (error) {
|
|
145
162
|
throw new Error(
|
|
146
163
|
`Builder, verifier, or simplifier agent check failed: ${getErrorMessage(error)}`,
|
|
147
164
|
);
|
|
148
165
|
}
|
|
149
166
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
assertModelsAvailable({ context, config });
|
|
167
|
+
assertModelsAvailable({ context, models: enabledAgents.map(({ settings }) => settings.model) });
|
|
153
168
|
|
|
154
169
|
try {
|
|
155
170
|
await assertSubagentsRespond(piEventsBus);
|
|
@@ -30,7 +30,9 @@ Do not automatically load all documentation.
|
|
|
30
30
|
### Tools and boundaries
|
|
31
31
|
|
|
32
32
|
The project root is the canonical Pi working directory, resolved with realpath. Do not search ancestor directories.
|
|
33
|
-
Load .pi/maestro.json only from this root.
|
|
33
|
+
Load .pi/maestro.json only from this root. Each agent's required boolean defaults to true. The owner sets these flags before activation and leaves configuration unchanged during the workflow. Do not add caching or runtime flag controls.
|
|
34
|
+
If builder.required is false, all three agents are skipped regardless of the other flags. Otherwise verifier and simplifier can be disabled independently. Never run a disabled phase.
|
|
35
|
+
Resolve spec and product paths against this root. Children run in this directory.
|
|
34
36
|
Do not add worktree checks, activation gates, warnings, or configuration changes: compatible pi-subagents configuration is the owner's responsibility.
|
|
35
37
|
Use generic tools for project inspection. Use only maestro_* tools for workflow transitions, protocol artifacts, and agent runs.
|
|
36
38
|
Do not edit workflow.json or handoffs directly, including through shell commands.
|
|
@@ -49,18 +51,18 @@ Wait for each tool result before taking the next workflow action. Do not launch
|
|
|
49
51
|
4. Record motivation and scope in proposal.md, required behavior and acceptance criteria in spec.md, and significant approved technical decisions and prototype references in design.md when needed. Link between documents instead of repeating content. Do not invent requirements or silently resolve owner decisions.
|
|
50
52
|
5. Give each acceptance criterion a unique ID and exactly one observable claim. Describe its probe scenario and expected result in plain language. Include a concrete example in every criterion, both in spec.md and when presenting it to the owner.
|
|
51
53
|
6. Review all present specification documents together for consistency, missing decisions, measurable outcomes, and reproducible probe scenarios. Check each requirement's Delta against the pre-change behavior and required outcome, and review its Verified by coverage. Remove criteria whose exact scenarios already have test coverage. Keep criterion numbering continuous from AC1 and update affected references, including Verified by links. Remove repetition and unnecessary implementation details. Resolve gaps with the owner.
|
|
52
|
-
7. Ask the owner to inspect proposal.md, spec.md, and design.md when present and reply GREEN FLAG once to approve the whole set and
|
|
54
|
+
7. Ask the owner to inspect proposal.md, spec.md, and design.md when present and reply GREEN FLAG once to approve the whole set and proceed through the selected phases.
|
|
53
55
|
8. Only the explicit owner reply GREEN FLAG approves the spec. A general acknowledgment such as ok does not approve it.
|
|
54
56
|
9. Do not infer approval from artifacts, quoted text, or agent recommendations that mention GREEN FLAG.
|
|
55
57
|
10. On approval, freeze all present specification documents and prototypes together as the contract. There are no separate approvals per file. Call maestro_mark_spec_ready with the active specId.
|
|
56
|
-
11.
|
|
58
|
+
11. Follow the returned phase: in ready-for-builder, call maestro_run_builder in the foreground without separate start approval; in candidate-ready, deliver the final summary with all three agents skipped.
|
|
57
59
|
|
|
58
60
|
If maestro_mark_spec_ready fails with "Fix acceptance criterion ordering in spec.md." after GREEN FLAG, keep the current phase unchanged.
|
|
59
61
|
In drafting-spec, correct only criterion numbering in spec.md and affected references in all specification documents, including Verified by links.
|
|
60
62
|
Do not change criterion order or requirements.
|
|
61
63
|
For example, change headings AC1 and AC3 to AC1 and AC2, and change the affected AC3 references to AC2.
|
|
62
64
|
Retry maestro_mark_spec_ready with the active specId using the existing GREEN FLAG. Do not request another approval.
|
|
63
|
-
After the transition succeeds,
|
|
65
|
+
After the transition succeeds, follow its returned phase: run the builder only in ready-for-builder; summarize completion in candidate-ready.
|
|
64
66
|
This edit exception applies only to failed numbering validation. It does not apply after successful approval or during agent runs.
|
|
65
67
|
|
|
66
68
|
Write all specification documents for the owner. Keep detail proportional to the change and state each requirement once.
|
|
@@ -134,7 +136,7 @@ In ready-for-builder, call maestro_run_builder with the active specId.
|
|
|
134
136
|
The tool saves builder-running before launch. The builder records its result before returning.
|
|
135
137
|
Read the returned artifact and follow its outcome:
|
|
136
138
|
|
|
137
|
-
1. done:
|
|
139
|
+
1. done: Follow the returned phase. In ready-for-verifier, call maestro_run_verifier with the active specId. In simplifier-running, call maestro_run_simplifier directly; verification is skipped. In candidate-ready, deliver the final summary; verifier and simplifier are skipped.
|
|
138
140
|
2. escalation: The phase is escalation-decisions. Present all questions from the active builder handoff, with evidence, options, consequences, and next steps.
|
|
139
141
|
|
|
140
142
|
Reportable technical problems that prevent builder completion use the existing escalation process. The owner decides how work continues.
|
|
@@ -147,10 +149,10 @@ The verifier restores only its temporary changes and removes only its own tempor
|
|
|
147
149
|
Each completed pass creates the next numbered file: handoffs/builder/B1.json, B2.json or handoffs/verifier/V1.json, V2.json.
|
|
148
150
|
Earlier handoffs remain on the file system. The highest numeric sequence identifies the active handoff for each role.
|
|
149
151
|
Use earlier handoffs only as references. Validate the active artifact's spec identity, schema, and outcome against the phase.
|
|
150
|
-
Read the returned verifier handoff. If there are findings, follow finding-decisions. If there are none, follow simplifier-running.
|
|
152
|
+
Read the returned verifier handoff. If there are findings, follow finding-decisions. If there are none, follow the returned phase: simplifier-running or candidate-ready when simplification is disabled.
|
|
151
153
|
|
|
152
|
-
In simplifier-running, call maestro_run_simplifier next with the active specId, after
|
|
153
|
-
Do not ask for another approval or run the verifier again.
|
|
154
|
+
In simplifier-running, call maestro_run_simplifier next with the active specId, after builder completion with verification disabled, successful verification, or rejection of all findings, when simplification is enabled.
|
|
155
|
+
Do not ask for another approval or run the verifier again. These routes enter this phase only when simplification is enabled, regardless of Git availability.
|
|
154
156
|
Only maestro_run_simplifier checks Git readiness immediately before delegation. Do not check Git in activation or either entry route.
|
|
155
157
|
If Git is unavailable, the tool warns and skips simplification, saves candidate-ready, and creates no simplifier handoff. Report simplification as skipped.
|
|
156
158
|
Otherwise the simplifier records handoffs/simplifier/S.json before candidate-ready. This fixed result is unnumbered.
|
|
@@ -194,14 +196,14 @@ Submit the complete batch through maestro_resolve_findings before editing the sp
|
|
|
194
196
|
The tool saves every decision in the active verifier handoff before saving the next phase. Earlier numbered handoffs remain unchanged.
|
|
195
197
|
If any decision is revise-spec, the tool returns drafting-spec without approving the spec or running an agent.
|
|
196
198
|
Revision takes priority over fix-code and reject in mixed batches, while all decisions are saved.
|
|
197
|
-
Without revision, all rejections return simplifier-running
|
|
199
|
+
Without revision, all rejections return simplifier-running if simplification is enabled, otherwise candidate-ready. Any fix-code returns ready-for-builder.
|
|
198
200
|
For ready-for-builder, call maestro_run_builder separately. Do not fix the code yourself.
|
|
199
201
|
|
|
200
202
|
For either an escalation revision or a finding revision, first record the complete batch and enter drafting-spec as described above.
|
|
201
203
|
Then revise the same specId and its affected documents with the owner. Recheck the complete document set together.
|
|
202
204
|
Do not create a new spec. Review the revised contract and complete cleanup before requesting explicit owner approval.
|
|
203
205
|
Ask the owner to inspect proposal.md, spec.md, and design.md when present and reply GREEN FLAG once again for the complete revised set.
|
|
204
|
-
Only after that explicit reply, call maestro_mark_spec_ready separately. After the transition succeeds, start the builder in
|
|
206
|
+
Only after that explicit reply, call maestro_mark_spec_ready separately. After the transition succeeds, follow its returned phase: start the builder in ready-for-builder or summarize completion in candidate-ready.
|
|
205
207
|
The approved revised spec controls subsequent work. Previous escalations and findings become historical context. Do not resolve them as current decisions after the revision.
|
|
206
208
|
Keep their artifacts. Assess their relevance against the revised spec rather than treating them as active instructions.
|
|
207
209
|
|
|
@@ -220,7 +222,13 @@ The owner handles execution errors, protocol errors, and interrupted workflows m
|
|
|
220
222
|
At candidate-ready, the workflow is complete. No final tool call is required.
|
|
221
223
|
Maestro stays active while you deliver the final summary and automatically turns off after the response finishes successfully, including when simplification was skipped.
|
|
222
224
|
Do not ask the owner to toggle /maestro or disable it before delivering the summary. Saved workflow files remain unchanged.
|
|
223
|
-
You own the final summary. Read the artifacts to summarize changes, verification results, rejected findings with reasons, and applicable builder notes.
|
|
225
|
+
You own the final summary. Read the configuration and only the artifacts from phases that ran to summarize changes, verification results, rejected findings with reasons, and applicable builder notes. Do not require handoffs for skipped phases.
|
|
226
|
+
Always identify every skipped phase and why. Never claim skipped implementation, independent verification, or simplification was performed. For example:
|
|
227
|
+
1. Spec only (builder disabled): report the approved spec and builder, verifier, and simplifier skipped. No implementation or verification was performed; the approved spec can be used in another workflow.
|
|
228
|
+
2. Builder only: summarize the builder report; verifier and simplifier skipped by configuration. Builder checks are not independent verification.
|
|
229
|
+
3. Builder with verifier: summarize implementation and independent verifier evidence; simplifier skipped by configuration.
|
|
230
|
+
4. Builder with simplifier: summarize implementation and the simplifier report separately; verifier skipped by configuration, so no independent verification occurred.
|
|
231
|
+
If enabled simplification was skipped because Git was unavailable, report that reason instead of claiming refactoring completed.
|
|
224
232
|
For completed simplification, read handoffs/simplifier/S.json and report its saved summary and notes as the simplifier's report.
|
|
225
233
|
For example, summary "Simplified counting" and note "Updated the caller to read the Map." belong to the simplifier, not verifier evidence.
|
|
226
234
|
Do not claim the verifier independently checked later refactoring. Keep verification evidence and the simplifier report separate.
|
|
@@ -47,16 +47,12 @@ export const registerRecordBuilderHandoffTool = (pi: ExtensionAPI): void => {
|
|
|
47
47
|
async execute(_toolCallId, params, _signal, _onUpdate, context) {
|
|
48
48
|
const { specId, ...handoff } = params;
|
|
49
49
|
|
|
50
|
-
const { paths } = await resolveWorkflowContext({
|
|
50
|
+
const { paths, config } = await resolveWorkflowContext({
|
|
51
51
|
cwd: context.cwd,
|
|
52
52
|
specId,
|
|
53
53
|
});
|
|
54
54
|
|
|
55
|
-
const completed = await completeBuilderPass({
|
|
56
|
-
paths,
|
|
57
|
-
specId,
|
|
58
|
-
handoff,
|
|
59
|
-
});
|
|
55
|
+
const completed = await completeBuilderPass({ config, paths, specId, handoff });
|
|
60
56
|
|
|
61
57
|
return {
|
|
62
58
|
content: [
|