@emiliosp/pi-maestro 0.1.1 → 0.1.2

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/README.md CHANGED
@@ -6,7 +6,7 @@ Pi extension for a spec-driven multiagent development workflow.
6
6
 
7
7
  ## The idea
8
8
 
9
- One spec describes one small reversible change. An agent builds it. A second, independent agent regenerates each acceptance criterion from scratch. The owner performs the final review and controls the Git flow after the candidate is ready.
9
+ One spec describes one small reversible change. An agent builds it. A second, independent agent regenerates each acceptance criterion from scratch. The owner performs the final review.
10
10
 
11
11
  Four principles hold the workflow together:
12
12
 
@@ -19,7 +19,7 @@ Four principles hold the workflow together:
19
19
 
20
20
  - **Owner** — You. You bring the problem, decide every escalation and every finding, review the final code, and control the Git flow after the candidate is ready. You never talk to a builder or a verifier.
21
21
  - **Maestro** — The agent you talk to. It writes the spec with you, spawns and supervises the other agents, records your decisions, and summarizes the results.
22
- - **Builder** — The agent that implements one spec. It never verifies its own work.
22
+ - **Builder** — The agent that implements one spec. It never approves its own work.
23
23
  - **Verifier** — The agent that verifies if the builder implementation is technically compliant to the spec.
24
24
 
25
25
  ## Prerequisites
@@ -67,11 +67,11 @@ Follow this workflow:
67
67
  3. Review the spec with Maestro.
68
68
  4. Approve the spec.
69
69
  5. Commit the approved `spec.md` and `workflow.json` on the current branch.
70
- 6. Ask Maestro to launch the builder.
70
+ 6. Ask Maestro to run the builder.
71
71
  7. Review builder escalations and answer them.
72
72
  8. Review verifier findings and choose an action for each finding.
73
73
  9. When the workflow reaches `candidate-ready`, read Maestro's summary of the results and Pull Request facts.
74
- 10. Review or change the candidate as needed, then open a Pull Request from the current branch and choose the merge method.
74
+ 10. Review or change the candidate as needed.
75
75
 
76
76
  Do not change product code while the workflow runs. The workflow is complete when it reaches `candidate-ready`. No final tool call is needed. Changes after completion are outside the Maestro review.
77
77
 
@@ -79,7 +79,7 @@ If an escalation or finding requires a contract change, edit and approve `spec.m
79
79
 
80
80
  Builder and verifier runs stay in the foreground. Pi waits for each run before you continue the conversation. Maestro shows the current phase in Pi's status. Use pi-subagents FleetView or `/subagents-fleet` to inspect live activity and the transcript.
81
81
 
82
- Restarting Pi, disabling Maestro, or using `/resume` clears live session state. Maestro does not recover an incomplete workflow from `workflow.json`.
82
+ Restarting Pi, disabling Maestro, or using `/resume` clears live session state. Maestro does not recover an incomplete workflow.
83
83
 
84
84
  ## Configuration
85
85
 
@@ -24,7 +24,7 @@ You are the independent verifier. Work only in the current Git checkout and bran
24
24
 
25
25
  Read the approved spec and relevant prototypes, the current workflow state, applicable `AGENTS.md` files, the builder handoff, and earlier verifier handoffs and owner decisions for this spec. The approved `spec.md` is the contract between the owner, Maestro, the builder, and you. Verify the candidate against that contract; do not silently reinterpret or expand it. Use the handoffs for context, not as proof. Follow repository commands and technical rules in the applicable `AGENTS.md` files; do not invent required commands. Do not modify the spec, prototypes, workflow state, or handoff files directly. Use the Maestro child tool for the terminal artifact.
26
26
 
27
- The candidate is the parent of the `verifier-running` checkpoint. Independently regenerate evidence for *every* acceptance criterion from that candidate commit. Run each probe and observe its expected result. Apply the specified safe, temporary breakage only in the current checkout, run the *same* probe and observe failure, restore every breakage fully, then rerun the same probe and observe success. Do not change approved probes, expected results, or breakages. Verify visual claims with reproducible evidence using the spec and repository instructions, including prototype comparisons when required. Run applicable repository checks. Record the actual command or procedure and honest probe and breakage statuses for every criterion, including `not-run` when necessary. Never treat the builder's results as evidence.
27
+ The candidate is the `verifier-running` checkpoint identified by the commit ID supplied by Maestro. Use that fixed commit, not a later `HEAD`. Independently regenerate evidence for *every* acceptance criterion from that candidate commit. Run each probe and observe its expected result. Apply the specified safe, temporary breakage only in the current checkout, run the *same* probe and observe failure, restore every breakage fully, then rerun the same probe and observe success. Do not change approved probes, expected results, or breakages. Verify visual claims with reproducible evidence using the spec and repository instructions, including prototype comparisons when required. Run applicable repository checks. Record the actual command or procedure and honest probe and breakage statuses for every criterion, including `not-run` when necessary. Never treat the builder's results as evidence.
28
28
 
29
29
  Do not repair product code, even if a probe fails. Use `edit` and `write` only to apply and restore temporary breakages. Record technical observations as findings with evidence, not questions or decisions. Give each finding a unique `F1`, `F2`, etc. ID, an acceptance criterion ID when relevant (otherwise `null`), severity, confidence, concise summary, and source plus observation. Every criterion with a probe other than `passed` or breakage other than `confirmed` needs a related finding. A finding always starts with `rejection: null`; only Maestro can record an owner rejection. Use `findings: []` only if every probe passes and every breakage is confirmed. Do not include full logs or secrets.
30
30
 
@@ -6,7 +6,7 @@ Maestro reads project configuration from:
6
6
  .pi/maestro.json
7
7
  ```
8
8
 
9
- The file is optional. Maestro uses all default values when the file is absent.
9
+ The file is optional, and Maestro uses all default values when it is absent.
10
10
 
11
11
  ## Default configuration
12
12
 
@@ -56,10 +56,6 @@ xhigh
56
56
  max
57
57
  ```
58
58
 
59
- Each object accepts only the documented fields. Unknown fields stop activation and produce an error.
60
-
61
- When a run reaches its timeout, Maestro reports it and does not treat the run as complete.
62
-
63
59
  ## Partial configuration
64
60
 
65
61
  Only `version` is required when the file exists. Each other field overrides its matching default.
@@ -77,19 +73,16 @@ This example keeps every default except the builder timeout.
77
73
 
78
74
  ## Schema version
79
75
 
80
- `version` identifies the configuration schema. It is separate from the npm package version.
81
-
82
- The current schema version is `1.0.0`. An unsupported major version stops Maestro activation. Minor and patch versions represent compatible schema changes supported by the installed Maestro release.
76
+ `version` identifies the configuration schema. It is separate from the npm package version, and it's a mechanism for future-proof additions.
83
77
 
84
78
  ## Path rules
85
79
 
86
80
  `specDirectory` must meet these rules:
87
81
 
88
- - The path is relative to the Git repository root.
89
- - The path points below the repository root.
90
- - The resolved path stays inside the repository, including through symlinks.
82
+ 1. The path is relative to the Git repository root.
83
+ 2. The path points below the repository root after `.` and `..` are resolved.
91
84
 
92
- An invalid path stops Maestro activation. Maestro validates the path while it loads configuration, but does not create the directory then. Workflow actions create a spec directory and its artifacts only when they need them.
85
+ It's owner responsibility to arrange the filesystem in order to support artifact writes and Git checkpoints.
93
86
 
94
87
  ## Model access
95
88
 
@@ -97,13 +90,9 @@ Maestro checks both configured models during activation. Each model must exist a
97
90
 
98
91
  A model error stops activation and identifies the affected model. Update the configuration or authenticate the provider, then run `/maestro` again.
99
92
 
100
- ## Fixed values
101
-
102
- Agent names:
93
+ Agent names have fixed value:
103
94
 
104
95
  ```text
105
96
  maestro.builder
106
97
  maestro.verifier
107
- ```
108
-
109
- Maestro does not require a branch naming pattern. The owner selects the current branch before using the workflow.
98
+ ```
@@ -1,6 +1,8 @@
1
1
  # Subagent integration
2
2
 
3
- Maestro uses `pi-subagents` to run the builder and verifier as child sessions. A child session is a separate Pi session that receives one role and one task. An agent definition is a Markdown file that gives the child its role, tools, and system prompt. A system prompt is the instruction text that the child follows.
3
+ Maestro uses `pi-subagents` to run the builder and verifier as child sessions.
4
+
5
+ A child session is a separate Pi session that receives one role and one task.
4
6
 
5
7
  ## Agent definitions
6
8
 
@@ -9,10 +11,6 @@ The package contains two agent definitions:
9
11
  1. [`agents/builder.md`](../agents/builder.md) defines the builder role.
10
12
  2. [`agents/verifier.md`](../agents/verifier.md) defines the verifier role.
11
13
 
12
- Each file has YAML frontmatter at the top. Frontmatter is the YAML block between the two `---` lines. The text after the frontmatter is the system prompt.
13
-
14
- The frontmatter defines the agent name, tools, context rules, and child-only extensions. The system prompt defines the role rules and the work procedure.
15
-
16
14
  ## Package registration
17
15
 
18
16
  `package.json` registers the agent directory with Pi:
@@ -29,25 +27,28 @@ The frontmatter defines the agent name, tools, context rules, and child-only ext
29
27
  }
30
28
  ```
31
29
 
32
- The `pi.subagents.agents` field tells `pi-subagents` to scan `./agents` for agent definitions. Pi scans nested directories as well.
30
+ The `pi.subagents.agents` field tells `pi-subagents` to scan `./agents` for agent definitions.
33
31
 
34
- The `package` and `name` fields in each file form the runtime name that delegation uses. The builder file has `package: maestro` and `name: builder`, so its runtime name is `maestro.builder`. The verifier runtime name is `maestro.verifier`.
32
+ The `package` and `name` fields in each file form the runtime name that delegation uses.
35
33
 
36
- ## Launch flow
34
+ ## Run flow
37
35
 
38
- When the owner launches the builder, the integration follows these steps:
36
+ When the owner runs the builder, the integration follows these steps:
39
37
 
40
- 1. The owner calls `maestro_launch_builder`.
41
- 2. `src/tools/main/launch-builder.ts` prepares the workflow and emits a delegation request.
38
+ 1. The owner calls `maestro_run_builder`.
39
+ 2. `src/tools/main/run-builder.ts` prepares the workflow and emits a delegation request.
42
40
  3. The request sets `agent: AGENTS.BUILDER`.
43
41
  4. `AGENTS.BUILDER` has the value `maestro.builder` in `src/config/schema.ts`.
44
42
  5. `pi-subagents` resolves `maestro.builder` to `agents/builder.md`.
45
43
  6. The child receives the system prompt and the tools from that agent definition.
44
+ 7. Maestro waits for the child to finish, checks its result, and returns it to the owner.
46
45
 
47
- Maestro also passes the explicit spec ID, the current repository root, the configured model, the thinking level, the timeout, and a fresh context. The task text tells the builder to read the applicable `AGENTS.md` files.
46
+ Maestro also passes the explicit spec ID, the current repository root, the configured model, the thinking level, the timeout, and a fresh context.
48
47
 
49
- The verifier uses the same name mapping with `AGENTS.VERIFIER` and `maestro.verifier`.
48
+ `maestro_run_verifier` in `src/tools/main/run-verifier.ts` uses the same flow with `AGENTS.VERIFIER` and `maestro.verifier`. Both tools run in the foreground and wait for a result.
50
49
 
51
50
  ## Subagent extension
52
51
 
53
- Both agent files set `subagentOnlyExtensions` to `../extensions/maestro-subagent.ts`. This field tells `pi-subagents` to load the extension only in the child session for that agent.
52
+ Both agent files set `subagentOnlyExtensions` to `../extensions/maestro-subagent.ts`.
53
+
54
+ This field tells `pi-subagents` to load the extension only in the child session for that agent.
package/docs/workflow.md CHANGED
@@ -2,17 +2,23 @@
2
2
 
3
3
  Maestro manages one spec-driven development workflow in the current session.
4
4
 
5
- The approved `spec.md` is the contract between the owner, Maestro, the builder, and the verifier. It defines the intended behavior, constraints, technical decisions, and acceptance criteria. Implementation details that the contract leaves open are decided during the work. Changes to the contract's behavior, scope, or approved decisions require an owner-approved revision.
5
+ The approved `spec.md` is the contract between the owner, Maestro, the builder, and the verifier.
6
6
 
7
- The owner works with Maestro. Builder and verifier communicate with Maestro through repository handoffs. Maestro prepares the spec, updates workflow state, starts the builder and verifier, and records owner decisions.
7
+ It defines the intended behavior, constraints, technical decisions, and acceptance criteria.
8
8
 
9
- Maestro uses the current Git checkout and branch. It does not create, switch, name, or validate a branch. It does not create worktrees. If the owner starts on `main`, `master`, or another branch, all workflow commits use that branch.
9
+ The owner works directly with Maestro.
10
+
11
+ Maestro, using the current Git branch, prepares the spec, updates workflow state, starts the builder and verifier, and records owner decisions.
12
+
13
+ Builder and verifier runs are foreground operations, and communicate with Maestro through repository handoffs.
14
+
15
+ Pi waits for each run before the owner continues. Maestro's Pi status shows the current phase, and pi-subagents FleetView shows the live activity and transcript.
10
16
 
11
17
  ## Roles
12
18
 
13
19
  ### Owner
14
20
 
15
- The owner is the human in the loop. Every decision that needs human judgment returns to the owner.
21
+ The owner is the human in the loop: every decision that needs human judgment returns to the owner.
16
22
 
17
23
  The owner has final authority over:
18
24
 
@@ -25,12 +31,8 @@ The owner has final authority over:
25
31
  - Git flow after the candidate is ready
26
32
  - Final Pull Request and merge
27
33
 
28
- The owner does not change product code while the workflow is running. The owner may revise `spec.md` while the workflow is blocked, as described below.
29
-
30
34
  ### Maestro
31
35
 
32
- Maestro:
33
-
34
36
  - Discusses the change with the owner
35
37
  - Writes and reviews the spec with the owner
36
38
  - Creates workflow artifacts on the current branch
@@ -40,11 +42,11 @@ Maestro:
40
42
  - Records explicit owner decisions
41
43
  - Summarizes the results and facts for a Pull Request when the candidate is ready
42
44
 
43
- Maestro does not know or manage a target branch.
44
-
45
45
  ### Builder
46
46
 
47
- The builder works on the current branch with a fresh context. It reads the active spec, implements the approved change, and runs every acceptance criterion.
47
+ The builder works on the current branch with a fresh context.
48
+
49
+ It reads the active spec, implements the approved change, and runs every acceptance criterion.
48
50
 
49
51
  For each criterion, the builder runs the probe, applies the approved temporary breakage, confirms that the same probe fails, restores the implementation, and confirms that the probe passes again.
50
52
 
@@ -52,29 +54,17 @@ The builder ends a run with one of these outcomes:
52
54
 
53
55
  - `done`
54
56
  - `failed`
55
- - An escalation
56
-
57
- The builder uses `maestro_record_builder_handoff` or `maestro_open_escalation`, then commits the implementation, generated workflow state, and handoff together.
57
+ - An `escalation`
58
58
 
59
59
  ### Verifier
60
60
 
61
- The verifier works on the current branch with a fresh context. It reads the active spec and available artifacts. Historical artifacts provide context, not proof; the verifier decides which information is still applicable to the active spec.
61
+ The verifier works on the current branch with a fresh context.
62
62
 
63
- The verifier independently regenerates every probe and breakage from the candidate. It does not repair product code and does not commit through Bash.
63
+ It reads the active spec and available artifacts. Historical artifacts provide context, not proof.
64
64
 
65
- Before the verifier starts, Maestro commits a `verifier-running` checkpoint. The candidate is the parent of that checkpoint's `HEAD`.
65
+ Before the verifier starts, Maestro commits a `verifier-running` checkpoint. That checkpoint is the candidate commit.
66
66
 
67
- The verifier applies and restores temporary breakages. `maestro_record_verifier_handoff` compares product files with that parent commit. If the product is unchanged, the tool writes `verifier.json` and `workflow.json` and commits only those protocol files. If product changes remain, the tool returns `PRODUCT_FILES_MODIFIED` and does not write or commit the handoff.
68
-
69
- There is no numbered verifier pass and no separate verifier branch. The current artifact is always:
70
-
71
- ```text
72
- .specs/<spec-id>/handoffs/verifier.json
73
- ```
74
-
75
- Git preserves earlier verifier handoffs.
76
-
77
- Builder and verifier runs are foreground operations. Pi waits for each run before the owner continues. Maestro's Pi status shows the current phase, and pi-subagents FleetView shows the live activity and transcript.
67
+ The verifier never changes product code, it independently regenerates every probe and breakage from the candidate.
78
68
 
79
69
  ## Main flow
80
70
 
@@ -95,7 +85,7 @@ flowchart TD
95
85
 
96
86
  buildOutcome -->|Escalation| escalation[Builder records an escalation and stops]
97
87
  escalation --> ownerAnswer[Owner decides]
98
- ownerAnswer --> escalationOutcome{Does the contract change?}
88
+ ownerAnswer --> escalationOutcome{Does the spec change?}
99
89
  escalationOutcome -->|No| recordContinue[Maestro records the resolution]
100
90
  recordContinue --> build
101
91
  escalationOutcome -->|Yes| reviseSpec[Owner revises and approves spec.md]
@@ -127,27 +117,25 @@ flowchart TD
127
117
 
128
118
  ## Workflow phases
129
119
 
130
- Maestro stores the current phase in `.specs/<spec-id>/workflow.json` by default.
120
+ Each spec has a `workflow.json` file that records its progress. Maestro creates and updates this file. It stores the current phase, which tells you where the work stands. For example, `ready-for-verifier` means that the builder completed the work and the verifier can start.
121
+
122
+ Maestro stores this file at `.specs/<spec-id>/workflow.json`.
131
123
 
132
124
  | Phase | Meaning |
133
125
  |---|---|
134
- | `drafting-spec` | Owner and Maestro are preparing the initial spec. |
135
- | `ready-for-builder` | The owner approved the spec and it awaits a builder run. |
136
- | `builder-running` | A builder run is active. |
137
- | `escalation-decision` | The owner must decide how to resolve the active escalation. |
138
- | `builder-failed` | The builder ended the run with a failure. |
139
- | `ready-for-verifier` | Builder work is ready for independent verification. |
140
- | `verifier-running` | A verifier run is active. |
141
- | `findings-decision` | The owner must decide how to handle verifier findings. |
142
- | `candidate-ready` | The candidate passed verification or all findings were rejected with reasons. This is the last persisted Maestro phase. |
126
+ | `drafting-spec` | Owner and Maestro are preparing the initial spec |
127
+ | `ready-for-builder` | The owner approved the spec and it awaits a builder run |
128
+ | `builder-running` | A builder run is active |
129
+ | `escalation-decision` | The owner must decide how to resolve the active escalation |
130
+ | `builder-failed` | The builder ended the run with a failure |
131
+ | `ready-for-verifier` | Builder work is ready for independent verification |
132
+ | `verifier-running` | A verifier run is active |
133
+ | `findings-decision` | The owner must decide how to handle verifier findings |
134
+ | `candidate-ready` | The candidate commit passed verification or all findings were rejected with reasons. This is the last persisted Maestro phase |
143
135
 
144
- A session can have one active Maestro workflow. A workflow in `candidate-ready` is complete from Maestro's point of view. Completed or abandoned workflows can remain under the spec directory.
136
+ Disabling Maestro, restarting Pi, or using `/resume` clears live session state. Maestro does not resume an incomplete workflow, the owner must clean it up manually.
145
137
 
146
- Disabling Maestro, restarting Pi, or using `/resume` clears live session state. Maestro does not resume an incomplete workflow from `workflow.json`; the owner must clean it up manually.
147
-
148
- ## Spec approval and revision
149
-
150
- Maestro treats `spec.md` as opaque Markdown. It checks the workflow phase and file existence, but does not parse the spec or compare its content with an earlier version.
138
+ ## Spec approval
151
139
 
152
140
  For the initial spec:
153
141
 
@@ -156,22 +144,7 @@ For the initial spec:
156
144
  3. `maestro_mark_spec_ready` changes the phase to `ready-for-builder`.
157
145
  4. The owner commits `spec.md` and `workflow.json` on the current branch.
158
146
 
159
- The committed `spec.md` and `workflow.json` are the approved contract for the builder and verifier. The contract is immutable during a builder or verifier pass. When a discovery shows that the contract must change, the owner makes an explicit revision and approval before the next pass.
160
-
161
- A contract revision is allowed only from these blocked phases:
162
-
163
- - `escalation-decision`
164
- - `findings-decision`
165
-
166
- `builder-failed` is a sink state. Maestro reports the technical error and stops the workflow; it does not retry the builder or revise the spec from that state.
167
-
168
- The owner edits and approves `spec.md`, then calls `maestro_mark_spec_ready` directly from the blocked phase. The tool changes the phase to `ready-for-builder`. There is no separate revision phase and no new `specId`.
169
-
170
- The previous escalation or finding becomes inactive. Its artifact remains in the branch as historical context. Builder and verifier decide whether historical artifacts apply to the current spec.
171
-
172
- The workflow does not store a separate spec version. The active contract is the current `spec.md`; Git preserves earlier versions and approvals.
173
-
174
- Immediately before each builder launch, Maestro calculates the SHA-256 of the current `spec.md` and stores it only in live session state. Builder handoff and escalation tools compare the current file with that baseline. A spec revision receives its new baseline only after the owner approves it. Restart, `/resume`, and deactivation discard the live baseline.
147
+ The committed `spec.md` represents the approved contract for the builder and verifier. The spec is immutable during a builder or verifier pass.
175
148
 
176
149
  ## Acceptance criterion simplicity principle
177
150
 
@@ -187,23 +160,29 @@ Expected result
187
160
  Breakage
188
161
  How to prove that the probe detects a broken behavior.
189
162
  ```
190
-
191
- Each distinct error behavior required by the spec must have its own acceptance criterion. Equivalent inputs that produce the same behavior can share one criterion.
192
-
193
- Builder and verifier both run the probe, apply the specified safe breakage, run the same probe again, restore the breakage, and run the probe again. They must restore every temporary change before the handoff.
163
+ Builder and verifier both run the probe, apply the specified safe breakage, run the same probe again, restore the breakage, and run the probe again. They restore every temporary change before the handoff.
194
164
 
195
165
  ## Escalations
196
166
 
197
167
  An escalation is the way Maestro brings a significant implementation discovery to the owner's attention and asks for a decision. It is not necessarily a technical failure, an error, or a blocker.
198
168
 
199
- An escalation is relevant when the work presents meaningful alternatives with different consequences. Examples include a conflict between the approved contract and the repository, behavior that the contract does not define, a material architectural alternative, a possible scope change, or a decision that affects verification or reversibility.
169
+ An escalation is relevant when the work presents meaningful alternatives with different consequences.
200
170
 
201
- Each escalation presents a question, context and evidence, available options, consequences, next steps, and an optional recommendation. While an escalation is unresolved, the workflow is paused in `escalation-decision` and the owner must decide how to proceed.
171
+ Examples:
172
+ - conflict between the approved spec and the repository.
173
+ - behavior that the spec does not define.
174
+ - a material architectural alternative.
175
+ - a possible scope change.
176
+ - a decision that affects verification or reversibility.
177
+
178
+ Each escalation presents a question, context and evidence, available options, consequences, next steps, and an optional recommendation.
179
+
180
+ While an escalation is unresolved, the workflow is paused in `escalation-decision` and the owner must decide how to proceed.
202
181
 
203
182
  The owner can choose one of two paths:
204
183
 
205
- - Continue with the current contract. Maestro records the decision and returns the workflow to `ready-for-builder` for another builder run.
206
- - Change the approved contract. The owner revises and approves `spec.md`, then calls `maestro_mark_spec_ready`. The workflow returns to `ready-for-builder` on the same branch and with the same `specId`.
184
+ - Continue with the current spec. Maestro records the decision and returns the workflow to `ready-for-builder` for another builder run.
185
+ - Change the approved spec. The owner revises and approves the spec, then the workflow returns to `ready-for-builder`.
207
186
 
208
187
  Each escalation remains in the workflow history as references.
209
188
 
@@ -214,26 +193,29 @@ A finding records a technical issue found by the verifier. Every finding blocks
214
193
  | Decision | Result |
215
194
  |---|---|
216
195
  | `reject` | Requires and records the owner’s reason. When every finding is rejected, the candidate becomes ready. |
217
- | `fix-code` | Keeps the current spec and starts another builder run. |
218
- | Spec must change | The owner revises `spec.md` from `findings-decision`; previous findings become historical. |
196
+ | `fix-code` | Keeps the current spec and returns the workflow to `ready-for-builder`. |
197
+ | Spec must change | The owner revises the spec from `findings-decision`; previous findings become historical. |
219
198
 
220
- When decisions are mixed, any `fix-code` decision starts another builder run. If the approved contract must change, the owner uses the same spec revision flow instead of resolving obsolete findings.
199
+ When decisions are mixed between `reject` and `fix-code`, any `fix-code` decision returns the workflow to `ready-for-builder`.
221
200
 
222
- ## Completion and Pull Request
201
+ If a finding requires a spec change, thw owner must approve a revised spec and run the builder again.
223
202
 
224
- The workflow ends at `candidate-ready` after a verifier run with no findings, or after the owner rejects every finding with a reason.
203
+ ## Spec revision
225
204
 
226
- The operations that produce this phase, `maestro_record_verifier_handoff` and `maestro_resolve_findings`, own the required checks:
205
+ A spec revision is allowed only from these blocked phases:
227
206
 
228
- 1. Before writing the transition, they make sure that the resulting handoff matches the spec identity and workflow revision, with no active findings.
229
- 2. They reject changes outside the expected protocol files. The verifier must also restore the product to the verified candidate.
230
- 3. They commit only the expected protocol files and return success only when the checkout is clean.
207
+ - `escalation-decision`
208
+ - `findings-decision`
231
209
 
232
- No final tool call or checkpoint is needed. `candidate-ready` is the last persisted Maestro phase.
210
+ The owner edits and approves the spec, then Maestro changes the phase to `ready-for-builder`.
233
211
 
234
- Maestro reads the artifacts and Git information to summarize the changes, verification results, rejected findings and reasons, and applicable builder notes. The summary includes the current branch and final `HEAD`. Rejected findings are owner decisions, not proof that verification passed.
212
+ The previous escalation or finding becomes inactive. Its artifact remains in the branch as historical context. Builder and verifier decide whether historical artifacts apply to the current spec.
213
+
214
+ ## Workflow completion
215
+
216
+ The workflow ends at `candidate-ready` after a verifier run with no findings, or after the owner rejects every finding with a reason.
235
217
 
236
- The summary does not change files or workflow state, create commits, or run verification again. The owner controls the Git flow, review, Pull Request, and merge. Maestro does not squash, stage, merge, create, or remove branches. It does not create worktrees.
218
+ Maestro reads the artifacts and Git information to summarize the changes, verification results, rejected findings and reasons, and applicable builder notes.
237
219
 
238
220
  ## Stored artifacts
239
221
 
@@ -255,6 +237,5 @@ The default spec directory contains:
255
237
  ```
256
238
 
257
239
  - `builder.json` and `verifier.json` represent the current handoffs and can be overwritten by later runs.
258
- - Builder handoff `notes` contain curated significant discoveries that did not require an owner decision; Maestro surfaces the applicable notes in the final workflow summary.
259
- - Escalations remain in the history directory.
240
+ - Builder handoff `notes` contain curated significant discoveries that did not require an owner decision; Maestro surfaces the applicable notes in the final workflow summary.
260
241
  - Earlier versions of all artifacts remain in Git commits.
@@ -12,14 +12,6 @@ import {
12
12
  CREATE_SPEC_TOOL,
13
13
  registerCreateSpecTool,
14
14
  } from '#tools/main/create-spec.ts';
15
- import {
16
- LAUNCH_BUILDER_TOOL,
17
- registerLaunchBuilderTool,
18
- } from '#tools/main/launch-builder.ts';
19
- import {
20
- LAUNCH_VERIFIER_TOOL,
21
- registerLaunchVerifierTool,
22
- } from '#tools/main/launch-verifier.ts';
23
15
  import {
24
16
  MARK_SPEC_READY_TOOL,
25
17
  registerMarkSpecReadyTool,
@@ -32,22 +24,30 @@ import {
32
24
  RESOLVE_FINDINGS_TOOL,
33
25
  registerResolveFindingsTool,
34
26
  } from '#tools/main/resolve-findings.ts';
27
+ import {
28
+ RUN_BUILDER_TOOL,
29
+ registerRunBuilderTool,
30
+ } from '#tools/main/run-builder.ts';
31
+ import {
32
+ RUN_VERIFIER_TOOL,
33
+ registerRunVerifierTool,
34
+ } from '#tools/main/run-verifier.ts';
35
35
 
36
36
  const MAIN_TOOL_NAMES: readonly string[] = [
37
37
  CREATE_SPEC_TOOL.NAME,
38
38
  MARK_SPEC_READY_TOOL.NAME,
39
- LAUNCH_BUILDER_TOOL.NAME,
39
+ RUN_BUILDER_TOOL.NAME,
40
40
  RESOLVE_ESCALATION_TOOL.NAME,
41
- LAUNCH_VERIFIER_TOOL.NAME,
41
+ RUN_VERIFIER_TOOL.NAME,
42
42
  RESOLVE_FINDINGS_TOOL.NAME,
43
43
  ];
44
44
 
45
45
  export default (pi: ExtensionAPI): void => {
46
46
  registerCreateSpecTool(pi);
47
47
  registerMarkSpecReadyTool(pi);
48
- registerLaunchBuilderTool(pi);
48
+ registerRunBuilderTool(pi);
49
49
  registerResolveEscalationTool(pi);
50
- registerLaunchVerifierTool(pi);
50
+ registerRunVerifierTool(pi);
51
51
  registerResolveFindingsTool(pi);
52
52
 
53
53
  const syncMainTools = (): void => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@emiliosp/pi-maestro",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "A spec-driven multiagent development workflow for Pi.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -3,15 +3,13 @@
3
3
  * Used: When Maestro initializes for a repository.
4
4
  */
5
5
 
6
- import { lstat, readFile, realpath } from 'node:fs/promises';
7
- import { dirname, isAbsolute, join, relative, resolve } from 'node:path';
6
+ import { readFile, realpath } from 'node:fs/promises';
7
+ import { isAbsolute, join, resolve } from 'node:path';
8
8
  import { assertConfiguration } from '#config/assertConfiguration.ts';
9
9
  import { CONFIG_FILE_PATH, DEFAULT_CONFIG } from '#config/defaults.ts';
10
10
  import type { MaestroConfig, PartialMaestroConfig } from '#config/schema.ts';
11
- import { isErrnoException } from '#utils/is-errno-exception.ts';
12
11
  import { pathExists } from '#utils/path-exists.ts';
13
12
  import { isPathStrictlyWithin } from '#utils/path-strictly-within.ts';
14
- import { isPathWithinOrEqual } from '#utils/path-within-or-equal.ts';
15
13
 
16
14
  const resolveConfiguration = (input: PartialMaestroConfig): MaestroConfig => {
17
15
  const resolved: MaestroConfig = {
@@ -35,43 +33,6 @@ const resolveConfiguration = (input: PartialMaestroConfig): MaestroConfig => {
35
33
  return resolved;
36
34
  };
37
35
 
38
- type ExistingAncestor = {
39
- path: string;
40
- realPath: string;
41
- };
42
-
43
- const findExistingAncestor = async (
44
- path: string,
45
- ): Promise<ExistingAncestor> => {
46
- let anchestor = path;
47
-
48
- while (true) {
49
- try {
50
- // lstat instead of access, because access follows symlinks
51
- await lstat(anchestor);
52
- } catch (error) {
53
- if (!isErrnoException(error) || error.code !== 'ENOENT') {
54
- throw error;
55
- }
56
-
57
- const parent = dirname(anchestor);
58
-
59
- if (parent === anchestor) {
60
- throw new Error(`Cannot resolve an existing ancestor for "${path}".`);
61
- }
62
-
63
- anchestor = parent;
64
- continue;
65
- }
66
-
67
- try {
68
- return { path: anchestor, realPath: await realpath(anchestor) };
69
- } catch {
70
- throw new Error(`Cannot resolve symlink "${anchestor}".`);
71
- }
72
- }
73
- };
74
-
75
36
  type AssertSafeDirectoryInput = {
76
37
  value: string;
77
38
  name: string;
@@ -96,11 +57,11 @@ type ResolveSafeDirectoryInput = {
96
57
  name: string;
97
58
  };
98
59
 
99
- const resolveSafeDirectory = async ({
60
+ const resolveSafeDirectory = ({
100
61
  repositoryRoot,
101
62
  directory,
102
63
  name,
103
- }: ResolveSafeDirectoryInput): Promise<string> => {
64
+ }: ResolveSafeDirectoryInput): string => {
104
65
  assertSafeDirectoryInput({ value: directory, name });
105
66
 
106
67
  const requestedDirectory = resolve(repositoryRoot, directory);
@@ -118,31 +79,7 @@ const resolveSafeDirectory = async ({
118
79
  throw new Error(`${name} must stay inside the Git root.`);
119
80
  }
120
81
 
121
- // The directory could not exist at the check time. We find the existing anchestor and do the check on that.
122
- const ancestor = await findExistingAncestor(requestedDirectory);
123
-
124
- if (
125
- !isPathWithinOrEqual({
126
- parent: repositoryRoot,
127
- candidate: ancestor.realPath,
128
- })
129
- ) {
130
- throw new Error(`${name} resolves outside the Git root through a symlink.`);
131
- }
132
-
133
- const unresolvedSuffix = relative(ancestor.path, requestedDirectory);
134
- const resolvedDirectory = resolve(ancestor.realPath, unresolvedSuffix);
135
-
136
- if (
137
- !isPathStrictlyWithin({
138
- parent: repositoryRoot,
139
- candidate: resolvedDirectory,
140
- })
141
- ) {
142
- throw new Error(`${name} resolves outside the Git root through a symlink.`);
143
- }
144
-
145
- return resolvedDirectory;
82
+ return requestedDirectory;
146
83
  };
147
84
 
148
85
  type ResolveDirectoriesInput = {
@@ -150,13 +87,11 @@ type ResolveDirectoriesInput = {
150
87
  config: MaestroConfig;
151
88
  };
152
89
 
153
- const resolveDirectories = async ({
154
- repositoryRoot: configuredRepositoryRoot,
90
+ const resolveDirectories = ({
91
+ repositoryRoot,
155
92
  config,
156
- }: ResolveDirectoriesInput): Promise<MaestroConfig> => {
157
- const repositoryRoot = await realpath(configuredRepositoryRoot);
158
-
159
- const specDirectory = await resolveSafeDirectory({
93
+ }: ResolveDirectoriesInput): MaestroConfig => {
94
+ const specDirectory = resolveSafeDirectory({
160
95
  repositoryRoot,
161
96
  directory: config.specDirectory,
162
97
  name: 'specDirectory',
@@ -186,7 +121,7 @@ export const loadConfiguration = async (
186
121
  const targetPath = join(repositoryRoot, CONFIG_FILE_PATH);
187
122
 
188
123
  if (!(await pathExists(targetPath))) {
189
- return await resolveDirectories({ repositoryRoot, config: DEFAULT_CONFIG });
124
+ return resolveDirectories({ repositoryRoot, config: DEFAULT_CONFIG });
190
125
  }
191
126
 
192
127
  const parsed = await readConfigurationFile(targetPath);
@@ -194,5 +129,5 @@ export const loadConfiguration = async (
194
129
  assertConfiguration(parsed);
195
130
  const config = resolveConfiguration(parsed);
196
131
 
197
- return await resolveDirectories({ repositoryRoot, config });
132
+ return resolveDirectories({ repositoryRoot, config });
198
133
  };
@@ -15,11 +15,11 @@ A builder escalation is an owner decision checkpoint, not only a technical failu
15
15
 
16
16
  If the approved contract must change from escalation-decision or findings-decision, the owner revises and approves the same specId, then calls maestro_mark_spec_ready. If a builder reports failed for a technical reason, Maestro reports the error and stops the workflow. The owner is responsible for the follow-up; there is no retry or spec revision from builder-failed.
17
17
 
18
- Use the deterministic maestro_* tools for workflow mutations, Git operations, artifact changes, and agent launches. Do not perform these mutations through generic tools.
18
+ Use the deterministic maestro_* tools for workflow mutations, Git operations, artifact changes, and agent runs. Do not perform these mutations through generic tools.
19
19
 
20
20
  While Maestro mode is active, use generic tools to inspect and discuss the repository, but do not edit normal product files. Builder and verifier work through their dedicated handoff tools and do not communicate with the owner directly. Do not treat their conclusions as owner decisions.
21
21
 
22
- The verifier uses the parent of the verifier-running checkpoint as its candidate and must restore product changes before its handoff. The verifier handoff tool owns the protocol commit. The verifier handoff and finding resolution operations own the checks required to reach candidate-ready.
22
+ The verifier uses the verifier-running checkpoint itself as its fixed candidate and must restore product changes before its handoff. The verifier handoff tool owns the protocol commit. The verifier handoff and finding resolution operations own the checks required to reach candidate-ready.
23
23
 
24
24
  The workflow ends at candidate-ready. No final tool call, checkpoint, or owner commit is required. You own the final summary. Use inspection tools to read the existing artifacts and Git information. Summarize the changes, verification results, rejected findings with their reasons, and applicable builder notes. Include the current branch and final HEAD after the protocol commit as the Pull Request facts. Do not present owner rejections as passed verification.
25
25