@emiliosp/pi-maestro 0.16.0 → 0.17.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/CHANGELOG.md CHANGED
@@ -3,6 +3,17 @@
3
3
  This file summarizes meaningful changes to the codebase, including behavior, data formats, architecture, and development tools. Git tags identify version boundaries;
4
4
  GitHub Releases are not required.
5
5
 
6
+ ## 0.17.0
7
+
8
+ 1. Added a standalone internal Pi SDK executor. Each invocation starts a fresh conversation with supplied model, thinking level, role guidance, working directory, and
9
+ additional tools. Native resource discovery loads instructions, skills, enabled extensions, and configured MCP, codemode, and tool search support, excluding the main
10
+ `Maestro` extension.
11
+ 2. Added native child session persistence in `subagents/` beneath Pi's project session directory.
12
+ 3. Replaced the `acceptance criterion` `probe` and `expected result` fields with `GIVEN`, `WHEN`, and `THEN`, keeping the concrete example. Requirement bodies now use a
13
+ named actor followed by `MUST` in the requirement heading. Added an optional bullet-list `## Assumptions` section to `spec.md`.
14
+
15
+ The `builder`, `verifier`, and `simplifier` still use `pi-subagents`. Workflow migration and dependency removal remain separate work.
16
+
6
17
  ## 0.16.0
7
18
 
8
19
  1. Required Pi 1.5.0 or later and pinned the development Pi dependencies to that baseline, so type checks and tests run against the declared host. The extension now uses
package/README.md CHANGED
@@ -45,7 +45,7 @@ The following official sources document the conceptual references. The links poi
45
45
  2. **Describe behavior, not routine implementation choices.** [OpenSpec's schema][openspec-schema] defines a `specification` as a behavior contract, not an implementation
46
46
  plan. `Maestro` records required behavior, constraints, and approved architectural decisions in the `spec`, leaving routine implementation choices to the `builder`.
47
47
  3. **Use concrete, testable scenarios.** [OpenSpec's schema][openspec-schema] pairs requirements with scenarios; [Spec Kit's template][spec-kit-template] uses
48
- Given/When/Then acceptance scenarios. Each `Maestro` `acceptance criterion` includes a `probe`, an `expected result`, and a concrete example.
48
+ Given/When/Then acceptance scenarios. Each `Maestro` `acceptance criterion` includes a `GIVEN`, a `WHEN`, a `THEN`, and a concrete example.
49
49
  4. **Clarify requirements progressively.** [Spec Kit's clarify command][spec-kit-clarify] asks one question at a time and integrates accepted answers into the
50
50
  `specification`. `Maestro` likewise asks one focused question, waits for the owner's answer, and updates the `spec` before asking the next question.
51
51
  5. **Review requirements separately from testing code.** [Spec Kit's checklist command][spec-kit-checklist] evaluates requirements for completeness, clarity, consistency,
@@ -54,7 +54,7 @@ The following official sources document the conceptual references. The links poi
54
54
  6. **Separate motivation, behavior, and design.** [OpenSpec's schema][openspec-schema] separates these concerns and calls for `design.md` only when significant technical
55
55
  decisions need recording, including reasons, alternatives, and risks.
56
56
  7. **Make requirement changes explicit.** [OpenSpec's schema][openspec-schema] distinguishes added, modified, removed, and renamed requirements. `Maestro` adapts this
57
- concept with one `Delta` field per requirement: `added`, `modified`, or `removed`. Each requirement states the complete required outcome.
57
+ concept with one `Delta` field per requirement: `added`, `modified`, or `removed`. Each requirement heading states the required outcome with a named actor and `MUST`.
58
58
  8. **Make requirement coverage traceable.** [Spec Kit's analyze command][spec-kit-analyze] maps requirements to implementation tasks and identifies coverage gaps.
59
59
  `Maestro` applies a related principle to verification: each requirement has a `Verified by` field linking to its `acceptance criteria`, existing tests covering exact
60
60
  scenarios, or both. The mapping connects requirements to verification.
package/ROADMAP.md CHANGED
@@ -10,37 +10,38 @@ reaching `candidate-ready`. Linear onboarding and test issues are not project ro
10
10
 
11
11
  ## Overview
12
12
 
13
- | ID | Item | Status |
14
- | -------------- | ---------------------------------------------------------------------------------------------------------------------------------- | --------- |
15
- | MAESTRO-6 | [Display specs in a browser](#maestro-6-display-specs-in-a-browser) | Backlog |
16
- | MAESTRO-7 | [Route builder failures through owner escalations](#maestro-7-route-builder-failures-through-owner-escalations) | Completed |
17
- | MAESTRO-8 | [Store escalations and owner decisions in builder handoffs](#maestro-8-store-escalations-and-owner-decisions-in-builder-handoffs) | Completed |
18
- | MAESTRO-9 | [Format glossary terms consistently](#maestro-9-format-glossary-terms-consistently) | Completed |
19
- | MAESTRO-10 | [Improve status presentation and activation feedback](#maestro-10-improve-status-presentation-and-activation-feedback) | Completed |
20
- | MAESTRO-11 | [Introduce Maestro at activation](#maestro-11-introduce-maestro-at-activation) | Completed |
21
- | MAESTRO-12 | [Verify code quality against AGENTS.md instructions](#maestro-12-verify-code-quality-against-agentsmd-instructions) | Completed |
22
- | MAESTRO-13 | [Check subagent extensions at activation](#maestro-13-check-subagent-extensions-at-activation) | Completed |
23
- | MAESTRO-14 | [Rename the test support directory](#maestro-14-rename-the-test-support-directory) | Completed |
24
- | MAESTRO-15 | [Match handoff criteria to the approved spec](#maestro-15-match-handoff-criteria-to-the-approved-spec) | Completed |
25
- | MAESTRO-16 | [Route finding-driven spec revisions through drafting-spec](#maestro-16-route-finding-driven-spec-revisions-through-drafting-spec) | Completed |
26
- | MAESTRO-17 | [Keep acceptance criterion numbering continuous](#maestro-17-keep-acceptance-criterion-numbering-continuous) | Completed |
27
- | MAESTRO-18 | [Record escalation resolutions when the spec changes](#maestro-18-record-escalation-resolutions-when-the-spec-changes) | Completed |
28
- | MAESTRO-19 | [Guide initial configuration](#maestro-19-guide-initial-configuration) | Backlog |
29
- | MAESTRO-20 | [Rename the npm package](#maestro-20-rename-the-npm-package) | Backlog |
30
- | MAESTRO-21 | [Label acceptance criterion coverage](#maestro-21-label-acceptance-criterion-coverage) | Completed |
31
- | MAESTRO-22 | [Avoid acceptance criteria already covered by tests](#maestro-22-avoid-acceptance-criteria-already-covered-by-tests) | Completed |
32
- | MAESTRO-23 | [Change agent models before a builder run](#maestro-23-change-agent-models-before-a-builder-run) | Backlog |
33
- | MAESTRO-24 | [Add a simplifier with one clear purpose per agent](#maestro-24-add-a-simplifier-with-one-clear-purpose-per-agent) | Completed |
34
- | MAESTRO-25 | [Define workflow reconciliation](#maestro-25-define-workflow-reconciliation) | Backlog |
35
- | MAESTRO-26 | [Exit Maestro mode automatically at workflow completion](#maestro-26-exit-maestro-mode-automatically-at-workflow-completion) | Completed |
36
- | MAESTRO-27 | [Make all implementation phases optional](#maestro-27-make-all-implementation-phases-optional) | Completed |
37
- | MAESTRO-FREE-1 | [Require Pi 1.5.0](#maestro-free-1-require-pi-150) | Completed |
38
- | MAESTRO-FREE-2 | [Remove Maestro run timeouts](#maestro-free-2-remove-maestro-run-timeouts) | Backlog |
39
- | MAESTRO-FREE-3 | [Run the builder through the Pi SDK](#maestro-free-3-run-the-builder-through-the-pi-sdk) | Backlog |
40
- | MAESTRO-FREE-4 | [Run the verifier through the Pi SDK](#maestro-free-4-run-the-verifier-through-the-pi-sdk) | Backlog |
41
- | MAESTRO-FREE-5 | [Run the simplifier through the Pi SDK](#maestro-free-5-run-the-simplifier-through-the-pi-sdk) | Backlog |
42
- | MAESTRO-FREE-6 | [Show SDK agent activity through Pi](#maestro-free-6-show-sdk-agent-activity-through-pi) | Backlog |
43
- | MAESTRO-FREE-7 | [Remove the pi-subagents dependency](#maestro-free-7-remove-the-pi-subagents-dependency) | Backlog |
13
+ | ID | Item | Status |
14
+ | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------- | ----------- |
15
+ | MAESTRO-6 | [Display specs in a browser](#maestro-6-display-specs-in-a-browser) | Backlog |
16
+ | MAESTRO-7 | [Route builder failures through owner escalations](#maestro-7-route-builder-failures-through-owner-escalations) | Completed |
17
+ | MAESTRO-8 | [Store escalations and owner decisions in builder handoffs](#maestro-8-store-escalations-and-owner-decisions-in-builder-handoffs) | Completed |
18
+ | MAESTRO-9 | [Format glossary terms consistently](#maestro-9-format-glossary-terms-consistently) | Completed |
19
+ | MAESTRO-10 | [Improve status presentation and activation feedback](#maestro-10-improve-status-presentation-and-activation-feedback) | Completed |
20
+ | MAESTRO-11 | [Introduce Maestro at activation](#maestro-11-introduce-maestro-at-activation) | Completed |
21
+ | MAESTRO-12 | [Verify code quality against AGENTS.md instructions](#maestro-12-verify-code-quality-against-agentsmd-instructions) | Completed |
22
+ | MAESTRO-13 | [Check subagent extensions at activation](#maestro-13-check-subagent-extensions-at-activation) | Completed |
23
+ | MAESTRO-14 | [Rename the test support directory](#maestro-14-rename-the-test-support-directory) | Completed |
24
+ | MAESTRO-15 | [Match handoff criteria to the approved spec](#maestro-15-match-handoff-criteria-to-the-approved-spec) | Completed |
25
+ | MAESTRO-16 | [Route finding-driven spec revisions through drafting-spec](#maestro-16-route-finding-driven-spec-revisions-through-drafting-spec) | Completed |
26
+ | MAESTRO-17 | [Keep acceptance criterion numbering continuous](#maestro-17-keep-acceptance-criterion-numbering-continuous) | Completed |
27
+ | MAESTRO-18 | [Record escalation resolutions when the spec changes](#maestro-18-record-escalation-resolutions-when-the-spec-changes) | Completed |
28
+ | MAESTRO-19 | [Guide initial configuration](#maestro-19-guide-initial-configuration) | Backlog |
29
+ | MAESTRO-20 | [Rename the npm package](#maestro-20-rename-the-npm-package) | Backlog |
30
+ | MAESTRO-21 | [Label acceptance criterion coverage](#maestro-21-label-acceptance-criterion-coverage) | Completed |
31
+ | MAESTRO-22 | [Avoid acceptance criteria already covered by tests](#maestro-22-avoid-acceptance-criteria-already-covered-by-tests) | Completed |
32
+ | MAESTRO-23 | [Change agent models before a builder run](#maestro-23-change-agent-models-before-a-builder-run) | Backlog |
33
+ | MAESTRO-24 | [Add a simplifier with one clear purpose per agent](#maestro-24-add-a-simplifier-with-one-clear-purpose-per-agent) | Completed |
34
+ | MAESTRO-25 | [Define workflow reconciliation](#maestro-25-define-workflow-reconciliation) | Backlog |
35
+ | MAESTRO-26 | [Exit Maestro mode automatically at workflow completion](#maestro-26-exit-maestro-mode-automatically-at-workflow-completion) | Completed |
36
+ | MAESTRO-27 | [Make all implementation phases optional](#maestro-27-make-all-implementation-phases-optional) | Completed |
37
+ | MAESTRO-FREE-1 | [Require Pi 1.5.0](#maestro-free-1-require-pi-150) | Completed |
38
+ | MAESTRO-FREE-2 | [Remove Maestro run timeouts](#maestro-free-2-remove-maestro-run-timeouts) | Completed |
39
+ | MAESTRO-FREE-PRE-3 | [Implement internal SDK delegation](#maestro-free-pre-3-implement-internal-sdk-delegation) | In progress |
40
+ | MAESTRO-FREE-3 | [Run the builder through the Pi SDK](#maestro-free-3-run-the-builder-through-the-pi-sdk) | Backlog |
41
+ | MAESTRO-FREE-4 | [Run the verifier through the Pi SDK](#maestro-free-4-run-the-verifier-through-the-pi-sdk) | Backlog |
42
+ | MAESTRO-FREE-5 | [Run the simplifier through the Pi SDK](#maestro-free-5-run-the-simplifier-through-the-pi-sdk) | Backlog |
43
+ | MAESTRO-FREE-6 | [Show SDK agent activity through Pi](#maestro-free-6-show-sdk-agent-activity-through-pi) | Backlog |
44
+ | MAESTRO-FREE-7 | [Remove the pi-subagents dependency](#maestro-free-7-remove-the-pi-subagents-dependency) | Backlog |
44
45
 
45
46
  ## Backlog
46
47
 
@@ -97,92 +98,123 @@ Explore how `Maestro` can reconcile saved `artifacts` and workflow state. The re
97
98
 
98
99
  Not yet defined. The `owner` must define the intended outcome, recovery boundaries, and completion condition before this item can move forward.
99
100
 
100
- ### MAESTRO-FREE-2: Remove Maestro run timeouts
101
+ ### MAESTRO-FREE-PRE-3: Implement internal SDK delegation
102
+
103
+ #### Implementation and evidence
104
+
105
+ The standalone executor is implemented under `src/delegation/` against the [approved specification](.specs/20261105-212231-implement-internal-pi-sdk-delegation/spec.md).
106
+ Execution orchestration, session lifecycle, and pure reply interpretation are separated into `executeTask`, `SubSession`, and `readTaskResult`. Manual verification on Pi
107
+ 1.5.0 exercised fresh context, native and additional tools, MCP through tool search and codemode, sequential waiting, failure, cancellation, cleanup, and native session
108
+ persistence. See [manual evidence](docs/subagent-integration.md#manual-verification). The three workflow roles still use `pi-subagents`. Final `owner` acceptance and
109
+ completion are not recorded. The caller's message is named `prompt`, execution is inlined in `executeTask`, and cancellation comments explain Node.js `AbortError`. At the
110
+ owner's request, cancellation is forwarded only by the signal listener, without checks before or after the prompt or a retry at `agent_start`. An already cancelled signal
111
+ does not prevent submission, and an aborted signal alone does not turn a normal Pi result into an interruption.
101
112
 
102
113
  #### Objective
103
114
 
104
- Remove Maestro's per-agent deadline and the three `timeoutMinutes` settings, as decided in [ADR-010](ADR.md#adr-010-use-the-pi-sdk-for-sequential-agent-delegation).
105
- Remove schema fields, defaults, delegation timeout inputs, and related configuration documentation together.
115
+ Implement and verify one internal execution operation using `createAgentSession()`, following [ADR-010](ADR.md#adr-010-use-the-pi-sdk-for-sequential-agent-delegation).
116
+ The operation is independent of the `builder`, `verifier`, and `simplifier` roles. Callers supply the task, role instructions, model settings, working directory, and
117
+ additional tools needed for that execution.
118
+
119
+ #### Scope and dependencies
120
+
121
+ Requires [MAESTRO-FREE-1](#maestro-free-1-require-pi-150) and [MAESTRO-FREE-2](#maestro-free-2-remove-maestro-run-timeouts). This item implements the execution mechanism
122
+ without switching existing workflow tools away from `pi-subagents`. FREE-3, FREE-4, and FREE-5 connect the three roles to it together after it is verified.
123
+
124
+ The executor manages child sessions, not the workflow. It does not select phases, interpret role outcomes, or validate `handoffs`. Those responsibilities remain with the
125
+ callers and existing workflow operations. Communication remains task-and-`handoff`, without shared in-memory workflow state or a live supervisor dialogue. This is not a
126
+ new public tool or a general-purpose orchestration framework. Live progress presentation remains in [MAESTRO-FREE-6](#maestro-free-6-show-sdk-agent-activity-through-pi).
106
127
 
107
128
  #### Completed when
108
129
 
109
- 1. `Maestro` no longer supplies a per-agent deadline. Elapsed-time display and timeouts internal to Pi, tools, or the remaining `pi-subagents` integration are unchanged.
110
- 2. Configuration without `timeoutMinutes` works; configuration retaining it fails existing TypeBox validation with no migration or compatibility handling.
111
- 3. Other configuration behavior and the existing workflow remain unchanged.
130
+ 1. The operation executes a supplied task in a fresh SDK conversation with the supplied model and thinking level, role guidance, global and project instructions, skills,
131
+ working tools, and caller-supplied additional tools. It does not depend on any of the three workflow roles.
132
+ 2. Enabled global and project extensions and native Pi tool support load as defined in ADR-010, excluding the main `Maestro` extension. The main session retains its
133
+ `Maestro` mode while the child executes. No compatibility adapters, integration health gates, or delegation-prevention tool filters are added.
134
+ 3. Execution waits for the child to finish, fail, or be interrupted before another child starts. The executor imposes no automatic deadline and does not start a new
135
+ session to retry or repair failed work.
136
+ 4. Manual cancellation reaches `session.abort()` and waits for interruption. Sessions, subscriptions, and owned resources are released on every exit, without rollback,
137
+ workflow changes, or synthetic `handoffs`. Execution errors propagate to the caller.
138
+ 5. Native Pi sessions are persisted in `subagents/` beneath Pi's project session directory, resolved through Pi's API. The saved path is available to the caller on
139
+ completion or failure when a file exists. Every execution starts fresh; no automatic resumption is introduced.
140
+ 6. Successful execution, execution failure, cancellation, context and tool loading, and session persistence are verified independently of the workflow migration. The
141
+ existing three role tools still use `pi-subagents` at the end of this item.
112
142
 
113
143
  ### MAESTRO-FREE-3: Run the builder through the Pi SDK
114
144
 
115
145
  #### Objective
116
146
 
117
- Replace `builder` delegation with `createAgentSession()` and deliver a complete, usable SDK `builder` `run`, following
118
- [ADR-010](ADR.md#adr-010-use-the-pi-sdk-for-sequential-agent-delegation). This item includes the internal execution operation used by later role migrations; do not
119
- release an incomplete `builder` pending separate context, cancellation, or persistence work.
147
+ Connect `builder` delegation to the internal SDK executor delivered by [MAESTRO-FREE-PRE-3](#maestro-free-pre-3-implement-internal-sdk-delegation), following
148
+ [ADR-010](ADR.md#adr-010-use-the-pi-sdk-for-sequential-agent-delegation). Preserve the existing role instructions, `handoffs`, and workflow behavior.
120
149
 
121
150
  #### Scope and dependencies
122
151
 
123
- Requires [MAESTRO-FREE-1](#maestro-free-1-require-pi-150) and [MAESTRO-FREE-2](#maestro-free-2-remove-maestro-run-timeouts). Keep the `verifier` and `simplifier` on
124
- `pi-subagents`. The temporary routing is fixed in code, not a configurable engine selector or a general-purpose delegation framework. Human documentation must describe
125
- the actual mixed-engine state. Live SDK progress is covered separately by [MAESTRO-FREE-6](#maestro-free-6-show-sdk-agent-activity-through-pi); existing workflow-phase
126
- status remains available in the meantime.
152
+ Requires [MAESTRO-FREE-PRE-3](#maestro-free-pre-3-implement-internal-sdk-delegation). Implement FREE-3, [FREE-4](#maestro-free-4-run-the-verifier-through-the-pi-sdk), and
153
+ [FREE-5](#maestro-free-5-run-the-simplifier-through-the-pi-sdk) as one migration of all three roles. Their identifiers retain the role-specific verification scope, not
154
+ separate execution mechanisms or releases. Do not introduce temporary mixed-engine routing or an engine selector. Verify each role and the supported optional-phase
155
+ combinations before completing the migration. Human documentation must describe the resulting SDK execution. Live progress remains in
156
+ [MAESTRO-FREE-6](#maestro-free-6-show-sdk-agent-activity-through-pi); existing workflow-phase status remains available in the meantime.
127
157
 
128
158
  #### Completed when
129
159
 
130
160
  1. An approved `spec` can be implemented by an SDK `builder` with fresh conversation history, the configured model and thinking level, role guidance, global and project
131
161
  instructions, skills, working tools, and existing `handoff` tools.
132
- 2. Enabled global and project extensions load through Pi, excluding the main `Maestro` extension. Instructions forbid further delegation; there are no additional tool
133
- filters, integration health gates, compatibility adapters, or automatic retries.
162
+ 2. It reuses the established executor's context and tool loading without another execution mechanism. Role instructions continue to forbid further delegation.
134
163
  3. `done` and `escalation` outcomes preserve existing saved `handoffs`, validation, phase transitions, and subsequent workflow routes. A later `builder` `pass` starts
135
164
  fresh and reads saved decisions rather than restoring the previous conversation.
136
165
  4. Errors stop the workflow without rollback or repair. Manual cancellation reaches `session.abort()`, and child sessions and subscriptions are cleaned up on every exit.
137
166
  5. Native Pi session files are saved beneath the project's Pi session directory in `subagents/`. The `owner` receives the saved path on completion or failure when a file
138
167
  exists; it can be inspected or exported with Pi, without automatic resumption.
139
- 6. Existing trust, configuration, and model checks remain applicable. `pi-subagents` ping and launch-contract checks apply only to enabled roles still using that engine;
140
- a `builder`-only workflow uses the SDK without requiring a `pi-subagents` availability reply.
168
+ 6. Existing trust, configuration, and model checks remain applicable. Activation and execution no longer require `pi-subagents` ping or launch-contract checks for any
169
+ role. A `builder`-only workflow uses the SDK without requiring a `pi-subagents` availability reply.
141
170
  7. Each `run` waits for its child to finish or be interrupted before another starts. Existing optional-phase behavior remains intact.
142
171
 
143
172
  ### MAESTRO-FREE-4: Run the verifier through the Pi SDK
144
173
 
145
174
  #### Objective
146
175
 
147
- Move the `verifier` to the SDK execution operation delivered by [MAESTRO-FREE-3](#maestro-free-3-run-the-builder-through-the-pi-sdk), following
148
- [ADR-010](ADR.md#adr-010-use-the-pi-sdk-for-sequential-agent-delegation). Do not redesign verification or its reports.
176
+ Connect the `verifier` to the SDK executor delivered by [MAESTRO-FREE-PRE-3](#maestro-free-pre-3-implement-internal-sdk-delegation), following
177
+ [ADR-010](ADR.md#adr-010-use-the-pi-sdk-for-sequential-agent-delegation). Implement this role's switch together with FREE-3 and FREE-5 under the
178
+ [shared migration scope](#maestro-free-3-run-the-builder-through-the-pi-sdk). Do not redesign verification or its reports.
149
179
 
150
180
  #### Completed when
151
181
 
152
182
  1. The SDK `verifier` independently checks the approved `spec` and saves existing numbered `handoffs`, preserving criterion validation, `finding` decisions, and phase
153
183
  transitions.
154
184
  2. It reuses the established fresh-session context, tools, persistence, cancellation, cleanup, and error policy without a second execution mechanism.
155
- 3. Activation no longer asks `pi-subagents` to check or execute the `verifier`. Its remaining checks apply only to enabled roles still on that engine.
156
- 4. Workflows with verification enabled or disabled retain their existing routes. If the `simplifier` is not yet migrated, it continues to use `pi-subagents` unchanged.
185
+ 3. Activation and execution no longer use `pi-subagents` for the `verifier`.
186
+ 4. Workflows with verification enabled or disabled retain their existing routes, with all enabled roles using the common SDK executor.
157
187
 
158
188
  ### MAESTRO-FREE-5: Run the simplifier through the Pi SDK
159
189
 
160
190
  #### Objective
161
191
 
162
- Move the `simplifier` to the SDK execution operation delivered by [MAESTRO-FREE-3](#maestro-free-3-run-the-builder-through-the-pi-sdk), following
163
- [ADR-010](ADR.md#adr-010-use-the-pi-sdk-for-sequential-agent-delegation). Keep its existing purpose and Git-only scope.
192
+ Connect the `simplifier` to the SDK executor delivered by [MAESTRO-FREE-PRE-3](#maestro-free-pre-3-implement-internal-sdk-delegation), following
193
+ [ADR-010](ADR.md#adr-010-use-the-pi-sdk-for-sequential-agent-delegation). Implement this role's switch together with FREE-3 and FREE-4 under the
194
+ [shared migration scope](#maestro-free-3-run-the-builder-through-the-pi-sdk). Keep its existing purpose and Git-only scope.
164
195
 
165
196
  #### Completed when
166
197
 
167
198
  1. The SDK `simplifier` preserves the current Git readiness decision, skip behavior, and entry routes. No Git readiness check moves into activation or an earlier phase.
168
199
  2. Successful execution saves the existing unnumbered `S.json` `handoff` and reaches `candidate-ready`; optional-phase behavior remains unchanged.
169
200
  3. It reuses the established context, tools, persistence, cancellation, cleanup, and error policy.
170
- 4. Activation no longer asks `pi-subagents` to check or execute the `simplifier`. Once all roles have migrated, no workflow path requires its ping or launch preflight.
201
+ 4. Activation and execution no longer use `pi-subagents` for the `simplifier`. All roles migrate together, so no workflow path requires its ping, launch preflight, or
202
+ fixed delegation deadline.
171
203
 
172
204
  ### MAESTRO-FREE-6: Show SDK agent activity through Pi
173
205
 
174
206
  #### Objective
175
207
 
176
208
  Show activity for SDK-based agent `runs` through Pi's standard `onUpdate` presentation, as decided in
177
- [ADR-010](ADR.md#adr-010-use-the-pi-sdk-for-sequential-agent-delegation). Requires [MAESTRO-FREE-3](#maestro-free-3-run-the-builder-through-the-pi-sdk) and applies to
178
- each role as it is migrated.
209
+ [ADR-010](ADR.md#adr-010-use-the-pi-sdk-for-sequential-agent-delegation). Requires the shared migration covered by
210
+ [MAESTRO-FREE-3](#maestro-free-3-run-the-builder-through-the-pi-sdk), FREE-4, and FREE-5, and applies to all three roles through the common executor.
179
211
 
180
212
  #### Completed when
181
213
 
182
214
  1. Progress reports the role, elapsed time, current tool, and recent normal assistant text, including activity while the agent produces no text.
183
215
  2. Pi controls layout, truncation, and expansion. There is no custom renderer, fixed line count, transcript inspector, or artificial progress prompting.
184
216
  3. Intermediate text stays out of the main model's context. Final workflow results, saved session contents, and cancellation behavior remain unchanged.
185
- 4. Progress subscriptions are released when the child finishes, fails, or is interrupted. Roles still on `pi-subagents` retain their existing presentation.
217
+ 4. Progress subscriptions are released when the child finishes, fails, or is interrupted.
186
218
 
187
219
  ### MAESTRO-FREE-7: Remove the pi-subagents dependency
188
220
 
@@ -238,6 +270,21 @@ The `owner` confirmed completion. `README.md` declares Pi 1.5.0 as the minimum h
238
270
  and tests run against that baseline. Schema enums use TypeBox `Type.Enum` with an explicit string type. `npm run check` passes on 1.5.0, including the extension and
239
271
  `pi-subagents` integration tests.
240
272
 
273
+ ### MAESTRO-FREE-2: Remove Maestro run timeouts
274
+
275
+ #### Recorded outcome
276
+
277
+ The `owner` confirmed completion of the timeout configuration removal implemented in `0.16.0`. The three `timeoutMinutes` settings, their defaults, and their
278
+ configuration documentation were removed. Existing TypeBox validation rejects configuration retaining those fields, without migration or compatibility handling.
279
+
280
+ The current `pi-subagents` integration still receives a fixed deadline of 9,999 minutes. This is not unlimited execution. Removal of that remaining deadline belongs to
281
+ the SDK delegation replacement under [ADR-010](ADR.md#adr-010-use-the-pi-sdk-for-sequential-agent-delegation), not a separate prerequisite for it.
282
+
283
+ #### Evidence
284
+
285
+ [Changelog](CHANGELOG.md#0160), [PR #46](https://github.com/emilioSp/pi-maestro/pull/46), [configuration schema](src/config/schema.ts), and
286
+ [current delegation deadline](src/tools/utils/pi-subagent-delegation.ts).
287
+
241
288
  ### MAESTRO-27: Make all implementation phases optional
242
289
 
243
290
  #### Objective
package/agents/builder.md CHANGED
@@ -51,17 +51,17 @@ discoveries without an owner decision in handoff `notes`. Do not turn notes into
51
51
 
52
52
  ## Prove every acceptance criterion
53
53
 
54
- Run every probe, including on repair passes. Previous evidence does not replace this pass's results. The spec defines probe scenarios, expected results, and concrete
55
- examples. Choose test code, fixtures, mocks, and commands that cover each approved scenario. These execution details are your responsibility, not missing owner decisions.
56
- Follow any explicit execution constraints in the approved spec. Run each executable probe against the implementation and compare the observed result with the expected
57
- result. Do not change approved probe scenarios, expected results, examples, or design decisions to obtain passing results. If the implementation fails, repair it within
58
- the contract and repeat the proof for affected criteria. If the contract needs clarification or revision, escalate instead of inventing a replacement probe. For visual
54
+ Run every GIVEN, WHEN, and THEN scenario, including on repair passes. Previous evidence does not replace this pass's results. The spec defines those scenarios and
55
+ concrete examples. Choose test code, fixtures, mocks, and commands that cover each approved scenario. These execution details are your responsibility, not missing owner
56
+ decisions. Follow any explicit execution constraints in the approved spec. Run each scenario against the implementation and compare the observed result with the THEN
57
+ outcome. Do not change approved GIVEN, WHEN, and THEN scenarios, examples, or design decisions to obtain passing results. If the implementation fails, repair it within
58
+ the contract and repeat the proof for affected criteria. If the contract needs clarification or revision, escalate instead of inventing a replacement scenario. For visual
59
59
  claims, use the specified reproducible procedure and compare with prototypes when required. Run applicable repository checks. If subsequent changes invalidate earlier
60
60
  evidence, rerun the affected checks and proofs.
61
61
 
62
- For each criterion, record its exact `id`, actual command or procedure in `probe`, and `probeStatus`. Use `probeStatus: passed` when the observed result matches the
63
- expected result. Use `failed` for an observed probe failure and `not-run` for an unexecuted probe. Include every spec criterion once. Do not omit unrun criteria,
64
- fabricate evidence, or include secrets or full logs.
62
+ For each criterion, record its exact `id`, actual command or procedure in `probe`, and `probeStatus`. Use `probeStatus: passed` when the observed result matches the THEN
63
+ outcome. Use `failed` for an observed failure and `not-run` for a check that did not run. Include every spec criterion once. Do not omit unrun criteria, fabricate
64
+ evidence, or include secrets or full logs.
65
65
 
66
66
  ## Record exactly one outcome
67
67
 
@@ -40,28 +40,28 @@ candidate to make verification succeed.
40
40
  ## Regenerate every proof
41
41
 
42
42
  Verify every acceptance criterion from the candidate, including criteria checked in earlier runs. Do not trust the builder's results or silently change the approved
43
- behavior, probe scenarios, expected results, or examples. Read executable probes from the candidate and builder handoff. Independently check that they cover the approved
43
+ behavior, GIVEN, WHEN, and THEN scenarios, or examples. Read executable checks from the candidate and builder handoff. Independently check that they cover the approved
44
44
  scenarios. The spec need not prescribe test code, fixtures, mocks, commands, or exact code edits. Missing execution details alone are not a contract gap. Use temporary
45
45
  verification files when needed to execute an approved scenario. Do not repair existing tests or weaken their coverage. If the builder's checks miss required behavior,
46
- record a finding even if your own probe passes. Follow any explicit execution constraints in the approved spec. Run each executable probe against the candidate and
47
- compare the observed result with the expected result. If a probe fails, record a finding. Do not repair the candidate. If a probe is unsafe, undefined, or impossible to
48
- execute, record the limitation as a finding. Continue with other criteria that can be checked safely. Do not stop the entire review at the first finding. Use temporary
49
- files only as needed for the specified probes. Remove them before handoff. For visual claims, produce reproducible evidence through the spec's procedure, including
50
- prototype comparisons when required.
46
+ record a finding even if your own check passes. Follow any explicit execution constraints in the approved spec. Run each scenario against the candidate and compare the
47
+ observed result with the THEN outcome. If the observed result does not match, record a finding. Do not repair the candidate. If a scenario is unsafe, undefined, or
48
+ impossible to execute, record the limitation as a finding. Continue with other criteria that can be checked safely. Do not stop the entire review at the first finding.
49
+ Use temporary files only as needed for the specified scenarios. Remove them before handoff. For visual claims, produce reproducible evidence through the spec's procedure,
50
+ including prototype comparisons when required.
51
51
 
52
52
  Follow applicable repository commands and technical rules. Do not invent required commands. Inspect check scripts before execution. Do not use automatic fixes to repair
53
53
  the candidate. If a required check changes files, record that effect and restore those changes before further verification. A result obtained only after an automatic fix
54
54
  does not prove that the candidate passes.
55
55
 
56
- For each criterion, record its exact `id`, actual command or procedure in `probe`, and `probeStatus`. Use `probeStatus: passed` when the observed result matches the
57
- expected result. Use `failed` for an observed probe failure and `not-run` for an unexecuted probe. Include every spec criterion once. Never omit unrun criteria or
58
- fabricate evidence.
56
+ For each criterion, record its exact `id`, actual command or procedure in `probe`, and `probeStatus`. Use `probeStatus: passed` when the observed result matches the THEN
57
+ outcome. Use `failed` for an observed failure and `not-run` for a check that did not run. Include every spec criterion once. Never omit unrun criteria or fabricate
58
+ evidence.
59
59
 
60
60
  ## Record findings, not decisions
61
61
 
62
- Record technical issues supported by fresh evidence. Do not add requirements, style preferences, or unrelated improvements. Give every criterion with a probe other than
63
- `passed` at least one related finding. Report required repository check failures as findings, even when every acceptance criterion passes. Do not copy an earlier
64
- rejection into a new finding. Only the owner can reject current findings through Maestro.
62
+ Record technical issues supported by fresh evidence. Do not add requirements, style preferences, or unrelated improvements. Give every criterion with a `probeStatus`
63
+ other than `passed` at least one related finding. Report required repository check failures as findings, even when every acceptance criterion passes. Do not copy an
64
+ earlier rejection into a new finding. Only the owner can reject current findings through Maestro.
65
65
 
66
66
  For each finding, follow the tool schema:
67
67
 
package/docs/glossary.md CHANGED
@@ -6,13 +6,15 @@
6
6
  | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
7
7
  | `Owner` | The person who approves the `spec`, decides questions and `findings`, and performs the final review. |
8
8
  | `Maestro` | The coordinator that prepares the `spec`, runs the agents, and records `owner` decisions. |
9
- | `Builder` | The agent that implements the approved `spec` and runs its `probes`. |
9
+ | `Builder` | The agent that implements the approved `spec` and runs every `GIVEN`, `WHEN`, and `THEN` scenario. |
10
10
  | `Verifier` | The independent agent that checks the implementation and reports technical issues. |
11
11
  | `Simplifier` | The agent that refactors accepted code for clarity without changing behavior or introducing check failures. |
12
12
  | `Spec` | A `specification` for one change: `proposal.md` for motivation and scope, `spec.md` for behavior and `acceptance criteria`, and optional `design.md` for technical decisions. The present documents are approved and frozen together. |
13
13
  | `Acceptance criterion` (`AC`) | One required, observable result defined in the `spec`. |
14
- | `Probe` | A scenario used to test an `acceptance criterion`. Reports record the actual command or procedure and its outcome. |
15
- | `Expected result` | The observable result that a `probe` must produce. |
14
+ | `GIVEN` | The starting conditions of an `acceptance criterion`. |
15
+ | `WHEN` | The action or observation that checks the behavior of an `acceptance criterion`. |
16
+ | `THEN` | The measurable outcome the `WHEN` must produce. |
17
+ | `Assumption` | A detail the request did not specify or a scope boundary taken as given. A false `assumption` during implementation is an `escalation` trigger. |
16
18
  | `Artifact` | A saved workflow file, such as a `spec`, or a `handoff` between agents. |
17
19
  | `Handoff` | A saved agent report. `Builder` and `verifier` reports include `probe` outcomes. A `simplifier` report includes refactored files, a summary, and notes. |
18
20
  | `Observability` | The owner's ability to inspect workflow progress and reported results. |
package/docs/workflow.md CHANGED
@@ -5,7 +5,8 @@
5
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
6
  records significant technical decisions. The set forms one contract for the change.
7
7
 
8
- An `acceptance criterion` contains a `probe`, an `expected result`, and an example. A `probe` is a scenario used to test behavior.
8
+ An `acceptance criterion` contains one `GIVEN`, one `WHEN`, one `THEN`, and an example. `GIVEN` and `WHEN` describe the scenario, and `THEN` states the measurable
9
+ outcome.
9
10
 
10
11
  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.
11
12
 
@@ -14,13 +15,13 @@ issues.
14
15
 
15
16
  ## Roles
16
17
 
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. |
18
+ | Role | Responsibility |
19
+ | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
20
+ | `Owner` | Decides requirements, scope, technical decisions, `spec` approval, `escalation` answers, and `finding` decisions. Performs the final review. |
21
+ | `Maestro` | Prepares the `spec` with the `owner`, records workflow progress, runs agents, presents issues, and saves `owner` decisions. |
22
+ | `Builder` | Implements the approved `spec` and runs every `GIVEN`, `WHEN`, and `THEN` scenario. Reports completion or an `escalation`, including technical problems that prevent completion. |
23
+ | `Verifier` | Independently runs every `GIVEN`, `WHEN`, and `THEN` scenario against the live project files. Reports `findings` without repairing product code. |
24
+ | `Simplifier` | Refactors accepted code for clarity without changing behavior or introducing check failures. |
24
25
 
25
26
  `Builder`, `verifier`, and `simplifier` `runs` are sequential foreground operations. Each starts with a fresh conversation and reads the `spec` and saved `artifacts`.
26
27
 
@@ -107,18 +108,18 @@ The default path is `.specs/<spec-id>/workflow.json`. The `spec` directory is [c
107
108
 
108
109
  Each new `spec` uses these documents in the same directory:
109
110
 
110
- | Document | Content | Presence |
111
- | ------------- | ------------------------------------------------------------------------------------------------- | -------------------------------------------------------------- |
112
- | `proposal.md` | Problem, goal, scope, and exclusions. | Always created. |
113
- | `spec.md` | Required behavior, constraints, deltas, and `acceptance criteria` next to their requirements. | Always created. |
114
- | `design.md` | Approved technical decisions, brief reasons, relevant contracts, risks, and prototype references. | Only when significant technical decisions need to be recorded. |
111
+ | Document | Content | Presence |
112
+ | ------------- | ------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------- |
113
+ | `proposal.md` | Problem, goal, scope, and exclusions. | Always created. |
114
+ | `spec.md` | Required behavior, constraints, deltas, `acceptance criteria` next to their requirements, and `assumptions`. | Always created. |
115
+ | `design.md` | Approved technical decisions, brief reasons, relevant contracts, risks, and prototype references. | Only when significant technical decisions need to be recorded. |
115
116
 
116
117
  ## Spec approval
117
118
 
118
119
  For the initial `spec`:
119
120
 
120
121
  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.
121
- 2. The `owner` reviews the complete document set: motivation, scope, requirements, `acceptance criteria`, and any approved technical decisions.
122
+ 2. The `owner` reviews the complete document set: motivation, scope, requirements, `acceptance criteria`, `assumptions`, and any approved technical decisions.
122
123
  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
124
  the selected phases.
124
125
  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.
@@ -152,24 +153,23 @@ continuous across the whole document, including standalone regression criteria,
152
153
  For example, a change that introduces persistent item titles can describe its requirement and linked `acceptance criterion` in `spec.md` as follows:
153
154
 
154
155
  ```markdown
155
- ### REQ1: Persist saved titles
156
+ ### REQ1: The system MUST persist saved titles
156
157
 
157
158
  Delta: added
158
159
 
159
- Saving and reopening an item must preserve its title.
160
-
161
160
  Verified by: [AC1](#ac1-saved-title-is-persisted)
162
161
 
163
162
  #### AC1: Saved title is persisted
164
163
 
165
- 1. Probe: Save a change to an item's title, then reopen the item.
166
- 2. Expected result: The saved title is still present.
167
- 3. Example: Change the title from "Draft" to "Ready", save, and reopen the item. The title is "Ready".
164
+ - GIVEN a saved item.
165
+ - WHEN its title is changed and saved, then the item is reopened.
166
+ - THEN the saved title is present.
167
+ - Example: Change the title from "Draft" to "Ready", save, and reopen the item. The title is "Ready".
168
168
  ```
169
169
 
170
170
  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
171
- 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
172
- needed. A requirement can reference both criteria and existing tests.
171
+ conditions, action, and outcome, `Verified by` links to the test file relative to `spec.md` and includes the exact scenario name. No duplicate criterion is needed. A
172
+ requirement can reference both criteria and existing tests.
173
173
 
174
174
  Before approval, `Maestro` follows the links and checks that their combined scenarios verify the whole requirement. Missing, partial, or uncertain coverage must be
175
175
  resolved with an appropriate criterion or a confirmed existing test. References are updated when criterion headings or test locations change, including during `spec`
@@ -190,19 +190,27 @@ For example, if saving item descriptions already works, adding title persistence
190
190
 
191
191
  ### AC2: Existing descriptions remain saved
192
192
 
193
- 1. Probe: Change and save the title of an item with a saved description, then reopen it.
194
- 2. Expected result: The description is unchanged.
195
- 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".
193
+ - GIVEN an item with a saved description.
194
+ - WHEN its title is changed and saved, then the item is reopened.
195
+ - THEN the description is unchanged.
196
+ - 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".
196
197
  ```
197
198
 
198
199
  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
199
200
  requirement-associated criteria:
200
201
 
201
- | Part | Content |
202
- | ----------------- | ---------------------------------------------------------------------------------- |
203
- | `Probe` | Starting conditions and the action or observation that checks the behavior. |
204
- | `Expected result` | The measurable result the `probe` observes. |
205
- | Example | Concrete starting conditions, an input or action, and the exact `expected result`. |
202
+ | Part | Content |
203
+ | --------- | ------------------------------------------------------------------------ |
204
+ | `GIVEN` | Starting conditions. |
205
+ | `WHEN` | The action or observation that checks the behavior. |
206
+ | `THEN` | The measurable outcome the `WHEN` must produce. |
207
+ | `Example` | Concrete starting conditions, an input or action, and the exact outcome. |
208
+
209
+ ## Assumptions
210
+
211
+ An `assumption` records a detail the request did not specify or a scope boundary taken as given. `Maestro` writes short `assumptions` in a `## Assumptions` section of
212
+ `spec.md` as a bullet list, without paragraphs. The section is omitted when there are none. An `assumption` that proves false during implementation is an `escalation`
213
+ trigger.
206
214
 
207
215
  ## Escalations
208
216
 
@@ -262,8 +270,8 @@ The revised `spec` controls subsequent work. Earlier `escalations`, `findings`,
262
270
 
263
271
  ## Verification boundary
264
272
 
265
- 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
266
- it created.
273
+ The `verifier` can make temporary changes to run its checks. Before submitting its `handoff`, it restores the exact original contents of affected files and removes only
274
+ files it created.
267
275
 
268
276
  Cleanup relies on the `verifier`. If cleanup cannot finish safely, the `verifier` stops and reports the remaining changes.
269
277
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@emiliosp/pi-maestro",
3
- "version": "0.16.0",
3
+ "version": "0.17.0",
4
4
  "description": "A spec-driven multiagent development workflow for Pi.",
5
5
  "keywords": [
6
6
  "orchestration",
@@ -0,0 +1,102 @@
1
+ /**
2
+ * Objective: Own the native session, cancellation, and cleanup for one child execution.
3
+ * Used: By the task executor while opening and closing a fresh SDK conversation.
4
+ */
5
+
6
+ import { existsSync } from 'node:fs';
7
+ import { realpath } from 'node:fs/promises';
8
+ import { join } from 'node:path';
9
+
10
+ import {
11
+ type AgentSession,
12
+ createAgentSession,
13
+ type CreateAgentSessionOptions,
14
+ SessionManager,
15
+ type ToolDefinition,
16
+ } from '@earendil-works/pi-coding-agent';
17
+
18
+ import { createChildServices } from '#src/delegation/createChildServices.ts';
19
+
20
+ export type SubSessionInput = {
21
+ roleGuidance: string;
22
+ cwd: string;
23
+ model: string;
24
+ thinkingLevel: NonNullable<CreateAgentSessionOptions['thinkingLevel']>;
25
+ additionalTools: ToolDefinition[];
26
+ signal?: AbortSignal;
27
+ };
28
+
29
+ export class SubSession {
30
+ private session?: AgentSession;
31
+ private sessionManager?: SessionManager;
32
+ private abortPromise?: Promise<void>;
33
+
34
+ private readonly input: SubSessionInput;
35
+
36
+ constructor(input: SubSessionInput) {
37
+ this.input = input;
38
+ }
39
+
40
+ public getSavedFile = (): string | undefined => {
41
+ const path = this.sessionManager?.getSessionFile();
42
+
43
+ return path && existsSync(path) ? path : undefined;
44
+ };
45
+
46
+ private abort = (): void => {
47
+ this.abortPromise = this.session?.abort();
48
+ // The cleanup path awaits this promise. Handle rejection immediately as well.
49
+ void this.abortPromise?.catch(() => {});
50
+ };
51
+
52
+ public open = async (): Promise<AgentSession> => {
53
+ const cwd = await realpath(this.input.cwd);
54
+ const services = await createChildServices({ cwd, roleGuidance: this.input.roleGuidance });
55
+
56
+ const model = (await services.modelRuntime.getAvailable()).find(
57
+ (entry) => `${entry.provider}/${entry.id}` === this.input.model,
58
+ );
59
+
60
+ if (!model) throw new Error(`Model is not available: "${this.input.model}".`);
61
+
62
+ this.sessionManager = SessionManager.create(
63
+ cwd,
64
+ join(SessionManager.create(cwd).getSessionDir(), 'subagents'),
65
+ );
66
+
67
+ const { session } = await createAgentSession({
68
+ ...services,
69
+ sessionManager: this.sessionManager,
70
+ model,
71
+ thinkingLevel: this.input.thinkingLevel,
72
+ customTools: this.input.additionalTools,
73
+ });
74
+
75
+ this.session = session;
76
+
77
+ this.input.signal?.addEventListener('abort', this.abort, { once: true });
78
+
79
+ await this.session.bindExtensions({ mode: 'print' });
80
+
81
+ return this.session;
82
+ };
83
+
84
+ public close = async (): Promise<void> => {
85
+ this.input.signal?.removeEventListener('abort', this.abort);
86
+
87
+ if (!this.session) return;
88
+
89
+ try {
90
+ await this.session.abort();
91
+ await this.abortPromise;
92
+ } finally {
93
+ try {
94
+ // AgentSession.dispose() does not emit shutdown. This is the native runtime's
95
+ // shutdown sequence, including extensions such as MCP that own connections.
96
+ await this.session.extensionRunner.emit({ type: 'session_shutdown', reason: 'quit' });
97
+ } finally {
98
+ this.session.dispose();
99
+ }
100
+ }
101
+ };
102
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Objective: Preserve task execution failures and their saved native session paths.
3
+ * Used: When standalone SDK execution fails or is interrupted.
4
+ */
5
+
6
+ type TaskExecutionErrorInput = {
7
+ cause: unknown;
8
+ sessionFile?: string;
9
+ };
10
+
11
+ export class TaskExecutionError extends Error {
12
+ readonly sessionFile?: string;
13
+
14
+ constructor({ cause, sessionFile }: TaskExecutionErrorInput) {
15
+ super(cause instanceof Error ? cause.message : String(cause), { cause });
16
+ this.name =
17
+ cause instanceof Error && cause.name === 'AbortError' ? 'AbortError' : 'TaskExecutionError';
18
+ this.sessionFile = sessionFile;
19
+ }
20
+ }
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Objective: Discover native Pi resources without loading the main Maestro extension.
3
+ * Used: During preparation of each standalone child execution.
4
+ */
5
+
6
+ import { realpathSync, readFileSync } from 'node:fs';
7
+ import { basename, dirname, join } from 'node:path';
8
+ import { fileURLToPath } from 'node:url';
9
+
10
+ import {
11
+ createAgentSessionServices,
12
+ createCodemodeExtension,
13
+ createMcpExtension,
14
+ createToolSearchExtension,
15
+ DefaultPackageManager,
16
+ getAgentDir,
17
+ SettingsManager,
18
+ } from '@earendil-works/pi-coding-agent';
19
+
20
+ const MAIN_EXTENSION = fileURLToPath(new URL('../../extensions/maestro.ts', import.meta.url));
21
+
22
+ type MaestroPackage = { name: '@emiliosp/pi-maestro' };
23
+
24
+ const isMaestroPackage = (value: unknown): value is MaestroPackage =>
25
+ typeof value === 'object' &&
26
+ value !== null &&
27
+ 'name' in value &&
28
+ value.name === '@emiliosp/pi-maestro';
29
+
30
+ const isMainExtension = (path: string): boolean => {
31
+ if (path.startsWith('builtin:')) return false;
32
+
33
+ const canonicalPath = realpathSync(path);
34
+
35
+ if (canonicalPath === realpathSync(MAIN_EXTENSION)) return true;
36
+
37
+ // Discovery can find an installed copy rather than the currently executing checkout.
38
+ if (
39
+ basename(canonicalPath) !== 'maestro.ts' ||
40
+ basename(dirname(canonicalPath)) !== 'extensions'
41
+ ) {
42
+ return false;
43
+ }
44
+
45
+ try {
46
+ return isMaestroPackage(
47
+ JSON.parse(readFileSync(join(dirname(canonicalPath), '../package.json'), 'utf8')),
48
+ );
49
+ } catch {
50
+ return false;
51
+ }
52
+ };
53
+
54
+ type CreateChildServicesInput = {
55
+ cwd: string;
56
+ roleGuidance: string;
57
+ };
58
+
59
+ export const createChildServices = async ({ cwd, roleGuidance }: CreateChildServicesInput) => {
60
+ const agentDir = getAgentDir();
61
+ const settingsManager = SettingsManager.create(cwd, agentDir);
62
+
63
+ const extensionFactories = [
64
+ { name: 'codemode', factory: createCodemodeExtension(), builtin: true, replaceable: true },
65
+ { name: 'tool-search', factory: createToolSearchExtension(), builtin: true, replaceable: true },
66
+ { name: 'mcp', factory: createMcpExtension(), builtin: true, replaceable: true },
67
+ ];
68
+
69
+ const packages = new DefaultPackageManager({
70
+ cwd,
71
+ agentDir,
72
+ settingsManager,
73
+ builtinExtensions: extensionFactories.map(({ name }) => name),
74
+ });
75
+
76
+ const resources = await packages.resolve(async () => 'error');
77
+
78
+ if (resources.installFailures?.length) {
79
+ throw new Error(resources.installFailures.map(({ message }) => message).join('\n'));
80
+ }
81
+
82
+ // extensionsOverride filters extensions after Pi has loaded and initialized them.
83
+ // It would exclude Maestro's event handlers, but its initialization code would still run.
84
+ // Use additionalExtensionPaths instead to exclude Maestro before loading it,
85
+ // so none of its code executes in the child session.
86
+ const additionalExtensionPaths = resources.extensions
87
+ .filter(({ enabled, path }) => enabled && !isMainExtension(path))
88
+ .map(({ path }) => path);
89
+
90
+ const services = await createAgentSessionServices({
91
+ cwd,
92
+ agentDir,
93
+ settingsManager,
94
+ resourceLoaderOptions: {
95
+ noExtensions: true,
96
+ additionalExtensionPaths,
97
+ extensionFactories,
98
+ appendSystemPromptOverride: (base) => [...base, roleGuidance],
99
+ },
100
+ });
101
+
102
+ const errors = [
103
+ ...services.resourceLoader.getExtensions().errors.map(({ error }) => error),
104
+ ...services.diagnostics.filter(({ type }) => type === 'error').map(({ message }) => message),
105
+ ];
106
+
107
+ if (errors.length) throw new Error(errors.join('\n'));
108
+
109
+ return services;
110
+ };
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Objective: Execute one independent task in a fresh, persisted native Pi conversation.
3
+ * Used: By internal callers that await child executions sequentially, outside workflow routing.
4
+ */
5
+
6
+ import { readTaskResult } from '#src/delegation/readTaskResult.ts';
7
+ import { SubSession, type SubSessionInput } from '#src/delegation/SubSession.ts';
8
+ import { TaskExecutionError } from '#src/delegation/TaskExecutionError.ts';
9
+
10
+ export type ExecuteTaskInput = SubSessionInput & {
11
+ prompt: string;
12
+ };
13
+
14
+ export type TaskExecutionResult = {
15
+ text: string;
16
+ sessionFile?: string;
17
+ };
18
+
19
+ export const executeTask = async (input: ExecuteTaskInput): Promise<TaskExecutionResult> => {
20
+ const subSession = new SubSession(input);
21
+
22
+ try {
23
+ try {
24
+ const session = await subSession.open();
25
+ await session.prompt(input.prompt, { expandPromptTemplates: false });
26
+
27
+ const text = readTaskResult(
28
+ session.messages.findLast((message) => message.role === 'assistant'),
29
+ );
30
+
31
+ return { text, sessionFile: subSession.getSavedFile() };
32
+ } finally {
33
+ await subSession.close();
34
+ }
35
+ } catch (cause) {
36
+ throw new TaskExecutionError({ cause, sessionFile: subSession.getSavedFile() });
37
+ }
38
+ };
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Objective: Interpret a completed assistant reply without accessing session state.
3
+ * Used: After the child becomes idle to return text or report its terminal failure.
4
+ */
5
+
6
+ import type { AssistantMessage } from '@earendil-works/pi-ai';
7
+
8
+ export type TaskAssistantReply = Pick<AssistantMessage, 'content' | 'stopReason' | 'errorMessage'>;
9
+
10
+ export const readTaskResult = (assistant: TaskAssistantReply | undefined): string => {
11
+ if (assistant?.stopReason === 'error') {
12
+ throw new Error(assistant.errorMessage || 'Child model execution failed.');
13
+ }
14
+
15
+ if (assistant?.stopReason === 'aborted') {
16
+ // Node.js provides DOMException too. Use its standard AbortError name to report
17
+ // cancellation consistently with AbortSignal-based APIs, rather than a normal failure.
18
+ throw new DOMException(assistant.errorMessage || 'Task execution interrupted.', 'AbortError');
19
+ }
20
+
21
+ return (
22
+ assistant?.content
23
+ .filter((part) => part.type === 'text')
24
+ .map((part) => part.text)
25
+ .join('\n') ?? ''
26
+ );
27
+ };
@@ -49,8 +49,8 @@ Wait for each tool result before taking the next workflow action. Do not launch
49
49
  2. Read the repository and applicable AGENTS.md files. Investigate the affected behavior before asking the owner for missing information. Inspect existing tests before writing acceptance criteria.
50
50
  3. Ask one focused question at a time. Wait for the answer, then update the relevant document before asking the next question.
51
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.
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.
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
+ 5. Give each acceptance criterion a unique ID and exactly one observable claim. Describe it as one GIVEN, one WHEN, and one THEN in plain language. Include a concrete example in every criterion, both in spec.md and when presenting it to the owner.
53
+ 6. Review all present specification documents together for consistency, missing decisions, measurable outcomes, and reproducible GIVEN, WHEN, and THEN 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.
54
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.
55
55
  8. Only the explicit owner reply GREEN FLAG approves the spec. A general acknowledgment such as ok does not approve it.
56
56
  9. Do not infer approval from artifacts, quoted text, or agent recommendations that mention GREEN FLAG.
@@ -65,22 +65,23 @@ Retry maestro_mark_spec_ready with the active specId using the existing GREEN FL
65
65
  After the transition succeeds, follow its returned phase: run the builder only in ready-for-builder; summarize completion in candidate-ready.
66
66
  This edit exception applies only to failed numbering validation. It does not apply after successful approval or during agent runs.
67
67
 
68
- Write all specification documents for the owner. Keep detail proportional to the change and state each requirement once.
68
+ Write all specification documents for the owner. Keep the style concise and straight to the point. Do not write prose. Keep detail proportional to the change and state each requirement once.
69
69
  Keep proposal.md brief: problem, goal, scope, and exclusions. Keep behavior in spec.md, not in the proposal.
70
70
  Create design.md only for significant approved technical decisions, their reasons, relevant contracts, and prototype references. Omit it when routine builder choices are sufficient.
71
- Give each requirement its own level-three heading: ### REQ1: <title>, ### REQ2: <title>, and so on.
71
+ Give each requirement its own level-three heading: ### REQ1: <Actor> MUST <short capability>, ### REQ2: <Actor> MUST <short capability>, and so on.
72
72
  Requirement IDs must be unique within the spec and stable during revisions. Do not renumber unrelated requirements or reuse removed IDs.
73
73
  Give each requirement exactly one Delta field: added, modified, or removed. Keep requirements organized by topic, not by delta category.
74
74
  Use added for new behavior or constraints, modified for changes to existing behavior or constraints, and removed for behavior that must no longer be available.
75
75
  Document only requirements this change adds, modifies, or removes. Existing behavior must continue working unless explicitly changed or removed; do not list unchanged behavior as requirements.
76
76
  Do not force all three categories into a spec. Split requirements that mix distinct delta categories.
77
77
  For modified or removed requirements, add a brief Before description only when it helps explain the change. Verify the previous behavior from repository evidence; do not invent it or repeat the whole old requirement.
78
- State the complete required outcome in the requirement body, not only a difference. For removed behavior, specify the required absence and any agreed replacement or error behavior so it remains verifiable.
78
+ State the complete required outcome in the requirement heading, not only a difference. For removed behavior, specify the required absence and any agreed replacement or error behavior so it remains verifiable.
79
79
  During spec revisions, keep the comparison anchored to the same pre-change behavior, not the previous draft or the builder's partial implementation.
80
80
  Delta classifies requirement changes, not acceptance criteria.
81
+ State the capability in the requirement heading with a named actor followed by MUST. Use only MUST among requirement keywords and keep one capability for each requirement. Put only supporting detail in the description after Delta, without repeating the MUST statement.
81
82
  Place each requirement-associated acceptance criterion immediately below its primary requirement using a level-four heading, such as #### AC1: <title>.
82
83
  A relevant regression criterion without an associated changed requirement may stand alone under an optional ## Regression checks section with a level-three ### AC<number>: <title> heading.
83
- Give standalone regression criteria the same probe, expected result, and concrete example fields. Do not invent a REQ or Delta field for them, force a requirement association, or enumerate all existing behavior. Omit the section when unnecessary.
84
+ Give standalone regression criteria the same GIVEN, WHEN, THEN, and concrete example fields. Do not invent a REQ or Delta field for them, force a requirement association, or enumerate all existing behavior. Omit the section when unnecessary.
84
85
  Define each AC only once. Other requirements may link to it. Keep AC numbering continuous from AC1 across both nested and standalone criteria, not restarted per requirement or section.
85
86
  Under each requirement, add Verified by with Markdown links to the acceptance criteria that verify it, using their actual heading anchors.
86
87
  For coverage provided by an existing test, link its file relative to spec.md and give the exact test scenario name instead of adding a duplicate criterion.
@@ -88,16 +89,17 @@ A requirement may link to multiple criteria, existing tests, or both; the same c
88
89
  Keep this mapping only under requirements, not repeated inside criteria. During review, follow every link and check that the combined scenarios verify the whole requirement.
89
90
  Resolve missing, partial, or uncertain coverage before requesting approval. Keep links current when criterion headings or test references change.
90
91
  Use the template topics as guidance. Omit empty subsections instead of filling them with Not applicable.
92
+ Record short assumptions in a ## Assumptions section as a bullet list. Include defaults chosen when the request did not specify a detail and scope boundaries taken as given. Omit the section when there are none.
91
93
  Keep observable behavior, constraints, edge cases, and recovery requirements in spec.md. Keep approved technical decisions in design.md and scope in proposal.md. Leave routine implementation choices to the builder.
92
- Keep probes as starting conditions and actions or observations, with measurable expected results.
93
- Cover relevant valid actions, invalid actions, and regressions directly through the probe and expected result.
94
- Omit a criterion only when an existing test covers the same starting conditions, action, and expected result.
94
+ Keep GIVEN as starting conditions, WHEN as the action or observation, and THEN as the measurable outcome.
95
+ Cover relevant valid actions, invalid actions, and regressions directly through GIVEN, WHEN, and THEN.
96
+ Omit a criterion only when an existing test covers the same starting conditions, action, and outcome.
95
97
  Similar tests do not count. Keep the criterion if coverage is partial or uncertain.
96
98
  For example, a test that rejects an empty title does not cover a title containing only spaces.
97
99
  For requirement-associated criteria, keep required behavior documented even when the criterion is omitted, and link the covering test from the requirement's Verified by field. Omit a standalone regression criterion when an existing test already covers its exact scenario without creating a requirement for it. These rules also apply during spec revisions.
98
100
  Each example must show specific starting conditions, an input or action, and the exact observable result expected from that scenario.
99
101
  Use concrete values or states, not a restatement of the claim. Keep examples within the criterion's scope and approved behavior.
100
- Every probe remains mandatory for builder and verifier.
102
+ Every GIVEN, WHEN, and THEN scenario remains mandatory for builder and verifier.
101
103
  The builder chooses test code, fixtures, mocks, and commands.
102
104
  Do not copy agent procedures, repository rules, investigation logs, or workflow history into the spec.
103
105
 
@@ -169,7 +171,7 @@ For each finding or escalation, give the owner enough detail to decide without o
169
171
 
170
172
  1. Identify findings with both handoff and finding IDs, such as V1/F1. Finding IDs are local to each verifier handoff. Identify escalation questions with both handoff and local IDs, such as B1/E1 or B2/E1. Escalation IDs restart at E1 in each builder handoff. Explain the issue or open question and its relation to the approved contract.
171
173
  2. For code-related issues, show a short code excerpt with its file path and line numbers. Explain how that code causes or constrains the behavior. A file reference alone is not enough.
172
- 3. Give a concrete example with starting conditions, input or action, current behavior, and practical impact. Compare with the contract's expected result when defined. Otherwise identify the behavior that needs an owner decision.
174
+ 3. Give a concrete example with starting conditions, input or action, current behavior, and practical impact. Compare with the contract's THEN outcome when defined. Otherwise identify the behavior that needs an owner decision.
173
175
  4. Explain each available choice, its required changes, scope, consequences, and next workflow step. For findings, cover fix-code, rejection, and spec revision when relevant. Explain what remains unchanged or unresolved if no code changes.
174
176
 
175
177
  Distinguish observed results from illustrative examples, assumptions, and unknowns. Never invent evidence, code, or expected behavior.
package/templates/spec.md CHANGED
@@ -2,39 +2,51 @@
2
2
 
3
3
  <!--
4
4
  Define required behavior, not motivation or implementation. See proposal.md for scope and design.md, when present, for approved technical decisions.
5
- Write for the owner. State each requirement once and keep its acceptance criteria immediately below it.
5
+ Write for the owner. Keep the style concise and straight to the point. Do not write prose.
6
+ State each requirement once and keep its acceptance criteria immediately below it.
6
7
  Use the topics below as guidance. Omit empty subsections and these instructions.
7
8
  Leave test code, fixtures, mocks, and commands to the builder. Keep execution evidence in handoffs.
8
9
  -->
9
10
 
10
11
  ## Requirements
11
12
 
12
- <Give each requirement its own ### REQ<number>: <title> heading and a unique, stable ID. Document only behavior or constraints this change adds, modifies, or removes, with relevant measurable limits, edge cases, and error handling. Existing behavior must continue working unless explicitly changed or removed; do not list unchanged behavior as requirements. Do not copy repository or agent instructions.>
13
+ <Give each requirement its own ### REQ<number>: <Actor> MUST <short capability> heading and a unique, stable ID. Document only behavior or constraints this change adds, modifies, or removes, with relevant measurable limits, edge cases, and error handling. Existing behavior must continue working unless explicitly changed or removed; do not list unchanged behavior as requirements. Do not copy repository or agent instructions.>
13
14
 
14
15
  <Give each requirement exactly one Delta value: added, modified, or removed. Keep requirements organized by topic, not by delta category. For modified or removed requirements, add a brief Before description only when useful. Verify the previous behavior from repository evidence; do not invent it or repeat the whole old requirement. State the complete required outcome, including the required absence and any agreed replacement or error behavior for removals. Keep the same pre-change baseline during revisions.>
15
16
 
16
- <Each requirement must have Verified by with Markdown links to its acceptance criteria, using their actual heading anchors. When an existing test covers the exact starting conditions, action, and expected result, link its file relative to spec.md and give the exact scenario name instead of creating a duplicate criterion. Keep criteria for partial or uncertain coverage. A requirement can reference both criteria and tests; check their combined coverage.>
17
+ <Each requirement must have Verified by with Markdown links to its acceptance criteria, using their actual heading anchors. When an existing test covers the exact starting conditions, action, and outcome, link its file relative to spec.md and give the exact scenario name instead of creating a duplicate criterion. Keep criteria for partial or uncertain coverage. A requirement can reference both criteria and tests; check their combined coverage.>
17
18
 
18
- <Write each requirement-associated AC once, immediately below its primary requirement, with a #### AC<number>: <title> heading. Other requirements can link to it without duplication. A relevant regression AC without an associated changed requirement can instead use a ### AC<number>: <title> heading under an optional ## Regression checks section, with the same probe, expected result, and example fields. Do not invent a REQ or Delta field for it. Include only regressions relevant to this change, not an inventory of existing behavior, and omit the section when unnecessary.>
19
+ <Write each requirement-associated AC once, immediately below its primary requirement, with a #### AC<number>: <title> heading. Other requirements can link to it without duplication. A relevant regression AC without an associated changed requirement can instead use a ### AC<number>: <title> heading under an optional ## Regression checks section, with the same GIVEN, WHEN, THEN, and Example fields. Do not invent a REQ or Delta field for it. Include only regressions relevant to this change, not an inventory of existing behavior, and omit the section when unnecessary.>
19
20
 
20
21
  <Number ACs continuously from AC1 across the whole document, including nested and standalone regression criteria. During review, remove criteria already covered exactly by existing tests and update numbering and affected links. Keep required behavior documented when a requirement-associated criterion is omitted; omitting a standalone regression criterion does not require creating a requirement.>
21
22
 
22
- ### REQ1: <short required behavior>
23
+ ### REQ1: <Actor> MUST <short capability>
23
24
 
24
25
  Delta: <added | modified | removed>
25
26
 
26
- <Describe the requirement once, including relevant boundary conditions and required failure or recovery behavior.>
27
+ <Optional supporting details, such as boundary conditions and required failure or recovery behavior. Keep only the MUST statement in the heading and do not repeat it here.>
27
28
 
28
29
  Verified by: [AC1](#ac1-short-observable-claim)
29
30
 
30
31
  #### AC1: <short observable claim>
31
32
 
32
- 1. Probe: <starting conditions and action or observation, without prescribing test implementation>
33
- 2. Expected result: <observable and measurable outcome>
34
- 3. Example: <specific starting conditions, concrete input or action, and exact expected result, not a restatement of the claim>
33
+ - GIVEN <starting conditions>
34
+ - WHEN <action or observation, without prescribing test implementation>
35
+ - THEN <observable and measurable outcome>
36
+ - Example: <specific starting conditions, concrete input or action, and exact outcome, not a restatement of the claim>
35
37
 
36
38
  <!--
37
- Each AC has one observable claim, a probe, an expected result, and a concrete example.
39
+ Each AC has exactly one GIVEN, one WHEN, and one THEN, plus a concrete Example.
40
+ THEN states the observable and measurable outcome that the WHEN must produce.
38
41
  Describe relevant valid actions, invalid actions, and regressions directly through those fields, without a separate classification label.
39
- The builder and verifier each run every probe independently. The builder chooses executable checks; the verifier checks their coverage independently.
42
+ The builder and verifier each run every scenario independently. The builder chooses executable checks; the verifier checks their coverage independently.
40
43
  -->
44
+
45
+ ## Assumptions
46
+
47
+ <!--
48
+ Record short defaults taken when the request did not specify a detail, or scope boundaries taken as given. Use a bullet list, not paragraphs. Omit the section when there are none.
49
+ -->
50
+
51
+ - <default chosen when the request did not specify a detail>
52
+ - <scope boundary taken as given>