pi-soly 0.2.1
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 +372 -0
- package/agents/soly-debugger.md +60 -0
- package/agents/soly-documenter.md +82 -0
- package/agents/soly-oracle.md +69 -0
- package/agents/soly-refactor.md +65 -0
- package/agents/soly-reviewer.md +107 -0
- package/agents/soly-tester.md +56 -0
- package/agents/soly-worker.md +84 -0
- package/agents-install.ts +105 -0
- package/commands.ts +778 -0
- package/config.ts +228 -0
- package/core.ts +1599 -0
- package/docs.ts +235 -0
- package/env.ts +196 -0
- package/git.ts +95 -0
- package/html.ts +157 -0
- package/index.ts +718 -0
- package/integrations.ts +64 -0
- package/intent.ts +303 -0
- package/iteration.ts +712 -0
- package/nudge.ts +123 -0
- package/package.json +66 -0
- package/scratchpad.ts +117 -0
- package/tools.ts +1132 -0
- package/workflows/execute.ts +401 -0
- package/workflows/index.ts +235 -0
- package/workflows/inspect.ts +492 -0
- package/workflows/parser.ts +268 -0
- package/workflows/pause.ts +150 -0
- package/workflows/planning.ts +624 -0
- package/workflows/quick.ts +258 -0
- package/workflows/resume.ts +201 -0
- package/workflows-data/discuss-phase.md +292 -0
- package/workflows-data/execute-phase.md +200 -0
- package/workflows-data/execute-plan.md +251 -0
- package/workflows-data/execute-task.md +116 -0
- package/workflows-data/pause-work.md +142 -0
- package/workflows-data/plan-phase.md +199 -0
- package/workflows-data/plan-task.md +185 -0
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
# Discuss Phase
|
|
2
|
+
|
|
3
|
+
<purpose>Reference document for the **interactive** `soly discuss <N>` flow. The
|
|
4
|
+
discussion is now driven by the interactive LLM (you) directly — no subagent.
|
|
5
|
+
You use the `soly_ask_user` tool to ask questions one at a time via a real
|
|
6
|
+
UI picker, and `soly_finish_discuss` to write the canonical CONTEXT.md. This
|
|
7
|
+
markdown is background context, not a strict protocol.</purpose>
|
|
8
|
+
|
|
9
|
+
<path_discipline>
|
|
10
|
+
**All soly-managed files live under `.soly/`.** CONTEXT.md, RESEARCH.md, and the discuss checkpoint all go in `.soly/phases/<NN>-<slug>/`. Never write these to the project root. Use absolute paths.
|
|
11
|
+
|
|
12
|
+
The iteration context file (path given by the parent in the task prompt) is your single source of truth for intent, STATE, ROADMAP, and any existing phase artifacts. Read it FIRST.
|
|
13
|
+
</path_discipline>
|
|
14
|
+
|
|
15
|
+
<interactive_flow>
|
|
16
|
+
**The flow is now interactive, not subagent-based.** The parent (extension) hands you a detailed prompt with the UX protocol. You drive the discussion in the same session:
|
|
17
|
+
|
|
18
|
+
1. **Read the iteration context file** (path given in the task prompt). It's the single source of truth — do NOT re-read STATE.md, ROADMAP.md, CONTEXT.md separately.
|
|
19
|
+
|
|
20
|
+
2. **Generate 3-5 phase-specific gray areas** grounded in the intent + ROADMAP row. For each, prepare a question with 2-3 CONCRETE options, ⭐ first = recommended answer, with 1-sentence rationale.
|
|
21
|
+
|
|
22
|
+
3. **Pick a picker** (the parent's prompt tells you which one is preferred):
|
|
23
|
+
- **`ask_pro`** (from the separate `pi-ask` extension, if installed) — multi-question tabbed picker. **PREFERRED**: call ONCE with all questions, returns all answers in one shot. Supports `allowOther: true` for free-text input per question.
|
|
24
|
+
- **`soly_ask_user`** (always available as fallback) — single-question picker. Call N times, one per question. No `allowOther` support.
|
|
25
|
+
|
|
26
|
+
4. **Save a checkpoint after each answer** with `soly_save_discuss_checkpoint` so the user can quit and resume. The final `soly_finish_discuss` will delete the checkpoint and write CONTEXT.md.
|
|
27
|
+
|
|
28
|
+
5. **After all questions captured**, call `soly_finish_discuss` with all decisions. It writes `<phase>-CONTEXT.md` and deletes the checkpoint.
|
|
29
|
+
|
|
30
|
+
6. **Tell the user the next step**: `soly plan <N>`.
|
|
31
|
+
|
|
32
|
+
**Resume:** if a checkpoint file exists, the parent detects it and tells you to resume from where the prior session left off. Acknowledge locked decisions at the top of your output, then continue with the next un-answered gray area.
|
|
33
|
+
</interactive_flow>
|
|
34
|
+
|
|
35
|
+
<read_first>`.soly/docs/` (INTENT, 0-point) · `.soly/STATE.md` · `.soly/ROADMAP.md` · `${PHASE_DIR}/*-CONTEXT.md` if exists (refine, don't re-derive) · `${PHASE_DIR}/*-DISCUSS-CHECKPOINT.json` if exists (resume from `areas_completed`)</read_first>
|
|
36
|
+
|
|
37
|
+
<philosophy>
|
|
38
|
+
**User = visionary. Worker = builder.** The user knows: how it should feel, what's essential vs nice-to-have, specific references. The user doesn't know (don't ask): codebase patterns, technical risks, implementation approach, success metrics.
|
|
39
|
+
|
|
40
|
+
Ask about vision and implementation choices. Capture for downstream.
|
|
41
|
+
</philosophy>
|
|
42
|
+
|
|
43
|
+
<scope_guardrail>
|
|
44
|
+
**No scope creep.** Phase boundary from `ROADMAP.md` is FIXED. Clarify HOW, never WHETHER.
|
|
45
|
+
- **Allowed:** "How should posts display?" · "What happens on empty?" · "Pull-to-refresh or manual?"
|
|
46
|
+
- **Not allowed:** "Should we also add comments?" · "What about search?" — new capability, its own phase.
|
|
47
|
+
|
|
48
|
+
If the user suggests scope creep: `"[X] would be a new capability — its own phase. Want me to note it for the backlog? For now, focus on [phase domain]."` Capture in `<deferred_ideas>`.
|
|
49
|
+
</scope_guardrail>
|
|
50
|
+
|
|
51
|
+
<gray_area_identification>
|
|
52
|
+
Gray areas are implementation decisions the user cares about — could go multiple ways, would change the result.
|
|
53
|
+
|
|
54
|
+
1. Read phase goal from `ROADMAP.md`.
|
|
55
|
+
2. Identify the domain (something users SEE/CALL/RUN/READ/ORGANIZE).
|
|
56
|
+
3. Generate phase-specific gray areas — **not** generic (UI/UX/Behavior).
|
|
57
|
+
|
|
58
|
+
Examples:
|
|
59
|
+
- Auth → Session handling · Error responses · Multi-device policy · Recovery flow
|
|
60
|
+
- Photo library → Grouping · Duplicates · Naming · Folder structure
|
|
61
|
+
- DB backup CLI → Output format · Flag design · Progress · Error recovery
|
|
62
|
+
- API docs → Structure · Example depth · Versioning · Interactivity
|
|
63
|
+
|
|
64
|
+
**Don't ask about:** implementation details, architecture, performance, scope (roadmap defines).
|
|
65
|
+
</gray_area_identification>
|
|
66
|
+
|
|
67
|
+
<output_protocol>
|
|
68
|
+
The `soly_ask_user` tool handles the user interaction. Each call is one round:
|
|
69
|
+
|
|
70
|
+
- **Picker shows:** title + question + rationale + numbered options. User navigates with ↑/↓/j/k, Enter to confirm, Esc to cancel.
|
|
71
|
+
- **Recommended option** (⭐ first) is visually marked so the user can pick it with one keystroke.
|
|
72
|
+
- **Rationale** is shown above the picker — this is the most important UX element, it shows the user that you've thought about the trade-off.
|
|
73
|
+
- **After answer**: tool returns the chosen option text. You acknowledge, save a checkpoint, and call `soly_ask_user` for the next question.
|
|
74
|
+
|
|
75
|
+
When all questions are captured, call `soly_finish_discuss` with all the collected decisions. It writes the canonical `<phase>-CONTEXT.md` per the schema below and deletes the checkpoint file.
|
|
76
|
+
|
|
77
|
+
The OLD subagent output protocol (with `## Gray Areas — Round N`, etc.) is **no longer used**. The picker replaces it.
|
|
78
|
+
</output_protocol>
|
|
79
|
+
|
|
80
|
+
<process>
|
|
81
|
+
|
|
82
|
+
**1. Initialize.** Compute state via `bash` (no SDK):
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
PHASE=$1
|
|
86
|
+
# Worker subagent inherits the parent's cwd (the project root), so
|
|
87
|
+
# `pwd` IS the project root. The previous `cd .. && pwd` was a bug.
|
|
88
|
+
PROJECT_ROOT="$(pwd)"
|
|
89
|
+
SOLY_DIR="$PROJECT_ROOT/.soly"
|
|
90
|
+
PHASE_DIR=$(ls -d "$SOLY_DIR/phases/"*"-$PHASE-"* 2>/dev/null | head -1) || { echo "Phase $PHASE not found" >&2; exit 1; }
|
|
91
|
+
PADDED_PHASE=$(printf "%02d" "$(echo "$PHASE" | grep -oE '^[0-9]+' | sed 's/^0*//')")
|
|
92
|
+
PHASE_SLUG=$(basename "$PHASE_DIR")
|
|
93
|
+
HAS_CONTEXT=$([ -f "$PHASE_DIR/${PADDED_PHASE}-CONTEXT.md" ] && echo true || echo false)
|
|
94
|
+
HAS_RESEARCH=$([ -f "$PHASE_DIR/${PADDED_PHASE}-RESEARCH.md" ] && echo true || echo false)
|
|
95
|
+
PLAN_COUNT=$(ls "$PHASE_DIR"/${PADDED_PHASE}-*-PLAN.md 2>/dev/null | wc -l | tr -d ' ')
|
|
96
|
+
HAS_CHECKPOINT=$([ -f "$PHASE_DIR/${PADDED_PHASE}-DISCUSS-CHECKPOINT.json" ] && echo true || echo false)
|
|
97
|
+
ROADMAP_EXISTS=$([ -f "$SOLY_DIR/ROADMAP.md" ] && echo true || echo false)
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
If `ROADMAP_EXISTS=false` → stop, tell parent "project must be initialized with a roadmap first."
|
|
101
|
+
|
|
102
|
+
**2. Check blocking anti-patterns.** Read `${PHASE_DIR}/.continue-here.md` if it exists; parse its Critical Anti-Patterns table for `severity = blocking`. For each, include in the next round's output:
|
|
103
|
+
|
|
104
|
+
```
|
|
105
|
+
## Blocking Anti-Patterns (from .continue-here.md)
|
|
106
|
+
> Resume agent must demonstrate understanding before proceeding.
|
|
107
|
+
|
|
108
|
+
### <pattern name>
|
|
109
|
+
1. **What is it?** ...
|
|
110
|
+
2. **How did it manifest?** ...
|
|
111
|
+
3. **Structural prevention:** ...
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
If you cannot answer from `.continue-here.md`, return `## Clarifications Needed` and stop.
|
|
115
|
+
|
|
116
|
+
**3. Check SPEC.md.** `ls "$PHASE_DIR"/*-SPEC.md 2>/dev/null | grep -v AI-SPEC | head -1`. If exists: read, count `## Requirements`, treat as locked — do NOT re-ask WHAT/WHY, only HOW. Add to `## Decisions Locked`.
|
|
117
|
+
|
|
118
|
+
**4. Resume / continue / fresh.**
|
|
119
|
+
|
|
120
|
+
| state | action |
|
|
121
|
+
|---|---|
|
|
122
|
+
| checkpoint exists | parse `decisions` + `areas_completed`; acknowledge locked; continue from first un-answered area |
|
|
123
|
+
| CONTEXT.md exists, no checkpoint | "refine" mode — list existing decisions, surface only uncovered gray areas |
|
|
124
|
+
| PLANs exist, no CONTEXT.md | warn in round 1: `## Heads Up — <N> plan(s) exist without user context. Decisions here won't affect them unless you replan. To proceed anyway, just answer. To abort, stop here.` |
|
|
125
|
+
| (none) | fresh — initialize phases 5–9 from scratch |
|
|
126
|
+
|
|
127
|
+
**5. Load prior context.** Read in this order, deduplicating:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
[ -f "$SOLY_DIR/PROJECT.md" ] && echo "PROJECT.md"
|
|
131
|
+
[ -f "$SOLY_DIR/REQUIREMENTS.md" ] && echo "REQUIREMENTS.md"
|
|
132
|
+
[ -f "$SOLY_DIR/STATE.md" ] && echo "STATE.md"
|
|
133
|
+
[ -f "$SOLY_DIR/DECISIONS-INDEX.md" ] && echo "DECISIONS-INDEX.md (prefer over per-phase if present)"
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Most-recent 3 prior `*-CONTEXT.md` files (prefer DECISIONS-INDEX if present). Extract `<decisions>`, `<specifics>`, and patterns (e.g., "user prefers minimal UI"). If `.soly/spikes/MANIFEST.md` or `.soly/sketches/MANIFEST.md` exist with `WRAPPED: true` frontmatter, read as validated findings.
|
|
137
|
+
|
|
138
|
+
**6. Cross-reference todos.** (Worker doesn't have `soly_todos`; use `bash` + `grep` with phase-domain keywords.)
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
KEYWORDS="<phase-domain-keywords>" # e.g. "auth|login|session"
|
|
142
|
+
grep -rnE "TODO|FIXME|XXX" --include="*.ts" --include="*.tsx" --include="*.py" --include="*.go" "$PROJECT_ROOT" 2>/dev/null \
|
|
143
|
+
| grep -iE "$KEYWORDS" | head -20
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Present matches; user picks folded (→ CONTEXT.md `<folded_todos>`) vs reviewed-not-folded (→ `<reviewed_todos>`).
|
|
147
|
+
|
|
148
|
+
**7. Scout codebase.** (No SDK; pure bash/find/grep.)
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
ls "$SOLY_DIR/codebase/" 2>/dev/null
|
|
152
|
+
find "$PROJECT_ROOT/src" -maxdepth 3 -type f \( -name "*.ts" -o -name "*.tsx" -o -name "*.py" \) 2>/dev/null | head -20
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Build a small `<codebase_context>` block (≤ 10 lines) of reusable assets/patterns. Use to annotate gray areas ("you already have a Card component with shadow/rounded variants — reusing it keeps the app consistent").
|
|
156
|
+
|
|
157
|
+
**8. Analyze phase.** Grounded in `<prior_decisions>`, `<codebase_context>`, `<locked_requirements>`. Produce:
|
|
158
|
+
- **Domain boundary** — what this phase delivers, what it does NOT.
|
|
159
|
+
- **Canonical refs accumulator** — every doc/spec/ADR the planner will need (ROADMAP refs, REQUIREMENTS, anything the user references). Full relative paths. MANDATORY in CONTEXT.md.
|
|
160
|
+
- **Already-decided gray areas** — skip from `<prior_decisions>` + `<locked_requirements>`.
|
|
161
|
+
- **Gray areas** — 1–2 specific ambiguities per relevant category.
|
|
162
|
+
- **Skip assessment** — if no meaningful gray areas remain, jump to step 11 with `<no_discussion_needed: true>`.
|
|
163
|
+
|
|
164
|
+
**9. Present gray areas.** Output `## Gray Areas — Round <N>` per output protocol. **3–5 areas/round sweet spot; > 5 → defer the rest to next round.** No "skip" / "you decide" options — give real choices.
|
|
165
|
+
|
|
166
|
+
**10. Discuss (interactive, one question at a time).**
|
|
167
|
+
|
|
168
|
+
**PREFERRED** (if `ask_pro` tool is available from the `pi-ask` extension): call `ask_pro` ONCE with all questions as tabs. Returns all answers in one shot. Per question: `header`, `question`, `options[2-4]`, optional `multiSelect`, optional `allowOther` (text input for custom answer).
|
|
169
|
+
|
|
170
|
+
**FALLBACK** (if `ask_pro` is not available): call `soly_ask_user` once per question, one at a time. Pattern:
|
|
171
|
+
|
|
172
|
+
```
|
|
173
|
+
soly_ask_user({
|
|
174
|
+
title: "Q1: <category>",
|
|
175
|
+
question: "<one short sentence>",
|
|
176
|
+
options: [
|
|
177
|
+
"⭐ <recommended option> — <1 sentence why>",
|
|
178
|
+
"<alternative 1>",
|
|
179
|
+
"<alternative 2>",
|
|
180
|
+
],
|
|
181
|
+
rationale: "<1–2 sentence note>",
|
|
182
|
+
})
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
After each answer (or once after all answers, for `ask_pro`), call `soly_save_discuss_checkpoint({phase_number, decisions, areas_total, areas_completed})` to enable resume. The user can quit mid-discussion and the next `soly discuss <N>` will pick up from the checkpoint.
|
|
186
|
+
|
|
187
|
+
If the user cancels a picker (Esc), defer that question and move on — never loop on the same question.
|
|
188
|
+
|
|
189
|
+
When all questions captured, call `soly_finish_discuss` with all decisions. It writes the canonical CONTEXT.md and deletes the checkpoint.
|
|
190
|
+
|
|
191
|
+
**11. Write CONTEXT.md** when all areas decided (or explicitly deferred):
|
|
192
|
+
|
|
193
|
+
```markdown
|
|
194
|
+
---
|
|
195
|
+
phase: <N> phase_slug: <slug> generated: <ISO8601>
|
|
196
|
+
areas_completed: <N> areas_deferred: <N>
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
# <N>: <Name> — Discussion Context
|
|
200
|
+
|
|
201
|
+
<domain>What this phase delivers, 1–2 paragraphs grounded in ROADMAP + intent.</domain>
|
|
202
|
+
|
|
203
|
+
<spec_lock><!-- only if SPEC.md was loaded -->
|
|
204
|
+
Requirements locked by SPEC.md. Do not re-litigate.
|
|
205
|
+
- <req 1>
|
|
206
|
+
</spec_lock>
|
|
207
|
+
|
|
208
|
+
<decisions>
|
|
209
|
+
### <Category>
|
|
210
|
+
- **Decision:** <what>
|
|
211
|
+
**Rationale:** <why / "user discretion">
|
|
212
|
+
**Source:** Round <N> of `soly discuss <N>`
|
|
213
|
+
</decisions>
|
|
214
|
+
|
|
215
|
+
<canonical_refs> <!-- MANDATORY -->
|
|
216
|
+
- `.soly/docs/<file>` — <why>
|
|
217
|
+
- `.soly/features/<feat>/README.md` — <why>
|
|
218
|
+
- `.soly/contracts/<file>` — <why>
|
|
219
|
+
- (no external docs referenced) <!-- only if literally none -->
|
|
220
|
+
</canonical_refs>
|
|
221
|
+
|
|
222
|
+
<code_context>
|
|
223
|
+
Reusable assets/patterns the planner should know:
|
|
224
|
+
- <path> — <what, why reuse>
|
|
225
|
+
</code_context>
|
|
226
|
+
|
|
227
|
+
<deferred_ideas>Scope-creep items for future phases.</deferred_ideas>
|
|
228
|
+
|
|
229
|
+
<folded_todos><!-- only if matches found --></folded_todos>
|
|
230
|
+
<reviewed_todos><!-- only if matches found --></reviewed_todos>
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
If `spec_lock` present, do NOT duplicate requirements into `<decisions>` — only implementation decisions.
|
|
234
|
+
|
|
235
|
+
**12. Report.**
|
|
236
|
+
|
|
237
|
+
- All decided:
|
|
238
|
+
```
|
|
239
|
+
## Discussion Complete — Phase <N>
|
|
240
|
+
Created: <path>
|
|
241
|
+
### Decisions Captured
|
|
242
|
+
- <Cat>: <one-liner>
|
|
243
|
+
### Deferred
|
|
244
|
+
- <idea> — future phase
|
|
245
|
+
### Next Step
|
|
246
|
+
`soly plan <N>`
|
|
247
|
+
```
|
|
248
|
+
- More rounds needed:
|
|
249
|
+
```
|
|
250
|
+
## Round <N> Complete — Phase <N>
|
|
251
|
+
### Decisions Captured This Round
|
|
252
|
+
- <Cat>: <one-liner>
|
|
253
|
+
### Open Questions (<M> remaining)
|
|
254
|
+
- <Area>: <ambiguity>
|
|
255
|
+
### Next Step
|
|
256
|
+
Re-invoke `soly discuss <N>` to continue. Your next free-text message will be parsed for answers.
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
</process>
|
|
260
|
+
|
|
261
|
+
<checkpoint_schema>
|
|
262
|
+
`${PHASE_DIR}/${PADDED_PHASE}-DISCUSS-CHECKPOINT.json`:
|
|
263
|
+
|
|
264
|
+
```json
|
|
265
|
+
{
|
|
266
|
+
"version": "1.0",
|
|
267
|
+
"phase": <N>, "padded_phase": "<NN>", "phase_slug": "<slug>", "phase_dir": "<path>",
|
|
268
|
+
"round": <N>,
|
|
269
|
+
"areas_total": <M>,
|
|
270
|
+
"areas_completed": [<index>, ...],
|
|
271
|
+
"areas_deferred": [<index>, ...],
|
|
272
|
+
"decisions": [
|
|
273
|
+
{"area": "<n>", "category": "<c>", "choice": "<what>", "rationale": "<why / 'user discretion'>", "round": <N>}
|
|
274
|
+
],
|
|
275
|
+
"canonical_refs": ["<path>", ...],
|
|
276
|
+
"codebase_context": ["<line>", ...],
|
|
277
|
+
"deferred_ideas": ["<idea>", ...],
|
|
278
|
+
"next_action": "await_user_answers | write_context | no_discussion_needed"
|
|
279
|
+
}
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
Update after every round. Delete after `write_context` succeeds.
|
|
283
|
+
</checkpoint_schema>
|
|
284
|
+
|
|
285
|
+
<hard_rules>
|
|
286
|
+
- No production code. Discussion/planning only.
|
|
287
|
+
- No PLAN.md from this workflow — that's `soly plan`.
|
|
288
|
+
- Don't assume missing intent. If `.soly/docs/` is silent, ask.
|
|
289
|
+
- No scope creep. Deferred ideas → `<deferred_ideas>`, not decisions.
|
|
290
|
+
- No subagents (you ARE one). No `.soly/rules/` edits.
|
|
291
|
+
- Return: structured output per output_protocol + checkpoint updates. Parent relays to user.
|
|
292
|
+
</hard_rules>
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
# Execute Phase
|
|
2
|
+
|
|
3
|
+
<purpose>Execute all plans in a phase, wave by wave. Per plan, follow `execute-plan.md` inline. Update STATE.md between plans. Generate a phase-level VERIFICATION.md at the end. You ARE the executor (`maxSubagentDepth: 1` is enforced — no sub-sub-agents). Checkpoint requests return a structured block; parent relays to user; next `soly execute <N>` resumes from `.execute-checkpoint.json`.</purpose>
|
|
4
|
+
|
|
5
|
+
<path_discipline>
|
|
6
|
+
**All soly-managed files live under `.soly/`.** Never write PLAN.md, CONTEXT.md, RESEARCH.md, SUMMARY.md, iteration files, or handoffs to the project root. All phase files go in `.soly/phases/<NN>-<slug>/`. Use absolute paths (or paths starting with `$SOLY_DIR`) — never bare relative names that could land in cwd.
|
|
7
|
+
|
|
8
|
+
The iteration context file (path given by the parent in the task prompt) is your single source of truth for intent, STATE, ROADMAP, and any existing phase artifacts. Read it FIRST, before any of your own `read` or `ls` calls.
|
|
9
|
+
</path_discipline>
|
|
10
|
+
|
|
11
|
+
<read_first>`.soly/STATE.md` (single source of truth for "where am I") · `.soly/ROADMAP.md` (phase goal + reqs) · `.soly/docs/` (INTENT, re-read before each plan) · the phase directory: list PLAN.md sorted, plus any SUMMARY.md / CONTEXT.md / RESEARCH.md / `.execute-checkpoint.json`. If `.soly/` missing → stop + error.</read_first>
|
|
12
|
+
|
|
13
|
+
<core_principle>
|
|
14
|
+
**Orchestrate, don't re-specify.** Each PLAN.md is the contract; `execute-plan.md` is the per-plan protocol. This file adds: wave grouping, state transitions between plans, phase-level aggregation (VERIFICATION.md), safe resumption from partial state. The full per-plan steps live in `execute-plan.md` — read it once, then apply per plan.
|
|
15
|
+
</core_principle>
|
|
16
|
+
|
|
17
|
+
<process>
|
|
18
|
+
|
|
19
|
+
**1. Parse args.** `PHASE` (required) plus optional `--plan <M>`, `--wave <W>`, `--from <M>`. If `--plan` is set, `PLAN_MODE=true` — skip wave grouping (defer to `execute-plan.md`).
|
|
20
|
+
|
|
21
|
+
**2. Initialize.** `bash` only:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
PHASE="$1"
|
|
25
|
+
# Worker subagent inherits the parent's cwd (the project root), so
|
|
26
|
+
# `pwd` IS the project root. The previous `cd .. && pwd` was a bug
|
|
27
|
+
# that sent files to the parent of the project (and then the worker
|
|
28
|
+
# would fall back to the `write` tool with a relative path, polluting
|
|
29
|
+
# the project root).
|
|
30
|
+
PROJECT_ROOT="$(pwd)"
|
|
31
|
+
SOLY_DIR="$PROJECT_ROOT/.soly"
|
|
32
|
+
PHASE_DIR=$(ls -d "$SOLY_DIR/phases/"*"-$PHASE-"* 2>/dev/null | head -1) || { echo "Phase $PHASE not found" >&2; exit 1; }
|
|
33
|
+
PADDED_PHASE=$(printf "%02d" "$(echo "$PHASE" | grep -oE '^[0-9]+' | sed 's/^0*//')")
|
|
34
|
+
PHASE_SLUG=$(basename "$PHASE_DIR")
|
|
35
|
+
mapfile -t ALL_PLANS < <(ls "$PHASE_DIR"/${PADDED_PHASE}-*-PLAN.md 2>/dev/null | sort)
|
|
36
|
+
mapfile -t ALL_SUMMARIES < <(ls "$PHASE_DIR"/${PADDED_PHASE}-*-SUMMARY.md 2>/dev/null | sort)
|
|
37
|
+
COMPLETED=$(for p in "${ALL_PLANS[@]}"; do [ -f "${p/-PLAN.md/-SUMMARY.md}" ] && echo 1; done | wc -l)
|
|
38
|
+
HAS_CHECKPOINT=$([ -f "$PHASE_DIR/.execute-checkpoint.json" ] && echo true || echo false)
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
If `HAS_CHECKPOINT=true` → read it, resume from `next_task_index`, surface `## Resuming From Checkpoint` in your first output.
|
|
42
|
+
|
|
43
|
+
**3. Safe-resume gate** (detect illegal partial state BEFORE any new work):
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
for p in "${ALL_PLANS[@]}"; do
|
|
47
|
+
s="${p/-PLAN.md/-SUMMARY.md}"
|
|
48
|
+
[ -f "$s" ] && continue
|
|
49
|
+
PLAN_ID=$(basename "$p" | sed -E "s/^${PADDED_PHASE}-([0-9]+)-.*/\1/")
|
|
50
|
+
if git log --oneline --all --grep="${PADDED_PHASE}-${PLAN_ID}" 2>/dev/null | grep -q .; then
|
|
51
|
+
echo "PARTIAL: $p has production commits but no SUMMARY"
|
|
52
|
+
fi
|
|
53
|
+
done
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
If any partial state detected → return `## Partial Plans Detected` listing them, **stop**. Do not silently re-execute; user chooses resume-summary-write / rollback / investigate.
|
|
57
|
+
|
|
58
|
+
**4. Check blocking anti-patterns.** Read `${PHASE_DIR}/.continue-here.md` if it exists; parse its Critical Anti-Patterns table for `severity = blocking`. For each, output `## Blocking Anti-Patterns` with the 3-question format (what / how manifested / structural prevention). If unanswerable from `.continue-here.md` → return `## Clarifications Needed` and stop.
|
|
59
|
+
|
|
60
|
+
**5. Discover + group plans.** Parse frontmatter of each PLAN.md for `wave:`, `depends-on:`, `requirements:`. Group by wave (1, 2, ...). Within a wave, dependency-driven order; file-name sort for unconstrained ties.
|
|
61
|
+
|
|
62
|
+
**Validate wave graph:**
|
|
63
|
+
|
|
64
|
+
| check | rule |
|
|
65
|
+
|---|---|
|
|
66
|
+
| Acyclic | walk `depends-on:` — no plan depends on itself, transitively or directly |
|
|
67
|
+
| Wave-consistent | `plan.wave > max(wave of its deps)` |
|
|
68
|
+
| External deps | any `depends-on:` outside this phase points to prior-phase work already Complete in STATE.md |
|
|
69
|
+
|
|
70
|
+
If validation fails → return `## Wave Graph Invalid`, stop.
|
|
71
|
+
|
|
72
|
+
**6. Execute waves.** For each wave:
|
|
73
|
+
|
|
74
|
+
1. List plans in dependency-safe order.
|
|
75
|
+
2. For each plan, **run the per-plan loop** (step 7).
|
|
76
|
+
3. After the wave, run wave gates (step 8).
|
|
77
|
+
4. If `--wave <W>` set and we're past W, stop.
|
|
78
|
+
|
|
79
|
+
Within a wave, plans are "parallel" in name but you do the work sequentially in this worker context. **Skip rule:** if a plan already has SUMMARY.md, skip — it's done from a prior invocation. Update `completed` count.
|
|
80
|
+
|
|
81
|
+
**7. Per-plan loop** (apply `execute-plan.md` inline — don't re-specify its steps):
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
For plan P:
|
|
85
|
+
1. record_start_time
|
|
86
|
+
2. parse_plan (count tasks, find acceptance criteria, checkpoints)
|
|
87
|
+
3. load_prompt (read PLAN.md fully; honor CONTEXT.md, RESEARCH.md)
|
|
88
|
+
4. execute tasks sequentially: read read_first → implement → verify
|
|
89
|
+
acceptance criteria (HARD GATE) → commit per task
|
|
90
|
+
5. if checkpoint:* reached → write .execute-checkpoint.json,
|
|
91
|
+
return Checkpoint block to parent, STOP
|
|
92
|
+
6. create_summary + commit SUMMARY.md (atomic — no narrative between;
|
|
93
|
+
write to `${PHASE_DIR}/${PADDED_PHASE}-${M}-<slug>-SUMMARY.md` — absolute path)
|
|
94
|
+
7. update_state: bump current_plan in STATE.md; mark plan row in
|
|
95
|
+
ROADMAP.md
|
|
96
|
+
8. update_requirements if PLAN.md has `requirements:`
|
|
97
|
+
9. delete .execute-checkpoint.json (if any)
|
|
98
|
+
10. record result for wave aggregation
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
**8. Wave gates (after each wave).**
|
|
102
|
+
|
|
103
|
+
**Regression check** — run the project's test suite (`npm test` / `bun test` / `dotnet test` / `pytest` / `go test ./...`). All previously-passing tests must still pass.
|
|
104
|
+
|
|
105
|
+
- Regression detected → STOP, return `## ⚠ Regression Detected` (failing tests, wave that introduced them, recommendation: revert / fix / continue with acknowledged breakage).
|
|
106
|
+
- Regression in CONTEXT.md as "expected" (e.g., "Wave 2 breaks test X; fixed in Wave 3") → continue.
|
|
107
|
+
|
|
108
|
+
**Cross-plan wiring check** — for each `must_haves.key_links` in each plan's SUMMARY, spot-check the link exists. If missing, log in wave summary; do NOT fail the wave.
|
|
109
|
+
|
|
110
|
+
These gates are intentionally lighter than a full external verifier — soly on pi trusts the executor's `acceptance_criteria` HARD GATE.
|
|
111
|
+
|
|
112
|
+
**9. Checkpoint handling.** When a plan hits `type="checkpoint:*"` or auth gate → follow `execute-plan.md`'s checkpoint protocol: write `.execute-checkpoint.json`, return `## Checkpoint` to parent. Parent presents, gathers response, re-invokes `soly execute <N>`. Next invocation picks up from the JSON.
|
|
113
|
+
|
|
114
|
+
**10. Aggregate + VERIFICATION.md.** After all waves:
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
## Phase <N>: <Name> Execution Complete
|
|
118
|
+
### Plans
|
|
119
|
+
- Plan 1: <title> — <duration> — <tasks>/<total> — <files mod> — <commit range>
|
|
120
|
+
### Wave Summary
|
|
121
|
+
- Wave 1: <n> plan(s), <dur>, <f> files · Wave 2: ...
|
|
122
|
+
### Total Plans <X>/<Y> · Duration <T> · Files <N> created, <M> modified · Deviations <K>
|
|
123
|
+
### Issues Encountered <aggregated from each SUMMARY "Issues Encountered">
|
|
124
|
+
### Next `soly status` · `<project verify cmd>` · `soly plan <N+1>` or `soly pause`
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Write `${PHASE_DIR}/${PADDED_PHASE}-VERIFICATION.md` (the canonical "did the phase deliver what ROADMAP said" check). Use the absolute path — never a bare relative name.
|
|
128
|
+
|
|
129
|
+
```markdown
|
|
130
|
+
---
|
|
131
|
+
phase: <N> phase_slug: <slug> status: pending generated: <ISO>
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
# Phase <N>: <Name> — Verification
|
|
135
|
+
|
|
136
|
+
## Phase Goal
|
|
137
|
+
<one-line from ROADMAP.md>
|
|
138
|
+
|
|
139
|
+
## Requirements Coverage
|
|
140
|
+
| Req ID | Plan | Status | Notes |
|
|
141
|
+
|---|---|---|---|
|
|
142
|
+
| REQ-01 | Plan 2 | complete | see SUMMARY § Verification |
|
|
143
|
+
|
|
144
|
+
## Test Results
|
|
145
|
+
- <verify cmd> → <result>
|
|
146
|
+
|
|
147
|
+
## Manual Verification
|
|
148
|
+
<URLs to open, behaviors to confirm>
|
|
149
|
+
|
|
150
|
+
## Gaps
|
|
151
|
+
- [ ] <not yet verified>
|
|
152
|
+
- [ ] <another gap>
|
|
153
|
+
|
|
154
|
+
## Status
|
|
155
|
+
`pending` until the user (or a verifier) flips to `passed` / `failed`. Phase is "Complete" when this file exists AND `status: passed`.
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
**Do NOT flip status to `passed` yourself** — that decision belongs to the user or a verifier.
|
|
159
|
+
|
|
160
|
+
**11. Update ROADMAP.md** (read + edit at `${SOLY_DIR}/ROADMAP.md` — absolute path):
|
|
161
|
+
- Phase row status → `Complete` if VERIFICATION.md `status: passed`, else `In Progress`.
|
|
162
|
+
- Update `completed_plans` count.
|
|
163
|
+
|
|
164
|
+
**12. Update STATE.md** (at `${SOLY_DIR}/STATE.md` — absolute path):
|
|
165
|
+
- Phase status → `Complete` (if VERIFICATION passed) or `Needs Review` (if not).
|
|
166
|
+
- Reset `current_plan` → 0. Update `last_updated`. Update `progress:` block.
|
|
167
|
+
- Keep < 150 lines.
|
|
168
|
+
|
|
169
|
+
**13. Return:**
|
|
170
|
+
|
|
171
|
+
- Complete:
|
|
172
|
+
```
|
|
173
|
+
## ✓ Phase <N>: <Name> Complete
|
|
174
|
+
### What Shipped <2–3 sentences>
|
|
175
|
+
### Stats Plans: <n> · Files: <c> created / <m> modified · Reqs: <c>/<t> · Deviations: <d>
|
|
176
|
+
### Verification <path> created (status: pending — flip after smoke test)
|
|
177
|
+
### Next `soly plan <N+1>` · `soly status` · `soly pause`
|
|
178
|
+
```
|
|
179
|
+
- Incomplete (some plans unshipped / checkpoint pending):
|
|
180
|
+
```
|
|
181
|
+
## ⚠ Phase <N>: <Name> Incomplete
|
|
182
|
+
### Shipped
|
|
183
|
+
- Plan 1: <title> — <dur>
|
|
184
|
+
### Outstanding
|
|
185
|
+
- Plan 3: <title> — checkpoint reached, awaiting user input
|
|
186
|
+
- Plan 5: <title> — not started
|
|
187
|
+
### Next Re-invoke `soly execute <N>` to continue.
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
</process>
|
|
191
|
+
|
|
192
|
+
<hard_rules>
|
|
193
|
+
- No `.soly/rules/` edits. No subagents (`maxSubagentDepth: 1`).
|
|
194
|
+
- No silent skip of partial-state plans — surface and stop.
|
|
195
|
+
- No flipping VERIFICATION.md to `passed` yourself.
|
|
196
|
+
- No silent architectural decisions — use `execute-plan.md`'s Rule 4 + checkpoint.
|
|
197
|
+
- Wave graph acyclic; validate before executing.
|
|
198
|
+
- Conventional Commits 1.0.0. Per-plan: `<type>(<plan-id>): <summary>`.
|
|
199
|
+
- Return: phase summary, per-plan rollup, verification status, next step.
|
|
200
|
+
</hard_rules>
|