@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 +11 -0
- package/README.md +2 -2
- package/ROADMAP.md +105 -58
- package/agents/builder.md +8 -8
- package/agents/verifier.md +12 -12
- package/docs/glossary.md +5 -3
- package/docs/workflow.md +40 -32
- package/package.json +1 -1
- package/src/delegation/SubSession.ts +102 -0
- package/src/delegation/TaskExecutionError.ts +20 -0
- package/src/delegation/createChildServices.ts +110 -0
- package/src/delegation/executeTask.ts +38 -0
- package/src/delegation/readTaskResult.ts +27 -0
- package/src/maestro/instructions/getMaestroInstructions.ts +13 -11
- package/templates/spec.md +23 -11
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 `
|
|
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
|
|
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
|
|
14
|
-
|
|
|
15
|
-
| MAESTRO-6
|
|
16
|
-
| MAESTRO-7
|
|
17
|
-
| MAESTRO-8
|
|
18
|
-
| MAESTRO-9
|
|
19
|
-
| MAESTRO-10
|
|
20
|
-
| MAESTRO-11
|
|
21
|
-
| MAESTRO-12
|
|
22
|
-
| MAESTRO-13
|
|
23
|
-
| MAESTRO-14
|
|
24
|
-
| MAESTRO-15
|
|
25
|
-
| MAESTRO-16
|
|
26
|
-
| MAESTRO-17
|
|
27
|
-
| MAESTRO-18
|
|
28
|
-
| MAESTRO-19
|
|
29
|
-
| MAESTRO-20
|
|
30
|
-
| MAESTRO-21
|
|
31
|
-
| MAESTRO-22
|
|
32
|
-
| MAESTRO-23
|
|
33
|
-
| MAESTRO-24
|
|
34
|
-
| MAESTRO-25
|
|
35
|
-
| MAESTRO-26
|
|
36
|
-
| MAESTRO-27
|
|
37
|
-
| MAESTRO-FREE-1
|
|
38
|
-
| MAESTRO-FREE-2
|
|
39
|
-
| MAESTRO-FREE-3 | [
|
|
40
|
-
| MAESTRO-FREE-
|
|
41
|
-
| MAESTRO-FREE-
|
|
42
|
-
| MAESTRO-FREE-
|
|
43
|
-
| MAESTRO-FREE-
|
|
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-
|
|
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
|
-
|
|
105
|
-
|
|
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.
|
|
110
|
-
|
|
111
|
-
|
|
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
|
-
|
|
118
|
-
[ADR-010](ADR.md#adr-010-use-the-pi-sdk-for-sequential-agent-delegation).
|
|
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-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
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.
|
|
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
|
|
140
|
-
|
|
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
|
-
|
|
148
|
-
[ADR-010](ADR.md#adr-010-use-the-pi-sdk-for-sequential-agent-delegation).
|
|
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
|
|
156
|
-
4. Workflows with verification enabled or disabled retain their existing routes
|
|
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
|
-
|
|
163
|
-
[ADR-010](ADR.md#adr-010-use-the-pi-sdk-for-sequential-agent-delegation).
|
|
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
|
|
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
|
|
178
|
-
|
|
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.
|
|
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
|
|
55
|
-
examples. Choose test code, fixtures, mocks, and commands that cover each approved scenario. These execution details are your responsibility, not missing owner
|
|
56
|
-
Follow any explicit execution constraints in the approved spec. Run each
|
|
57
|
-
|
|
58
|
-
the contract and repeat the proof for affected criteria. If the contract needs clarification or revision, escalate instead of inventing a replacement
|
|
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
|
-
|
|
64
|
-
|
|
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
|
|
package/agents/verifier.md
CHANGED
|
@@ -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,
|
|
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
|
|
47
|
-
|
|
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.
|
|
49
|
-
files only as needed for the specified
|
|
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
|
-
|
|
58
|
-
|
|
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
|
|
63
|
-
`passed` at least one related finding. Report required repository check failures as findings, even when every acceptance criterion passes. Do not copy an
|
|
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
|
|
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
|
-
| `
|
|
15
|
-
| `
|
|
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
|
|
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 `
|
|
22
|
-
| `Verifier` | Independently runs every `
|
|
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
|
|
111
|
-
| ------------- |
|
|
112
|
-
| `proposal.md` | Problem, goal, scope, and exclusions.
|
|
113
|
-
| `spec.md` | Required behavior, constraints, deltas,
|
|
114
|
-
| `design.md` | Approved technical decisions, brief reasons, relevant contracts, risks, and prototype references.
|
|
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:
|
|
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
|
-
|
|
166
|
-
|
|
167
|
-
|
|
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
|
|
172
|
-
|
|
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
|
-
|
|
194
|
-
|
|
195
|
-
|
|
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
|
|
202
|
-
|
|
|
203
|
-
| `
|
|
204
|
-
| `
|
|
205
|
-
|
|
|
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
|
|
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
|
@@ -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
|
|
53
|
-
6. Review all present specification documents together for consistency, missing decisions, measurable outcomes, and reproducible
|
|
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: <
|
|
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
|
|
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
|
|
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
|
|
93
|
-
Cover relevant valid actions, invalid actions, and regressions directly through
|
|
94
|
-
Omit a criterion only when an existing test covers the same starting conditions, action, and
|
|
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
|
|
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
|
|
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.
|
|
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>: <
|
|
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
|
|
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
|
|
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
|
|
23
|
+
### REQ1: <Actor> MUST <short capability>
|
|
23
24
|
|
|
24
25
|
Delta: <added | modified | removed>
|
|
25
26
|
|
|
26
|
-
<
|
|
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
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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
|
|
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
|
|
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>
|