@emiliosp/pi-maestro 0.9.4 → 0.9.5

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
@@ -2,6 +2,12 @@
2
2
 
3
3
  This file summarizes meaningful changes to the codebase, including behavior, data formats, architecture, and development tools. Git tags identify version boundaries; GitHub Releases are not required. Version-only changes and routine maintenance are omitted.
4
4
 
5
+ ## 0.9.4
6
+
7
+ 1. Added numbering validation to `spec` approval. Matched `acceptance criterion` headings must start at `AC1` and continue without gaps. See [PR #36](https://github.com/emilioSp/pi-maestro/pull/36).
8
+ 2. Invalid numbering rejects approval before saving the workflow and leaves all saved files unchanged. No matching headings still permits approval.
9
+ 3. Added `Maestro` guidance to correct only numbering and affected references, then retry with the existing `GREEN FLAG`. No additional `owner` approval is required before starting the `builder`.
10
+
5
11
  ## 0.9.3
6
12
 
7
13
  1. Added a parent `pi-subagents` availability check during activation. A matching successful version 1 `ping` reply is required within 2000 ms. See [PR #35](https://github.com/emilioSp/pi-maestro/pull/35).
package/ROADMAP.md CHANGED
@@ -86,23 +86,39 @@ A later integration test requested by the `owner` directly checks the environmen
86
86
 
87
87
  [Specification](.specs/20261013-194407-check-pi-subagents-availability-with-ping-at-activation/spec.md), [verifier report](.specs/20261013-194407-check-pi-subagents-availability-with-ping-at-activation/handoffs/verifier/V1.json), and [merged PR #35](https://github.com/emilioSp/pi-maestro/pull/35).
88
88
 
89
+ ### R-05: Keep acceptance criterion numbering continuous
90
+
91
+ Implemented in `0.9.4`. `Spec` approval rejects numbered `acceptance criterion` headings that do not start at `AC1` and continue without gaps. Rejection leaves saved files unchanged.
92
+
93
+ `Maestro` corrects numbering and affected references without changing criterion order or requirements, then retries with the existing `GREEN FLAG`. No additional `owner` approval is required.
94
+
95
+ All 3 `acceptance criteria` passed with no `verifier` `findings`. The saved workflow reached `candidate-ready`.
96
+
97
+ #### Evidence
98
+
99
+ [Specification](.specs/20261013-202811-check-acceptance-criterion-numbering-before-builder-execution/spec.md), [verifier report](.specs/20261013-202811-check-acceptance-criterion-numbering-before-builder-execution/handoffs/verifier/V1.json), and [merged PR #36](https://github.com/emilioSp/pi-maestro/pull/36).
100
+
89
101
  ## Now
90
102
 
91
- ### R-05: Keep acceptance criterion numbering continuous
103
+ ### R-10: Match handoff criteria to the approved spec
92
104
 
93
105
  #### Objective
94
106
 
95
- When criteria are removed during `spec` preparation or revision, renumber the remaining criteria without gaps. Numbering starts at `AC1` and continues through the final criterion.
107
+ Prevent `builder` and `verifier` reports from omitting or adding `acceptance criteria`. Each report must contain exactly the criterion IDs in the approved `spec`, with no duplicates in either place. Existing duplicate checks in reports do not establish this match.
96
108
 
97
- #### Current state
109
+ The `specification` must define the criterion heading format used to extract IDs. For example, a heading can use `### AC1: ...`.
98
110
 
99
- Implemented approval-time numbering validation and `Maestro` guidance for numbering-only recovery using the existing GREEN FLAG. Rejected numbering leaves saved files unchanged. Independent verification is pending.
111
+ #### Completed when
100
112
 
101
- [Specification](.specs/20261013-202811-check-acceptance-criterion-numbering-before-builder-execution/spec.md).
113
+ Both `handoff` submissions reject missing, extra, or duplicate criterion IDs before saving a report or changing phase.
102
114
 
103
- #### Completed when
115
+ #### Implementation status
104
116
 
105
- The `spec` and its current references use consistent numbering.
117
+ The [approved specification](.specs/20261013-211629-match-handoff-criteria-to-the-approved-spec/spec.md) limits this change to missing IDs. The implementation rejects missing `spec` IDs before saving either `handoff` or changing phase. Extra report IDs remain allowed. No new check rejects duplicate IDs in the `spec`.
118
+
119
+ Both `acceptance criteria` passed independent verification with no `findings`. The saved workflow reached `candidate-ready`. The broader exact-match objective remains outside this approved scope.
120
+
121
+ Later changes requested by the `owner` extract the shared presence check into one utility and cover extraction with unit tests. One missing-ID integration test remains per role to check rejection before saving. These changes are outside the completed independent verification.
106
122
 
107
123
  ## Next
108
124
 
@@ -151,39 +167,3 @@ Explore how `Maestro` can reconcile saved `artifacts` and workflow state. The re
151
167
  #### Completed when
152
168
 
153
169
  Not yet defined. The `owner` must define the intended outcome, recovery boundaries, and completion condition before this item can move forward.
154
-
155
- ### R-10: Match handoff criteria to the approved spec
156
-
157
- #### Objective
158
-
159
- Prevent `builder` and `verifier` reports from omitting or adding `acceptance criteria`. Each report must contain exactly the criterion IDs in the approved `spec`, with no duplicates in either place. Existing duplicate checks in reports do not establish this match.
160
-
161
- The `specification` must define the criterion heading format used to extract IDs. For example, a heading can use `### AC1: ...`.
162
-
163
- #### Completed when
164
-
165
- Both `handoff` submissions reject missing, extra, or duplicate criterion IDs before saving a report or changing phase.
166
-
167
- ### R-11: Reduce temporary verifier changes
168
-
169
- #### Objective
170
-
171
- Reduce the risk that verification changes the `candidate`. Existing instructions already require exact restoration, cleanup, and reporting of unresolved restoration problems. Refine the remaining guidance rather than duplicate those rules.
172
-
173
- Prefer checks that leave existing files unchanged and use separate temporary files when possible. Change an existing file only when a criterion requires it. Retain its exact contents and restore it immediately after each `probe`, including failed `probes`. Prefer check-only commands over commands that apply automatic fixes.
174
-
175
- `Maestro` currently has no file-hash restoration check. Adding one requires a separate scope decision.
176
-
177
- #### Completed when
178
-
179
- `Verifier` instructions cover these limits and require restoration and temporary-file cleanup before `handoff`. If restoration fails, the `verifier` must stop and report affected paths and remaining changes.
180
-
181
- ### R-13: Show when Maestro is working
182
-
183
- #### Objective
184
-
185
- Show an activity indicator in Pi's status bar while progress does not require an `owner` decision. A spinner is one option, not an agreed implementation.
186
-
187
- #### Completed when
188
-
189
- The status clearly distinguishes work in progress from a request for `owner` action.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@emiliosp/pi-maestro",
3
- "version": "0.9.4",
3
+ "version": "0.9.5",
4
4
  "description": "A spec-driven multiagent development workflow for Pi.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -3,7 +3,7 @@
3
3
  * Used: When the builder reports done or escalation through the child tool.
4
4
  */
5
5
 
6
- import { mkdir } from 'node:fs/promises';
6
+ import { mkdir, readFile } from 'node:fs/promises';
7
7
  import { Value } from 'typebox/value';
8
8
  import { assertBuilderHandoff } from '#artifacts/builder-handoff/assertBuilderHandoff.ts';
9
9
  import {
@@ -19,6 +19,7 @@ import { readWorkflowState } from '#workflow/state/readWorkflowState.ts';
19
19
  import { WORKFLOW_PHASES, type WorkflowState } from '#workflow/state/schema.ts';
20
20
  import { writeWorkflowState } from '#workflow/state/writeWorkflowState.ts';
21
21
  import { transitionWorkflow } from '#workflow/transitions.ts';
22
+ import { assertSpecAcceptanceCriteria } from '#workflow/utils/assertSpecAcceptanceCriteria.ts';
22
23
 
23
24
  export type CompletedBuilderPass = {
24
25
  handoff: BuilderHandoff;
@@ -76,6 +77,11 @@ export const completeBuilderPass = async ({
76
77
  assertBuilderHandoff(handoffInput);
77
78
  const { handoff } = handoffInput;
78
79
 
80
+ assertSpecAcceptanceCriteria({
81
+ markdown: await readFile(paths.getSpecFilePath(specId), 'utf8'),
82
+ criterionIds: new Set(handoff.acceptanceCriteria.map(({ id }) => id)),
83
+ });
84
+
79
85
  const nextState = transitionWorkflow({
80
86
  state: currentState,
81
87
  event: getWorkflowEventByBuilderHandoff(handoff),
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Objective: Require every spec criterion ID in a handoff.
3
+ * Used: Before builder and verifier submissions save their reports.
4
+ */
5
+
6
+ type AssertSpecAcceptanceCriteriaInput = {
7
+ markdown: string;
8
+ criterionIds: Set<string>;
9
+ };
10
+
11
+ export function assertSpecAcceptanceCriteria({
12
+ markdown,
13
+ criterionIds,
14
+ }: AssertSpecAcceptanceCriteriaInput): void {
15
+ const missingIds = [...markdown.matchAll(/^### AC(\d+):/gm)]
16
+ .map((match) => `AC${match[1]}`)
17
+ .filter((id) => !criterionIds.has(id));
18
+
19
+ if (missingIds.length > 0) {
20
+ throw new Error(
21
+ `Handoff is missing acceptance criterion IDs from spec.md: ${missingIds.join(', ')}.`,
22
+ );
23
+ }
24
+ }
@@ -3,7 +3,7 @@
3
3
  * Used: When the verifier submits its terminal handoff.
4
4
  */
5
5
 
6
- import { mkdir } from 'node:fs/promises';
6
+ import { mkdir, readFile } from 'node:fs/promises';
7
7
  import { assertVerifierHandoff } from '#artifacts/verifier-handoff/assertVerifierHandoff.ts';
8
8
  import type { VerifierHandoff } from '#artifacts/verifier-handoff/schema.ts';
9
9
  import { writeVerifierHandoff } from '#artifacts/verifier-handoff/writeVerifierHandoff.ts';
@@ -12,6 +12,7 @@ import { readWorkflowState } from '#workflow/state/readWorkflowState.ts';
12
12
  import { WORKFLOW_PHASES, type WorkflowState } from '#workflow/state/schema.ts';
13
13
  import { writeWorkflowState } from '#workflow/state/writeWorkflowState.ts';
14
14
  import { transitionWorkflow } from '#workflow/transitions.ts';
15
+ import { assertSpecAcceptanceCriteria } from '#workflow/utils/assertSpecAcceptanceCriteria.ts';
15
16
  import { getWorkflowEventByVerifierHandoff } from '#workflow/verifier/utils/getWorkflowEventByVerifierHandoff.ts';
16
17
 
17
18
  export type CompletedVerifierPass = {
@@ -56,6 +57,11 @@ export const completeVerifierPass = async ({
56
57
  assertVerifierHandoff(handoffInput);
57
58
  const { handoff } = handoffInput;
58
59
 
60
+ assertSpecAcceptanceCriteria({
61
+ markdown: await readFile(paths.getSpecFilePath(specId), 'utf8'),
62
+ criterionIds: new Set(handoff.acceptanceCriteria.map(({ id }) => id)),
63
+ });
64
+
59
65
  const nextState = transitionWorkflow({
60
66
  state: currentState,
61
67
  event: getWorkflowEventByVerifierHandoff(handoff),