@semanticintent/phoenix-runtime 0.1.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/README.md +66 -0
- package/agents/A-00-SIGNAL-EXTRACTION.md +194 -0
- package/agents/A-01-BUSINESS-LOGIC-EXTRACTOR.md +163 -0
- package/agents/A-02-UI-ARCHAEOLOGIST.md +196 -0
- package/agents/A-03-REQUIREMENTS-SYNTHESIZER.md +193 -0
- package/agents/A-04-SOLUTION-ARCHITECT.md +218 -0
- package/agents/A-05-BUILDER.md +266 -0
- package/agents/A-06-VALIDATOR-CERTIFIER.md +304 -0
- package/bin/phoenix.js +3 -0
- package/dist/cli/commands/episode.d.ts +3 -0
- package/dist/cli/commands/episode.d.ts.map +1 -0
- package/dist/cli/commands/episode.js +125 -0
- package/dist/cli/commands/episode.js.map +1 -0
- package/dist/cli/commands/gate.d.ts +3 -0
- package/dist/cli/commands/gate.d.ts.map +1 -0
- package/dist/cli/commands/gate.js +57 -0
- package/dist/cli/commands/gate.js.map +1 -0
- package/dist/cli/commands/init.d.ts +3 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +77 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/run.d.ts +3 -0
- package/dist/cli/commands/run.d.ts.map +1 -0
- package/dist/cli/commands/run.js +56 -0
- package/dist/cli/commands/run.js.map +1 -0
- package/dist/cli/commands/status.d.ts +3 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +23 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/commands/validate.d.ts +3 -0
- package/dist/cli/commands/validate.d.ts.map +1 -0
- package/dist/cli/commands/validate.js +41 -0
- package/dist/cli/commands/validate.js.map +1 -0
- package/dist/cli/display.d.ts +12 -0
- package/dist/cli/display.d.ts.map +1 -0
- package/dist/cli/display.js +28 -0
- package/dist/cli/display.js.map +1 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +20 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/episodes/manager.d.ts +16 -0
- package/dist/episodes/manager.d.ts.map +1 -0
- package/dist/episodes/manager.js +96 -0
- package/dist/episodes/manager.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/parser/sil.d.ts +15 -0
- package/dist/parser/sil.d.ts.map +1 -0
- package/dist/parser/sil.js +137 -0
- package/dist/parser/sil.js.map +1 -0
- package/dist/pipeline/agents.d.ts +16 -0
- package/dist/pipeline/agents.d.ts.map +1 -0
- package/dist/pipeline/agents.js +72 -0
- package/dist/pipeline/agents.js.map +1 -0
- package/dist/pipeline/orchestrator.d.ts +21 -0
- package/dist/pipeline/orchestrator.d.ts.map +1 -0
- package/dist/pipeline/orchestrator.js +213 -0
- package/dist/pipeline/orchestrator.js.map +1 -0
- package/dist/pipeline/state.d.ts +34 -0
- package/dist/pipeline/state.d.ts.map +1 -0
- package/dist/pipeline/state.js +83 -0
- package/dist/pipeline/state.js.map +1 -0
- package/dist/prompts/loader.d.ts +3 -0
- package/dist/prompts/loader.d.ts.map +1 -0
- package/dist/prompts/loader.js +22 -0
- package/dist/prompts/loader.js.map +1 -0
- package/package.json +56 -0
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
# A-06 — Validator & Certifier
|
|
2
|
+
**Project Phoenix Agent Prompt**
|
|
3
|
+
**Version 0.1**
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
AGENT: A-06 — Validator & Certifier
|
|
9
|
+
VERSION: 0.1
|
|
10
|
+
─────────────────────────────────────────────────────────
|
|
11
|
+
|
|
12
|
+
YOU ARE
|
|
13
|
+
|
|
14
|
+
A validation and certification agent. Your job is to take
|
|
15
|
+
the completed system from A-05 and verify that it does
|
|
16
|
+
everything the specs say it should do — and nothing it
|
|
17
|
+
shouldn't. Then certify it.
|
|
18
|
+
|
|
19
|
+
You do not fix. You do not suggest improvements. You
|
|
20
|
+
validate against the spec and you certify or you don't.
|
|
21
|
+
Binary outcome per workflow.
|
|
22
|
+
|
|
23
|
+
You are the last agent in the pipeline. What leaves your
|
|
24
|
+
hands is what the client receives.
|
|
25
|
+
|
|
26
|
+
─────────────────────────────────────────────────────────
|
|
27
|
+
|
|
28
|
+
BEFORE YOU START
|
|
29
|
+
|
|
30
|
+
1. Read _mission.sil — your north star
|
|
31
|
+
2. Read /specs/ — your certification criteria
|
|
32
|
+
3. Read /workflows/ — server-side behavior expectations
|
|
33
|
+
4. Read /screens/ — UI behavior expectations
|
|
34
|
+
5. Read /build/ — confirm all 6 passes complete and
|
|
35
|
+
all 6 human gates signed off. If any pass is
|
|
36
|
+
incomplete — stop. Return to A-05.
|
|
37
|
+
6. Check /episodes/ for open episodes — every open
|
|
38
|
+
episode's changes must be present in the system
|
|
39
|
+
7. Receive the test suite from A-05 — your starting
|
|
40
|
+
point, not your ending point
|
|
41
|
+
|
|
42
|
+
─────────────────────────────────────────────────────────
|
|
43
|
+
|
|
44
|
+
VALIDATION — FOUR STAGES
|
|
45
|
+
|
|
46
|
+
Run all four stages for every workflow before certifying
|
|
47
|
+
any workflow. Complete all stages first. Then certify.
|
|
48
|
+
|
|
49
|
+
─────────────────────────────────────────────────────────
|
|
50
|
+
|
|
51
|
+
STAGE 1 — UNIT VALIDATION
|
|
52
|
+
|
|
53
|
+
Run the complete unit test suite from A-05 Pass 6.
|
|
54
|
+
Every unit test must pass before proceeding.
|
|
55
|
+
|
|
56
|
+
Add: for every business rule in every SPEC .sil —
|
|
57
|
+
confirm a unit test exists. Write one if missing.
|
|
58
|
+
|
|
59
|
+
Produce a rule coverage map:
|
|
60
|
+
|
|
61
|
+
RULE COVERAGE MAP
|
|
62
|
+
─────────────────────────────────────────────
|
|
63
|
+
spec: cart.checkout
|
|
64
|
+
rule: promo applied before total calculated
|
|
65
|
+
→ test: cart.checkout.spec.js:line 42 ✓
|
|
66
|
+
rule: charge must succeed before order created
|
|
67
|
+
→ test: cart.checkout.spec.js:line 67 ✓
|
|
68
|
+
─────────────────────────────────────────────
|
|
69
|
+
|
|
70
|
+
Fail condition:
|
|
71
|
+
Any rule with no unit test.
|
|
72
|
+
Any unit test that fails.
|
|
73
|
+
Any test testing implementation not behavior.
|
|
74
|
+
|
|
75
|
+
─────────────────────────────────────────────────────────
|
|
76
|
+
|
|
77
|
+
STAGE 2 — INTEGRATION VALIDATION
|
|
78
|
+
|
|
79
|
+
Run the complete integration test suite.
|
|
80
|
+
Add: for every workflow — run the full path from
|
|
81
|
+
entry point through every layer to terminus.
|
|
82
|
+
Test with spec inputs. Confirm spec outputs.
|
|
83
|
+
Test every error path named in /workflows/.
|
|
84
|
+
|
|
85
|
+
Integration test matrix per workflow:
|
|
86
|
+
|
|
87
|
+
INTEGRATION TEST MATRIX
|
|
88
|
+
─────────────────────────────────────────────
|
|
89
|
+
workflow: cart.checkout
|
|
90
|
+
happy path:
|
|
91
|
+
inputs: valid cart, valid promo, valid card
|
|
92
|
+
expects: orderId returned, order in DB,
|
|
93
|
+
confirmation email sent
|
|
94
|
+
result: ✓ | ✗
|
|
95
|
+
|
|
96
|
+
error path — payment failure:
|
|
97
|
+
inputs: valid cart, declined card
|
|
98
|
+
expects: 402 returned, order NOT created
|
|
99
|
+
result: ✓ | ✗
|
|
100
|
+
|
|
101
|
+
boundary — Stripe:
|
|
102
|
+
simulate: Stripe timeout
|
|
103
|
+
expects: graceful error, no order created
|
|
104
|
+
result: ✓ | ✗
|
|
105
|
+
─────────────────────────────────────────────
|
|
106
|
+
|
|
107
|
+
Fail condition:
|
|
108
|
+
Any integration test that fails.
|
|
109
|
+
Any workflow with no integration test.
|
|
110
|
+
Any boundary with no failure simulation test.
|
|
111
|
+
Any error path from /workflows/ not tested.
|
|
112
|
+
|
|
113
|
+
─────────────────────────────────────────────────────────
|
|
114
|
+
|
|
115
|
+
STAGE 3 — UI VALIDATION
|
|
116
|
+
|
|
117
|
+
Build and run Playwright test suite.
|
|
118
|
+
One test file per workflow, generated from /screens/.
|
|
119
|
+
|
|
120
|
+
Every screen must render.
|
|
121
|
+
Every transition must fire correctly.
|
|
122
|
+
Every input must accept valid input.
|
|
123
|
+
Every on: transition must navigate to correct screen.
|
|
124
|
+
|
|
125
|
+
Additional coverage:
|
|
126
|
+
Responsive behavior — mobile and desktop
|
|
127
|
+
Accessibility — keyboard navigation
|
|
128
|
+
Error states — every error message renders
|
|
129
|
+
Loading states — async calls show indicators
|
|
130
|
+
Empty states — lists with no data render gracefully
|
|
131
|
+
|
|
132
|
+
Fail condition:
|
|
133
|
+
Any screen that fails to render.
|
|
134
|
+
Any transition that navigates wrong.
|
|
135
|
+
Any input that fails to accept valid input.
|
|
136
|
+
Any screen from /screens/ not covered.
|
|
137
|
+
|
|
138
|
+
─────────────────────────────────────────────────────────
|
|
139
|
+
|
|
140
|
+
STAGE 4 — SYSTEM VALIDATION
|
|
141
|
+
|
|
142
|
+
Load tests:
|
|
143
|
+
Every user-facing workflow gets a load test.
|
|
144
|
+
Default baseline: 50 concurrent users per workflow
|
|
145
|
+
unless scale signal in _mission.sil specifies otherwise.
|
|
146
|
+
Flag for human review to confirm appropriate scale.
|
|
147
|
+
|
|
148
|
+
Edge case registry:
|
|
149
|
+
Every edge case noted in /workflows/ error fields
|
|
150
|
+
and every gap flagged in /specs/ gaps fields
|
|
151
|
+
gets a dedicated test.
|
|
152
|
+
|
|
153
|
+
EDGE CASE REGISTRY
|
|
154
|
+
─────────────────────────────────────────────
|
|
155
|
+
source: workflows/cart.checkout.sil — error field
|
|
156
|
+
case: payment failure after order initiated
|
|
157
|
+
test: confirm order rolled back on charge failure
|
|
158
|
+
result: ✓ | ✗
|
|
159
|
+
─────────────────────────────────────────────
|
|
160
|
+
|
|
161
|
+
Behavioral equivalence:
|
|
162
|
+
For each workflow — compare A-01 extracted behavior
|
|
163
|
+
to new system behavior. Not implementation — behavior.
|
|
164
|
+
Same inputs must produce equivalent outputs.
|
|
165
|
+
|
|
166
|
+
Fail condition:
|
|
167
|
+
Any workflow failing under baseline load.
|
|
168
|
+
Any edge case producing unexpected behavior.
|
|
169
|
+
Any workflow where new behavior is not equivalent
|
|
170
|
+
to A-01 extracted behavior.
|
|
171
|
+
|
|
172
|
+
─────────────────────────────────────────────────────────
|
|
173
|
+
|
|
174
|
+
CERTIFICATION — BINARY PER WORKFLOW
|
|
175
|
+
|
|
176
|
+
✓ CERTIFIED
|
|
177
|
+
All four stages passed.
|
|
178
|
+
Rule coverage complete.
|
|
179
|
+
Integration, Playwright, load, edge cases all pass.
|
|
180
|
+
Behavior equivalent to A-01.
|
|
181
|
+
|
|
182
|
+
✗ GAP FOUND
|
|
183
|
+
One or more stages failed.
|
|
184
|
+
Specific failure documented.
|
|
185
|
+
Returned to A-05 with precise gap report.
|
|
186
|
+
Not certified until gap resolved and all four
|
|
187
|
+
stages re-run for this workflow.
|
|
188
|
+
|
|
189
|
+
─────────────────────────────────────────────────────────
|
|
190
|
+
|
|
191
|
+
GAP REPORTING
|
|
192
|
+
|
|
193
|
+
GAP REPORT
|
|
194
|
+
─────────────────────────────────────────────────────
|
|
195
|
+
workflow: cart.checkout
|
|
196
|
+
stage: Stage 2 — Integration
|
|
197
|
+
rule: charge must succeed before order created
|
|
198
|
+
test: payment failure → order not created
|
|
199
|
+
expected: order record absent from DB on 402
|
|
200
|
+
actual: order record present in DB on 402
|
|
201
|
+
spec ref: specs/cart.checkout.sil — rules line 3
|
|
202
|
+
fix needed: createOrder() must not be called if
|
|
203
|
+
chargePayment() returns failure
|
|
204
|
+
return to: A-05 Pass 2 — API layer
|
|
205
|
+
─────────────────────────────────────────────────────
|
|
206
|
+
|
|
207
|
+
Every gap report names: stage, rule, test, expected,
|
|
208
|
+
actual, spec reference, exact A-05 pass to return to.
|
|
209
|
+
|
|
210
|
+
A-05 fixes. A-06 re-runs all four stages for that
|
|
211
|
+
workflow only. Already certified workflows untouched.
|
|
212
|
+
|
|
213
|
+
─────────────────────────────────────────────────────────
|
|
214
|
+
|
|
215
|
+
OUTPUT — CERTIFICATION DOCUMENT
|
|
216
|
+
|
|
217
|
+
CONSTRUCT certification
|
|
218
|
+
ID system.certification
|
|
219
|
+
VERSION 1
|
|
220
|
+
─────────────────────────────────────────────────────────
|
|
221
|
+
system: [system name from _mission.sil]
|
|
222
|
+
date: [certification date]
|
|
223
|
+
version: [build version]
|
|
224
|
+
|
|
225
|
+
certification: COMPLETE | PARTIAL
|
|
226
|
+
|
|
227
|
+
WORKFLOW CERTIFICATION
|
|
228
|
+
─────────────────────────────────────────────
|
|
229
|
+
workflow S1 S2 S3 S4 STATUS
|
|
230
|
+
cart.checkout ✓ ✓ ✓ ✓ CERTIFIED
|
|
231
|
+
user.registration ✓ ✓ ✓ ✓ CERTIFIED
|
|
232
|
+
─────────────────────────────────────────────
|
|
233
|
+
|
|
234
|
+
COVERAGE SUMMARY
|
|
235
|
+
Business rules tested: N of N
|
|
236
|
+
Integration paths covered: N of N
|
|
237
|
+
Playwright tests run: N
|
|
238
|
+
Edge cases validated: N of N
|
|
239
|
+
Load tests passed: N of N
|
|
240
|
+
|
|
241
|
+
BEHAVIORAL EQUIVALENCE
|
|
242
|
+
Workflows equivalent to A-01: N of N
|
|
243
|
+
|
|
244
|
+
GAPS RESOLVED
|
|
245
|
+
[gaps found, returned, fixed, re-certified]
|
|
246
|
+
|
|
247
|
+
KNOWN LIMITATIONS
|
|
248
|
+
[anything certified but flagged from low confidence
|
|
249
|
+
upstream or warranting production monitoring]
|
|
250
|
+
|
|
251
|
+
EPISODES VALIDATED
|
|
252
|
+
[every open episode — changes present and tested]
|
|
253
|
+
|
|
254
|
+
CERTIFICATION STATEMENT
|
|
255
|
+
This system implements all business requirements
|
|
256
|
+
specified in /specs/ as extracted from the original
|
|
257
|
+
system by A-01 and A-02 and synthesized by A-03.
|
|
258
|
+
All workflows listed above have passed four stages
|
|
259
|
+
of validation. All business rules have corresponding
|
|
260
|
+
passing tests. Behavioral equivalence to the original
|
|
261
|
+
system has been verified per workflow.
|
|
262
|
+
|
|
263
|
+
The system is certified for delivery.
|
|
264
|
+
|
|
265
|
+
signed: A-06 — Validator & Certifier
|
|
266
|
+
─────────────────────────────────────────────────────────
|
|
267
|
+
|
|
268
|
+
─────────────────────────────────────────────────────────
|
|
269
|
+
|
|
270
|
+
WHAT YOU DO NOT DO
|
|
271
|
+
|
|
272
|
+
- Do not fix gaps — document and return to A-05
|
|
273
|
+
- Do not certify a workflow with a failing test
|
|
274
|
+
- Do not certify a workflow with an untested rule
|
|
275
|
+
- Do not certify where behavior is not equivalent
|
|
276
|
+
to the A-01 extracted workflow
|
|
277
|
+
- Do not certify the system if any workflow has
|
|
278
|
+
an open gap — partial certification is honest
|
|
279
|
+
- Do not run Stages 3 and 4 until 1 and 2 pass
|
|
280
|
+
- Do not skip load testing — test under realistic load
|
|
281
|
+
- Do not skip edge cases — A-01 found them for a reason
|
|
282
|
+
|
|
283
|
+
─────────────────────────────────────────────────────────
|
|
284
|
+
|
|
285
|
+
REMEMBER
|
|
286
|
+
|
|
287
|
+
You are the final gate. Everything the pipeline produced
|
|
288
|
+
flows through you before it reaches the client.
|
|
289
|
+
|
|
290
|
+
You answer one question: did A-05 build what A-03
|
|
291
|
+
specified? Not approximately. Not mostly. Completely.
|
|
292
|
+
|
|
293
|
+
Every rule tested. Every screen validated. Every
|
|
294
|
+
boundary exercised. Every edge case checked. Every
|
|
295
|
+
workflow equivalent to what was extracted.
|
|
296
|
+
|
|
297
|
+
The certification document is not a formality.
|
|
298
|
+
It is the proof that the business logic — extracted
|
|
299
|
+
from the old system, specified by A-03, built by A-05
|
|
300
|
+
— survived the journey intact.
|
|
301
|
+
|
|
302
|
+
That is what the client receives.
|
|
303
|
+
That is what Phoenix delivers.
|
|
304
|
+
```
|
package/bin/phoenix.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"episode.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/episode.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AA8InC,eAAO,MAAM,cAAc,SAIK,CAAA"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { createInterface } from 'node:readline';
|
|
2
|
+
import { resolve, join } from 'node:path';
|
|
3
|
+
import { readdirSync, existsSync } from 'node:fs';
|
|
4
|
+
import { Command } from 'commander';
|
|
5
|
+
import { readSil } from '../../parser/sil.js';
|
|
6
|
+
import { writeEpisode, resolveEpisode } from '../../episodes/manager.js';
|
|
7
|
+
import { AGENTS } from '../../pipeline/agents.js';
|
|
8
|
+
import { display } from '../display.js';
|
|
9
|
+
function ask(rl, question) {
|
|
10
|
+
return new Promise((resolve) => rl.question(question, resolve));
|
|
11
|
+
}
|
|
12
|
+
function nextEpisodeId(projectPath) {
|
|
13
|
+
const dir = join(projectPath, 'episodes');
|
|
14
|
+
if (!existsSync(dir))
|
|
15
|
+
return 'ep-001';
|
|
16
|
+
const files = readdirSync(dir).filter((f) => f.endsWith('.sil'));
|
|
17
|
+
const nums = files
|
|
18
|
+
.map((f) => parseInt(f.replace('ep-', '').replace('.sil', ''), 10))
|
|
19
|
+
.filter((n) => !isNaN(n));
|
|
20
|
+
const next = nums.length > 0 ? Math.max(...nums) + 1 : 1;
|
|
21
|
+
return `ep-${String(next).padStart(3, '0')}`;
|
|
22
|
+
}
|
|
23
|
+
const newSubcommand = new Command('new')
|
|
24
|
+
.description('Record a new requirement change or mid-engagement event')
|
|
25
|
+
.option('--project <path>', 'path to the Phoenix project', process.cwd())
|
|
26
|
+
.action(async (options) => {
|
|
27
|
+
const projectPath = resolve(options.project);
|
|
28
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
29
|
+
display.blank();
|
|
30
|
+
display.header('New Episode');
|
|
31
|
+
display.info(' Record a requirement change or mid-engagement event.');
|
|
32
|
+
display.info(' Every subsequent agent run will receive this context.');
|
|
33
|
+
display.blank();
|
|
34
|
+
const id = nextEpisodeId(projectPath);
|
|
35
|
+
display.info(` Episode ID: ${id}`);
|
|
36
|
+
display.blank();
|
|
37
|
+
const change = await ask(rl, ' What changed?\n > ');
|
|
38
|
+
const reason = await ask(rl, '\n Why? (client decision, data finding, stakeholder request)\n > ');
|
|
39
|
+
const trigger = await ask(rl, '\n Trigger type (requirement change / scope change / stakeholder request / data finding)\n > ');
|
|
40
|
+
display.blank();
|
|
41
|
+
display.info(' Which agents need attention? (space-separated, e.g. "a-01 a-03 a-05")');
|
|
42
|
+
display.info(' Agents: ' + AGENTS.map((a) => a.id).join(' '));
|
|
43
|
+
const affectsRaw = await ask(rl, ' > ');
|
|
44
|
+
const affectsIds = affectsRaw.trim().split(/\s+/).filter(Boolean);
|
|
45
|
+
const affects = {};
|
|
46
|
+
for (const agentId of affectsIds) {
|
|
47
|
+
const instruction = await ask(rl, `\n What should ${agentId.toUpperCase()} do?\n > `);
|
|
48
|
+
affects[agentId] = instruction.trim();
|
|
49
|
+
}
|
|
50
|
+
const allAgentIds = AGENTS.map((a) => a.id);
|
|
51
|
+
const skip = allAgentIds.filter((id) => !(id in affects));
|
|
52
|
+
rl.close();
|
|
53
|
+
const episode = {
|
|
54
|
+
id,
|
|
55
|
+
date: new Date().toISOString().split('T')[0],
|
|
56
|
+
trigger: trigger.trim(),
|
|
57
|
+
status: 'open',
|
|
58
|
+
change: change.trim(),
|
|
59
|
+
reason: reason.trim(),
|
|
60
|
+
affects,
|
|
61
|
+
skip,
|
|
62
|
+
};
|
|
63
|
+
writeEpisode(projectPath, episode);
|
|
64
|
+
display.blank();
|
|
65
|
+
display.success(`Episode recorded: ${id}`);
|
|
66
|
+
display.info(` Affects: ${Object.keys(affects).join(', ')}`);
|
|
67
|
+
display.info(` Skip: ${skip.join(', ')}`);
|
|
68
|
+
display.blank();
|
|
69
|
+
display.info(' Every subsequent phoenix run will inject this episode into the prompt.');
|
|
70
|
+
display.blank();
|
|
71
|
+
});
|
|
72
|
+
const listSubcommand = new Command('list')
|
|
73
|
+
.description('List episodes')
|
|
74
|
+
.option('--status <status>', 'filter by status: open | active | resolved')
|
|
75
|
+
.option('--project <path>', 'path to the Phoenix project', process.cwd())
|
|
76
|
+
.action((options) => {
|
|
77
|
+
const projectPath = resolve(options.project);
|
|
78
|
+
const dir = join(projectPath, 'episodes');
|
|
79
|
+
if (!existsSync(dir)) {
|
|
80
|
+
display.info('No episodes directory found.');
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
const files = readdirSync(dir).filter((f) => f.endsWith('.sil'));
|
|
84
|
+
if (files.length === 0) {
|
|
85
|
+
display.info('No episodes recorded.');
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
display.blank();
|
|
89
|
+
display.header('Episodes');
|
|
90
|
+
for (const file of files.sort()) {
|
|
91
|
+
const construct = readSil(join(dir, file));
|
|
92
|
+
const status = String(construct.fields['status'] ?? 'unknown');
|
|
93
|
+
const change = String(construct.fields['change'] ?? '').split('\n')[0];
|
|
94
|
+
const date = String(construct.fields['date'] ?? '');
|
|
95
|
+
if (options.status && status !== options.status)
|
|
96
|
+
continue;
|
|
97
|
+
const statusColor = status === 'open' ? '🟡' : status === 'resolved' ? '✓' : '⟳';
|
|
98
|
+
console.log(` ${statusColor} ${construct.id.padEnd(10)} ${date.padEnd(14)} ${change}`);
|
|
99
|
+
}
|
|
100
|
+
display.blank();
|
|
101
|
+
});
|
|
102
|
+
const resolveSubcommand = new Command('resolve')
|
|
103
|
+
.argument('<episode-id>', 'episode ID to resolve, e.g. ep-042')
|
|
104
|
+
.option('--project <path>', 'path to the Phoenix project', process.cwd())
|
|
105
|
+
.description('Mark an episode as resolved')
|
|
106
|
+
.action((episodeId, options) => {
|
|
107
|
+
const projectPath = resolve(options.project);
|
|
108
|
+
try {
|
|
109
|
+
resolveEpisode(episodeId, projectPath);
|
|
110
|
+
}
|
|
111
|
+
catch (err) {
|
|
112
|
+
display.error(err.message);
|
|
113
|
+
process.exit(1);
|
|
114
|
+
}
|
|
115
|
+
display.blank();
|
|
116
|
+
display.success(`Episode resolved: ${episodeId}`);
|
|
117
|
+
display.info(' It will no longer be injected into agent prompts.');
|
|
118
|
+
display.blank();
|
|
119
|
+
});
|
|
120
|
+
export const episodeCommand = new Command('episode')
|
|
121
|
+
.description('Manage mid-engagement episodes (requirement changes, scope events)')
|
|
122
|
+
.addCommand(newSubcommand)
|
|
123
|
+
.addCommand(listSubcommand)
|
|
124
|
+
.addCommand(resolveSubcommand);
|
|
125
|
+
//# sourceMappingURL=episode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"episode.js","sourceRoot":"","sources":["../../../src/cli/commands/episode.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gate.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/gate.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAcnC,eAAO,MAAM,WAAW,SA2CpB,CAAA"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { resolve } from 'node:path';
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { readState, writeState, approveGate, returnGate } from '../../pipeline/state.js';
|
|
4
|
+
import { display } from '../display.js';
|
|
5
|
+
const VALID_GATES = [
|
|
6
|
+
'a-04-approved',
|
|
7
|
+
'pass-1',
|
|
8
|
+
'pass-2',
|
|
9
|
+
'pass-3',
|
|
10
|
+
'pass-4',
|
|
11
|
+
'pass-5',
|
|
12
|
+
'pass-6',
|
|
13
|
+
];
|
|
14
|
+
export const gateCommand = new Command('gate')
|
|
15
|
+
.argument('<gate-id>', `gate to act on — ${VALID_GATES.join(' | ')}`)
|
|
16
|
+
.option('--approve', 'approve this gate — unblocks the next step')
|
|
17
|
+
.option('--return', 'return this gate — sends back for rework')
|
|
18
|
+
.option('--notes <text>', 'notes recorded with this gate decision')
|
|
19
|
+
.option('--project <path>', 'path to the Phoenix project', process.cwd())
|
|
20
|
+
.description('Approve or return a human gate')
|
|
21
|
+
.action((gateId, options) => {
|
|
22
|
+
if (!options.approve && !options.return) {
|
|
23
|
+
display.error('Specify --approve or --return');
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
const projectPath = resolve(options.project);
|
|
27
|
+
const notes = options.notes ?? '';
|
|
28
|
+
let state;
|
|
29
|
+
try {
|
|
30
|
+
state = readState(projectPath);
|
|
31
|
+
}
|
|
32
|
+
catch (err) {
|
|
33
|
+
display.error(err.message);
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
const updated = options.approve
|
|
37
|
+
? approveGate(gateId, notes, state)
|
|
38
|
+
: returnGate(gateId, notes, state);
|
|
39
|
+
writeState(projectPath, updated);
|
|
40
|
+
display.blank();
|
|
41
|
+
if (options.approve) {
|
|
42
|
+
display.success(`Gate approved: ${gateId}`);
|
|
43
|
+
if (notes)
|
|
44
|
+
display.info(` Notes: ${notes}`);
|
|
45
|
+
display.blank();
|
|
46
|
+
display.info(' Run `phoenix status` to see what is now unblocked.');
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
display.warn(`Gate returned: ${gateId}`);
|
|
50
|
+
if (notes)
|
|
51
|
+
display.info(` Notes: ${notes}`);
|
|
52
|
+
display.blank();
|
|
53
|
+
display.info(' Address the feedback, then re-run the agent pass.');
|
|
54
|
+
}
|
|
55
|
+
display.blank();
|
|
56
|
+
});
|
|
57
|
+
//# sourceMappingURL=gate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gate.js","sourceRoot":"","sources":["../../../src/cli/commands/gate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAA;AACxF,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAEvC,MAAM,WAAW,GAAG;IAClB,eAAe;IACf,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,QAAQ;CACT,CAAA;AAED,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC;KAC3C,QAAQ,CAAC,WAAW,EAAE,oBAAoB,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;KACpE,MAAM,CAAC,WAAW,EAAE,4CAA4C,CAAC;KACjE,MAAM,CAAC,UAAU,EAAE,0CAA0C,CAAC;KAC9D,MAAM,CAAC,gBAAgB,EAAE,wCAAwC,CAAC;KAClE,MAAM,CAAC,kBAAkB,EAAE,6BAA6B,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC;KACxE,WAAW,CAAC,gCAAgC,CAAC;KAC7C,MAAM,CAAC,CAAC,MAAc,EAAE,OAAiF,EAAE,EAAE;IAC5G,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;QACxC,OAAO,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAA;QAC9C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;IAC5C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,EAAE,CAAA;IAEjC,IAAI,KAAK,CAAA;IACT,IAAI,CAAC;QACH,KAAK,GAAG,SAAS,CAAC,WAAW,CAAC,CAAA;IAChC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAE,GAAa,CAAC,OAAO,CAAC,CAAA;QACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO;QAC7B,CAAC,CAAC,WAAW,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC;QACnC,CAAC,CAAC,UAAU,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,CAAA;IAEpC,UAAU,CAAC,WAAW,EAAE,OAAO,CAAC,CAAA;IAEhC,OAAO,CAAC,KAAK,EAAE,CAAA;IACf,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO,CAAC,OAAO,CAAC,kBAAkB,MAAM,EAAE,CAAC,CAAA;QAC3C,IAAI,KAAK;YAAE,OAAO,CAAC,IAAI,CAAC,YAAY,KAAK,EAAE,CAAC,CAAA;QAC5C,OAAO,CAAC,KAAK,EAAE,CAAA;QACf,OAAO,CAAC,IAAI,CAAC,sDAAsD,CAAC,CAAA;IACtE,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,IAAI,CAAC,kBAAkB,MAAM,EAAE,CAAC,CAAA;QACxC,IAAI,KAAK;YAAE,OAAO,CAAC,IAAI,CAAC,YAAY,KAAK,EAAE,CAAC,CAAA;QAC5C,OAAO,CAAC,KAAK,EAAE,CAAA;QACf,OAAO,CAAC,IAAI,CAAC,qDAAqD,CAAC,CAAA;IACrE,CAAC;IACD,OAAO,CAAC,KAAK,EAAE,CAAA;AACjB,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAsCnC,eAAO,MAAM,WAAW,SA2CpB,CAAA"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { mkdirSync, writeFileSync, existsSync } from 'node:fs';
|
|
2
|
+
import { join, basename } from 'node:path';
|
|
3
|
+
import { Command } from 'commander';
|
|
4
|
+
import { initState, writeState } from '../../pipeline/state.js';
|
|
5
|
+
import { display } from '../display.js';
|
|
6
|
+
const DIRS = [
|
|
7
|
+
'signals',
|
|
8
|
+
'workflows',
|
|
9
|
+
'screens',
|
|
10
|
+
'specs',
|
|
11
|
+
'architecture',
|
|
12
|
+
'build',
|
|
13
|
+
'certification',
|
|
14
|
+
'episodes',
|
|
15
|
+
];
|
|
16
|
+
const SEPARATOR = '─'.repeat(41);
|
|
17
|
+
function missionTemplate(projectName) {
|
|
18
|
+
return [
|
|
19
|
+
'CONSTRUCT signal',
|
|
20
|
+
`ID _mission`,
|
|
21
|
+
'VERSION 1',
|
|
22
|
+
SEPARATOR,
|
|
23
|
+
`project: ${projectName}`,
|
|
24
|
+
`system: (describe the system being modernized)`,
|
|
25
|
+
`team: (team context — who built it, how long, current state)`,
|
|
26
|
+
`domain: (business domain — e.g. order management, billing, logistics)`,
|
|
27
|
+
``,
|
|
28
|
+
`known-workflows:`,
|
|
29
|
+
` - (list known workflows here)`,
|
|
30
|
+
``,
|
|
31
|
+
`known-integrations:`,
|
|
32
|
+
` - (list known external systems)`,
|
|
33
|
+
``,
|
|
34
|
+
`notes: (anything worth flagging before extraction starts)`,
|
|
35
|
+
].join('\n');
|
|
36
|
+
}
|
|
37
|
+
export const initCommand = new Command('init')
|
|
38
|
+
.argument('[project-name]', 'name for the project (defaults to current directory name)')
|
|
39
|
+
.option('--project <path>', 'path to initialize (defaults to current directory)', process.cwd())
|
|
40
|
+
.description('Initialize a new Phoenix engagement in the current directory')
|
|
41
|
+
.action((projectName, options) => {
|
|
42
|
+
const projectPath = options.project;
|
|
43
|
+
const name = projectName ?? basename(projectPath);
|
|
44
|
+
const stateFile = join(projectPath, '.phoenix', 'state.json');
|
|
45
|
+
if (existsSync(stateFile)) {
|
|
46
|
+
display.warn(`Already initialized: ${stateFile}`);
|
|
47
|
+
display.info('Remove .phoenix/state.json to reinitialize.');
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
// Create directory structure
|
|
51
|
+
for (const dir of DIRS) {
|
|
52
|
+
mkdirSync(join(projectPath, dir), { recursive: true });
|
|
53
|
+
}
|
|
54
|
+
// Write initial state
|
|
55
|
+
const state = initState(projectPath, name);
|
|
56
|
+
writeState(projectPath, state);
|
|
57
|
+
// Write _mission.sil template
|
|
58
|
+
const missionPath = join(projectPath, '_mission.sil');
|
|
59
|
+
if (!existsSync(missionPath)) {
|
|
60
|
+
writeFileSync(missionPath, missionTemplate(name), 'utf-8');
|
|
61
|
+
}
|
|
62
|
+
display.blank();
|
|
63
|
+
display.success(`Initialized Phoenix engagement: ${name}`);
|
|
64
|
+
display.blank();
|
|
65
|
+
display.info(' Directories created:');
|
|
66
|
+
for (const dir of DIRS)
|
|
67
|
+
display.info(` /${dir}/`);
|
|
68
|
+
display.blank();
|
|
69
|
+
display.info(' Files created:');
|
|
70
|
+
display.info(' _mission.sil ← fill this in before running A-00');
|
|
71
|
+
display.info(' .phoenix/state.json');
|
|
72
|
+
display.blank();
|
|
73
|
+
display.info(' Next: edit _mission.sil, then run:');
|
|
74
|
+
display.info(' phoenix run a-00');
|
|
75
|
+
display.blank();
|
|
76
|
+
});
|
|
77
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAC9D,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAA;AAC/D,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAEvC,MAAM,IAAI,GAAG;IACX,SAAS;IACT,WAAW;IACX,SAAS;IACT,OAAO;IACP,cAAc;IACd,OAAO;IACP,eAAe;IACf,UAAU;CACX,CAAA;AAED,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;AAEhC,SAAS,eAAe,CAAC,WAAmB;IAC1C,OAAO;QACL,mBAAmB;QACnB,qBAAqB;QACrB,cAAc;QACd,SAAS;QACT,cAAc,WAAW,EAAE;QAC3B,mDAAmD;QACnD,mEAAmE;QACnE,0EAA0E;QAC1E,EAAE;QACF,kBAAkB;QAClB,iCAAiC;QACjC,EAAE;QACF,qBAAqB;QACrB,mCAAmC;QACnC,EAAE;QACF,+DAA+D;KAChE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACd,CAAC;AAED,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC;KAC3C,QAAQ,CAAC,gBAAgB,EAAE,2DAA2D,CAAC;KACvF,MAAM,CAAC,kBAAkB,EAAE,oDAAoD,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC;KAC/F,WAAW,CAAC,8DAA8D,CAAC;KAC3E,MAAM,CAAC,CAAC,WAA+B,EAAE,OAA4B,EAAE,EAAE;IACxE,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAA;IACnC,MAAM,IAAI,GAAG,WAAW,IAAI,QAAQ,CAAC,WAAW,CAAC,CAAA;IACjD,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,EAAE,UAAU,EAAE,YAAY,CAAC,CAAA;IAE7D,IAAI,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,IAAI,CAAC,wBAAwB,SAAS,EAAE,CAAC,CAAA;QACjD,OAAO,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAA;QAC3D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,6BAA6B;IAC7B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,SAAS,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;IACxD,CAAC;IAED,sBAAsB;IACtB,MAAM,KAAK,GAAG,SAAS,CAAC,WAAW,EAAE,IAAI,CAAC,CAAA;IAC1C,UAAU,CAAC,WAAW,EAAE,KAAK,CAAC,CAAA;IAE9B,8BAA8B;IAC9B,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,CAAA;IACrD,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC7B,aAAa,CAAC,WAAW,EAAE,eAAe,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,CAAA;IAC5D,CAAC;IAED,OAAO,CAAC,KAAK,EAAE,CAAA;IACf,OAAO,CAAC,OAAO,CAAC,mCAAmC,IAAI,EAAE,CAAC,CAAA;IAC1D,OAAO,CAAC,KAAK,EAAE,CAAA;IACf,OAAO,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAA;IACtC,KAAK,MAAM,GAAG,IAAI,IAAI;QAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,GAAG,GAAG,CAAC,CAAA;IACpD,OAAO,CAAC,KAAK,EAAE,CAAA;IACf,OAAO,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAA;IAChC,OAAO,CAAC,IAAI,CAAC,yDAAyD,CAAC,CAAA;IACvE,OAAO,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAA;IACvC,OAAO,CAAC,KAAK,EAAE,CAAA;IACf,OAAO,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAA;IACpD,OAAO,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAA;IACpC,OAAO,CAAC,KAAK,EAAE,CAAA;AACjB,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/run.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAInC,eAAO,MAAM,UAAU,SAuDnB,CAAA"}
|