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,251 @@
|
|
|
1
|
+
# Execute Plan
|
|
2
|
+
|
|
3
|
+
<purpose>Execute one PLAN.md, produce a matching SUMMARY.md, update STATE.md/ROADMAP.md. Single worker — no sub-subagents.</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, phase CONTEXT/RESEARCH, prior SUMMARYs, and (section 6) the current PLAN. Read it FIRST.
|
|
9
|
+
</path_discipline>
|
|
10
|
+
|
|
11
|
+
<read_first>`.soly/STATE.md` · `.soly/ROADMAP.md` · `PLAN.md` (the contract) · `<phase>-CONTEXT.md` if exists (honor user decisions) · `<phase>-RESEARCH.md` if exists (use chosen libs/patterns). If `.soly/` missing → stop + error.</read_first>
|
|
12
|
+
|
|
13
|
+
<atomic_close_out>
|
|
14
|
+
**Only legal close-out order:** `production-code commit(s) → SUMMARY commit → STATE/ROADMAP update`.
|
|
15
|
+
The only legal half-state is mid-production-commits while still actively working. Once production commits exist, returning without a committed SUMMARY is an **illegal partial-plan state** — the next `soly execute-plan` must detect it before starting a new plan.
|
|
16
|
+
</atomic_close_out>
|
|
17
|
+
|
|
18
|
+
<process>
|
|
19
|
+
|
|
20
|
+
**1. Init context + partial-plan check.** `bash` only (no SDK):
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
PHASE="$1"; PLAN="$2" # PLAN optional — defaults to next unfinished
|
|
24
|
+
# Worker subagent inherits the parent's cwd (the project root), so
|
|
25
|
+
# `pwd` IS the project root. The previous `cd .. && pwd` was a bug.
|
|
26
|
+
PROJECT_ROOT="$(pwd)"
|
|
27
|
+
SOLY_DIR="$PROJECT_ROOT/.soly"
|
|
28
|
+
PHASE_DIR=$(ls -d "$SOLY_DIR/phases/"*"-$PHASE-"* 2>/dev/null | head -1) || { echo "Phase $PHASE not found" >&2; exit 1; }
|
|
29
|
+
PADDED_PHASE=$(printf "%02d" "$(echo "$PHASE" | grep -oE '^[0-9]+' | sed 's/^0*//')")
|
|
30
|
+
PHASE_SLUG=$(basename "$PHASE_DIR")
|
|
31
|
+
mapfile -t ALL_PLANS < <(ls "$PHASE_DIR"/${PADDED_PHASE}-*-PLAN.md 2>/dev/null | sort)
|
|
32
|
+
|
|
33
|
+
# Pick target plan
|
|
34
|
+
if [ -n "$PLAN" ]; then
|
|
35
|
+
TARGET_PLAN="$PHASE_DIR/${PADDED_PHASE}-$PLAN-PLAN.md"
|
|
36
|
+
else
|
|
37
|
+
for p in "${ALL_PLANS[@]}"; do
|
|
38
|
+
[ ! -f "${p/-PLAN.md/-SUMMARY.md}" ] && { TARGET_PLAN="$p"; break; }
|
|
39
|
+
done
|
|
40
|
+
fi
|
|
41
|
+
[ -z "$TARGET_PLAN" ] || [ ! -f "$TARGET_PLAN" ] && { echo "No unfinished PLAN.md" >&2; exit 1; }
|
|
42
|
+
|
|
43
|
+
PLAN_NUM=$(basename "$TARGET_PLAN" | sed -E "s/^${PADDED_PHASE}-([0-9]+)-.*/\1/")
|
|
44
|
+
EXPECTED_SUMMARY="${TARGET_PLAN/-PLAN.md/-SUMMARY.md}"
|
|
45
|
+
COMMIT_COUNT=$(git log --oneline --all --grep="${PADDED_PHASE}-${PLAN_NUM}" 2>/dev/null | wc -l | tr -d ' ')
|
|
46
|
+
SUMMARY_EXISTS=$([ -f "$EXPECTED_SUMMARY" ] && echo true || echo false)
|
|
47
|
+
PARTIAL_PLAN=$([ "$COMMIT_COUNT" -gt 0 ] && [ "$SUMMARY_EXISTS" = false ] && echo true || echo false)
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
**If `PARTIAL_PLAN=true`** → return `## Partial Plan Detected` to parent and STOP. Do not silently overwrite. User decides: resume summary-write, rollback, or investigate.
|
|
51
|
+
|
|
52
|
+
**2. Record start time.** `PLAN_START_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ")` · `PLAN_START_EPOCH=$(date +%s)`
|
|
53
|
+
|
|
54
|
+
**3. Parse plan structure.** `grep -cE '^\s*<task' "$PLAN_PATH"` for task count; `grep -nE 'type="checkpoint|<acceptance_criteria>'` for hotspots. Execute all tasks yourself sequentially — no sub-subagent dispatch.
|
|
55
|
+
|
|
56
|
+
**3.5. Seed pi-todo (cross-extension, optional).** If the `todo_update` tool is available in this session (the `pi-todo` extension is installed), call it NOW with one TodoItem per `<task>` from the plan, all `status: "pending"` with `activeForm` set to the present-continuous form of the task. Then set the first task to `in_progress` before starting work. This gives the user a live checklist in the footer. Clear the list (`todo_update({todos: []})`) after the SUMMARY is committed (step 12) when the plan is fully done.
|
|
57
|
+
|
|
58
|
+
**4. Load the plan as contract.** Read PLAN.md fully. **If `<interfaces>` block exists → use those types directly, don't re-read source files. If per-task `<read_first>` exists → read every listed file BEFORE any edit (not optional — ground truth).**
|
|
59
|
+
|
|
60
|
+
**5. Execute tasks in order.** Per task:
|
|
61
|
+
|
|
62
|
+
1. **Read first** — open every `<read_first>` file.
|
|
63
|
+
2. **Implement** — minimal correct change, follow project patterns. No speculative scaffolding. No `.soly/rules/` edits.
|
|
64
|
+
3. **Verify acceptance criteria (HARD GATE):**
|
|
65
|
+
- Run the grep/file-check/CLI for each criterion in `<acceptance_criteria>`.
|
|
66
|
+
- Log PASS/FAIL with output. If ANY fails → fix immediately, re-run ALL.
|
|
67
|
+
- Loop until all pass. If can't pass after 2 fix attempts → log as deviation. **Do NOT silently skip.**
|
|
68
|
+
4. **Run `<verification>`** commands (lint, typecheck, scoped tests).
|
|
69
|
+
5. **Commit per task:**
|
|
70
|
+
```bash
|
|
71
|
+
git add <files>
|
|
72
|
+
git commit -m "<type>(${PADDED_PHASE}-${PLAN_NUM}): <task summary>"
|
|
73
|
+
```
|
|
74
|
+
`<type>` ∈ `feat | fix | refactor | test | chore | docs`. Track commit hash for summary.
|
|
75
|
+
6. **On `type="checkpoint:*"`** → STOP, return Checkpoint block (step 6). Do NOT continue.
|
|
76
|
+
7. **On `type="tdd"`** → RED (failing test, `test(...)`) → GREEN (impl, `feat(...)`) → REFACTOR (`refactor(...)`). Tests MUST fail before impl, MUST pass after.
|
|
77
|
+
|
|
78
|
+
**6. Checkpoint protocol** (when you hit `type="checkpoint:*"` or auth gate — see step 7):
|
|
79
|
+
|
|
80
|
+
Can't talk to user directly. Stop, return structured block, parent relays.
|
|
81
|
+
|
|
82
|
+
```
|
|
83
|
+
## Checkpoint Reached — Phase <P>, Plan <N>
|
|
84
|
+
**Type:** <human-verify|decision|human-action>
|
|
85
|
+
**Task:** <n> — <name> **Progress:** <x>/<y>
|
|
86
|
+
|
|
87
|
+
### Completed so far
|
|
88
|
+
- Task 1: <name> (commit <hash>)
|
|
89
|
+
- ...
|
|
90
|
+
|
|
91
|
+
### Checkpoint Content
|
|
92
|
+
<type-specific body>
|
|
93
|
+
|
|
94
|
+
### What I Need From You
|
|
95
|
+
<"approved" | "select: <option-id>" | "done" | <question>>
|
|
96
|
+
|
|
97
|
+
### State Preserved At
|
|
98
|
+
`<phase_dir>/.execute-checkpoint.json`
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
| Type | Body | Resume signal |
|
|
102
|
+
|---|---|---|
|
|
103
|
+
| `human-verify` (90%) | What was built + verification steps (commands/URLs) + expected | "approved" or specific issues |
|
|
104
|
+
| `decision` (9%) | Decision + context + 2–3 options with pros/cons | "select: <option-id>" |
|
|
105
|
+
| `human-action` (1%) | What was automated + ONE manual step + verify plan | "done" |
|
|
106
|
+
|
|
107
|
+
**State preservation:** write `${PHASE_DIR}/.execute-checkpoint.json` with `completed_tasks[]`, `commit_hashes{}`, `next_task_index` for deterministic resume. Delete on clean close-out.
|
|
108
|
+
|
|
109
|
+
**7. Authentication gates** are NOT failures — expected interaction points. Indicators: "Not authenticated", 401/403, "Please run {tool} login", "Set {ENV_VAR}". Protocol: recognize → STOP → write `.execute-checkpoint.json` with `type: "human-action"` + exact auth steps → return Checkpoint block → wait. Document in SUMMARY.md under `## Authentication Gates`, not as a deviation.
|
|
110
|
+
|
|
111
|
+
**8. Deviation rules:**
|
|
112
|
+
|
|
113
|
+
| Rule | Trigger | Action |
|
|
114
|
+
|---|---|---|
|
|
115
|
+
| 1 | Bug found while implementing | Auto-fix, test, verify, track as deviation |
|
|
116
|
+
| 2 | Missing critical implementation detail | Auto-fix, test, verify, track as deviation |
|
|
117
|
+
| 3 | Blocker in adjacent code | Auto-fix only if scope strictly bounded; else Rule 4 |
|
|
118
|
+
| 4 | Architectural change, new dep, scope expansion | **STOP** — write `.execute-checkpoint.json` `type: "decision"`, return to parent. NEVER silently decide. |
|
|
119
|
+
|
|
120
|
+
- **Scope boundary:** do NOT auto-fix pre-existing issues unrelated to current task — note in SUMMARY "Out-of-Scope Issues".
|
|
121
|
+
- **Fix attempt limit:** max 3 retries per deviation before Rule 4.
|
|
122
|
+
- **Priority:** Rule 4 (STOP) > Rules 1–3 (auto) > unsure → Rule 4.
|
|
123
|
+
|
|
124
|
+
**9. Pre-commit hook failure:**
|
|
125
|
+
1. `git commit` fails with hook error. 2. Read error — names hook + what failed. 3. Fix (type/lint/secret). 4. `git add` fixed. 5. Retry. 6. Budget 1–2 cycles per commit. If still failing → `type: "human-action"` checkpoint with hook output.
|
|
126
|
+
**Do NOT use `--no-verify`** unless project's `.soly/docs/` or ROADMAP.md explicitly opts out.
|
|
127
|
+
|
|
128
|
+
**10. Verification failure gate:** 1st retry (hooks flake) → 2nd retry (fix obvious cause) → 3rd retry (apply deviation rules) → 3+ fails → `type: "decision"` checkpoint, STOP.
|
|
129
|
+
|
|
130
|
+
**11. Generate USER-SETUP** (only if PLAN.md frontmatter has `user_setup:`):
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
grep -A 50 "^user_setup:" "$PLAN_PATH" | head -50
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Write `${PHASE_DIR}/${PADDED_PHASE}-${PLAN_NUM}-USER-SETUP.md`:
|
|
137
|
+
|
|
138
|
+
```markdown
|
|
139
|
+
---
|
|
140
|
+
phase: <P> plan: <N> status: Incomplete generated: <ISO8601>
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
# User Setup — Phase <P> Plan <N>
|
|
144
|
+
|
|
145
|
+
## <service-name>
|
|
146
|
+
- **Env vars:** `<VAR>` — <description, where to get it>
|
|
147
|
+
- **Account setup:** <link + checklist>
|
|
148
|
+
- **Dashboard config:** <link + steps>
|
|
149
|
+
- **Local dev notes:** <how to verify locally>
|
|
150
|
+
- **Verification:** `<command>` should print <expected>
|
|
151
|
+
|
|
152
|
+
## Verification
|
|
153
|
+
Run all verification commands. When all pass, change `status:` to `Complete`.
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
**12. Create SUMMARY.md** (atomic — NO narrative between `write` and `git commit`):
|
|
157
|
+
|
|
158
|
+
```markdown
|
|
159
|
+
---
|
|
160
|
+
phase: <P> plan: <N> title: "<from PLAN>" status: complete
|
|
161
|
+
duration: "<Xh Ym>" started: <ISO> completed: <ISO>
|
|
162
|
+
tasks_completed: <N> files_modified: <N>
|
|
163
|
+
tags: [<from PLAN frontmatter>]
|
|
164
|
+
key-files: { created: [<paths>], modified: [<paths>] }
|
|
165
|
+
key-decisions: [<d1>, <d2>]
|
|
166
|
+
requirements-completed: [<from PLAN frontmatter, verbatim>]
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
# Phase <P> Plan <N>: <Title> Summary
|
|
170
|
+
|
|
171
|
+
<one-line substantive — e.g. "JWT auth with refresh rotation using jose", not "Authentication implemented">
|
|
172
|
+
|
|
173
|
+
## Duration <duration> (<start> → <end>)
|
|
174
|
+
|
|
175
|
+
## Tasks
|
|
176
|
+
- Task 1: <name> (commit <hash>)
|
|
177
|
+
- ...
|
|
178
|
+
|
|
179
|
+
## Deviations from Plan
|
|
180
|
+
If none: `None — plan executed exactly as written.`
|
|
181
|
+
Per deviation:
|
|
182
|
+
```
|
|
183
|
+
**[Rule N — <Cat>] <Title>**
|
|
184
|
+
- Found during: Task <X>
|
|
185
|
+
- Issue: <what> Fix: <what you did>
|
|
186
|
+
- Files: <paths> Verification: <how> Commit: <hash>
|
|
187
|
+
```
|
|
188
|
+
End with: `**Total deviations:** <N> auto-fixed (Rules 1–3). **Out-of-scope:** <N>. **Escalated:** <N>.`
|
|
189
|
+
|
|
190
|
+
## Authentication Gates
|
|
191
|
+
<none or per-gate entries>
|
|
192
|
+
|
|
193
|
+
## Out-of-Scope Issues
|
|
194
|
+
<issues not in this plan's scope — future phase>
|
|
195
|
+
|
|
196
|
+
## Verification
|
|
197
|
+
<output of <verification> block, or "all criteria passed; see commits">
|
|
198
|
+
|
|
199
|
+
## Files Touched - Created: <n> - Modified: <n>
|
|
200
|
+
|
|
201
|
+
## Next
|
|
202
|
+
<if more plans: "Ready for plan <N+1> — re-invoke `soly execute-plan <P>`">
|
|
203
|
+
<if last: "Phase <P> complete. Consider `soly plan <P+1>` or `soly pause`.">
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
git add "$EXPECTED_SUMMARY"
|
|
208
|
+
git commit -m "chore(${PADDED_PHASE}-${PLAN_NUM}): complete plan <N>"
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
**13. Update STATE.md** (read + edit, no CLI):
|
|
212
|
+
- Bump `current_plan` in "Current Position".
|
|
213
|
+
- Add `key-decisions` to "Decisions" table (skip if trivial).
|
|
214
|
+
- Update `last_updated`.
|
|
215
|
+
- Keep < 150 lines — archive long-form to `.soly/DECISIONS-INDEX.md` if it grows.
|
|
216
|
+
|
|
217
|
+
**Update ROADMAP.md** — phase's progress row: increment completed plan count; status → `In Progress` (more plans) or `Complete` (last) with date.
|
|
218
|
+
|
|
219
|
+
**14. Update requirements** (only if PLAN.md has `requirements:`):
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
REQUIREMENTS=$(grep -A1 "^requirements:" "$PLAN_PATH" | tail -1 | sed -E 's/.*\[([^]]+)\].*/\1/' | tr ',' ' ')
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
For each ID, find line in `.soly/REQUIREMENTS.md`, flip status to `Complete`.
|
|
226
|
+
|
|
227
|
+
**15. Return:**
|
|
228
|
+
|
|
229
|
+
```
|
|
230
|
+
## Plan Complete — Phase <P> Plan <N>
|
|
231
|
+
**Title:** <t> **Duration:** <d> **Tasks:** <n> **Files:** <m> **Deviations:** <n> auto / <m> escalated
|
|
232
|
+
<if USER_SETUP>
|
|
233
|
+
## ⚠ User Setup Required
|
|
234
|
+
<path> generated with <n> service(s) — complete before next plan's external checks.
|
|
235
|
+
</if>
|
|
236
|
+
### Next
|
|
237
|
+
<if more plans: "Re-invoke `soly execute-plan <P>` for plan <N+1>.">
|
|
238
|
+
<if last: "Phase <P> complete. Try `soly plan <P+1>` or `soly pause`.">
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
</process>
|
|
242
|
+
|
|
243
|
+
<hard_rules>
|
|
244
|
+
- No `.soly/rules/` edits. No `.soly/docs/` edits without explicit user decision in conversation.
|
|
245
|
+
- No subagents (you ARE one). `maxSubagentDepth: 1` is enforced.
|
|
246
|
+
- **Never skip `<acceptance_criteria>` HARD GATE.** Not optional.
|
|
247
|
+
- **Never emit narrative between SUMMARY `write` and `git commit`** (truncation is a known failure mode).
|
|
248
|
+
- **Never silently make architectural decisions** — use Rule 4 + checkpoint.
|
|
249
|
+
- Commit messages: Conventional Commits 1.0.0. Per-task: `<type>(<plan-id>): <summary>`.
|
|
250
|
+
- Return: SUMMARY path, plan summary, deviation count, next step.
|
|
251
|
+
</hard_rules>
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# Execute Task
|
|
2
|
+
|
|
3
|
+
<purpose>Execute ONE task (atomic unit — a feature slice, one endpoint, one page, one contract wire). Produce SUMMARY.md. Tasks live under `.soly/features/<feature>/tasks/<task-id>/` with PLAN.md as the contract.</purpose>
|
|
4
|
+
|
|
5
|
+
<path_discipline>
|
|
6
|
+
**All soly-managed files live under `.soly/`.** Never write PLAN.md, SUMMARY.md, iteration files, or handoffs to the project root. Task files go in `.soly/features/<feature>/tasks/<task-id>/`. Use absolute paths — 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, the feature README, prior task SUMMARYs, and the current task PLAN. Read it FIRST.
|
|
9
|
+
</path_discipline>
|
|
10
|
+
|
|
11
|
+
<read_first>`.soly/STATE.md` · `.soly/docs/` (INTENT, 0-point) · `.soly/features/<feature>/README.md` · `PLAN.md` (the contract) · `.soly/contracts/*` if PLAN.md references it. If `.soly/features/` or task dir missing → error + stop, do not invent paths.</read_first>
|
|
12
|
+
|
|
13
|
+
<task_frontmatter>
|
|
14
|
+
PLAN.md frontmatter (executor must respect all fields; **flag** incomplete ones in your report, don't silently fill):
|
|
15
|
+
|
|
16
|
+
```yaml
|
|
17
|
+
---
|
|
18
|
+
id: auth-be-login-a3f9 # slug-4hex, must match the directory name
|
|
19
|
+
kind: be # be | fe | infra | docs | integration
|
|
20
|
+
feature: auth # parent feature
|
|
21
|
+
status: ready # ready | in-progress | blocked | done
|
|
22
|
+
priority: high # high | medium | low
|
|
23
|
+
parallelizable: true
|
|
24
|
+
depends-on: [] # list of task ids; each must be status: done
|
|
25
|
+
---
|
|
26
|
+
```
|
|
27
|
+
</task_frontmatter>
|
|
28
|
+
|
|
29
|
+
<atomic_close_out>
|
|
30
|
+
Only legal order: `production-code commit(s) → SUMMARY.md commit → PLAN.md frontmatter status: done → report`.
|
|
31
|
+
Once production commits exist, returning without a committed SUMMARY is an illegal partial-task state.
|
|
32
|
+
</atomic_close_out>
|
|
33
|
+
|
|
34
|
+
<process>
|
|
35
|
+
|
|
36
|
+
**1. Verify ready.** `TASK_DIR` from worker args. Parse `status` from frontmatter:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
TASK_DIR="$1"
|
|
40
|
+
[ -d "$TASK_DIR" ] && [ -f "$TASK_DIR/PLAN.md" ] || { echo "task dir or PLAN.md missing" >&2; exit 1; }
|
|
41
|
+
STATUS=$(awk '/^---$/{c++; next} c==1{print}' "$TASK_DIR/PLAN.md" | grep -E '^status:' | awk '{print $2}' | tr -d '"')
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
- `status` is `ready` (or `in-progress` for resume).
|
|
45
|
+
- Every task in `depends-on:` has `status: done` (its SUMMARY.md is committed).
|
|
46
|
+
|
|
47
|
+
If not → return `## Blocker` to parent, stop. Do NOT start a blocked task.
|
|
48
|
+
|
|
49
|
+
**2. Read intent + feature context.** **0-POINT CHECK** — the iteration context file (path given in the task prompt) already contains the intent docs as a summary, the feature README, prior task SUMMARYs, and the current task PLAN. Use that. If intent and PLAN.md conflict, flag it. Read `.soly/contracts/*` (if it exists) only if the task touches API surfaces.
|
|
50
|
+
|
|
51
|
+
**3. Execute** with standard worker self-audit:
|
|
52
|
+
|
|
53
|
+
1. Write code.
|
|
54
|
+
2. Run build / typecheck / lint — **0 warnings**.
|
|
55
|
+
3. Cross-check diff against `.soly/rules/coding/*` (or `.editorconfig`).
|
|
56
|
+
4. **Rule gap?** Invoke the project's rule-authoring skill (`analyzer-coach` or equivalent) — it proposes an `.editorconfig` entry, a coding-rule doc addition, or a custom-analyzer rule. Loop until clean, max 3 iterations.
|
|
57
|
+
5. Commit production-code changes (one or more commits).
|
|
58
|
+
|
|
59
|
+
Do NOT skip the audit. "I think I'm fine" is not a check.
|
|
60
|
+
|
|
61
|
+
**4. Write `SUMMARY.md`** at the absolute path `${TASK_DIR}/SUMMARY.md` (the task dir is the iteration context's `task` frontmatter field, plus the feature subdir). Never a bare relative name:
|
|
62
|
+
|
|
63
|
+
```markdown
|
|
64
|
+
---
|
|
65
|
+
id: <task-id> title: "<from PLAN>" status: done
|
|
66
|
+
started: <ISO> completed: <ISO> duration: "<Xm>"
|
|
67
|
+
feature: <feature>
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
# <task-id> Summary
|
|
71
|
+
|
|
72
|
+
<1–2 sentences: what was done>
|
|
73
|
+
|
|
74
|
+
## Changed files
|
|
75
|
+
- `<path>` — <what>
|
|
76
|
+
|
|
77
|
+
## Validation
|
|
78
|
+
- `<cmd>` → exit 0 (output: ...)
|
|
79
|
+
- `<cmd>` → exit 0 (output: ...)
|
|
80
|
+
|
|
81
|
+
## Rule gaps discovered
|
|
82
|
+
<none, or per-gap: which skill proposed, which rule added>
|
|
83
|
+
|
|
84
|
+
## Decisions needing approval
|
|
85
|
+
<none, or per-decision: rationale + recommendation>
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**5. Close out** — atomic, do NOT skip or reorder:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
cd "$PROJECT_ROOT" && git add "$TASK_DIR/SUMMARY.md"
|
|
92
|
+
git commit -m "chore(tasks): summary for <task-id>"
|
|
93
|
+
cd "$PROJECT_ROOT" && git add "$TASK_DIR/PLAN.md" # flip status → done
|
|
94
|
+
git commit -m "chore(tasks): mark <task-id> done"
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
You may combine into one commit, but the SUMMARY must be on disk before the frontmatter flip. **Do not flip status without a committed SUMMARY.**
|
|
98
|
+
|
|
99
|
+
**6. Report** to parent: task id, SUMMARY path, commits, validation results, decisions needing approval.
|
|
100
|
+
|
|
101
|
+
</process>
|
|
102
|
+
|
|
103
|
+
<hard_rules>
|
|
104
|
+
- No `.soly/rules/` edits. No subagents (you ARE one).
|
|
105
|
+
- No starting tasks with un-`done` `depends-on:`.
|
|
106
|
+
- If rule gap → add via the rule-authoring skill. **No silent workarounds** (`#pragma`, `severity = none`).
|
|
107
|
+
- Return: changed files, commands + exit codes, validation evidence, surprises, decisions needing parent approval.
|
|
108
|
+
</hard_rules>
|
|
109
|
+
|
|
110
|
+
<interactive_rules_out_of_scope>
|
|
111
|
+
- `interactive: true` rules (describe the conversation, not execution). You're in execute mode, not discuss — surface genuine blockers in the report, don't ask the user.
|
|
112
|
+
</interactive_rules_out_of_scope>
|
|
113
|
+
|
|
114
|
+
<dual_mode_note>
|
|
115
|
+
Project may also have `.soly/phases/` (phase-based layout, distinct from task-based). You are only responsible for this task. Don't touch phases. Don't modify ROADMAP.md or STATE.md beyond what your close-out requires (typically nothing for tasks — the parent updates those).
|
|
116
|
+
</dual_mode_note>
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# Pause Work
|
|
2
|
+
|
|
3
|
+
<purpose>Create `.soly/HANDOFF.json` (machine-readable) and a `.continue-here.md` (human-readable) to preserve work state across sessions. `soly resume` consumes both.</purpose>
|
|
4
|
+
|
|
5
|
+
<read_first>.soly/STATE.md (current position) · the most recent `.soly/phases/*/SUMMARY.md` if any</read_first>
|
|
6
|
+
|
|
7
|
+
<process>
|
|
8
|
+
|
|
9
|
+
**1. Detect context.** First match wins; nothing detectable → `.soly/.continue-here.md` (note ambiguity in `<current_state>`).
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
phase=$(ls -t .soly/phases/*/PLAN.md 2>/dev/null | head -1)
|
|
13
|
+
phase_slug=$(echo "$phase" | grep -oP 'phases/\K[^/]+')
|
|
14
|
+
spike=$(ls -td .soly/spikes/*/ 2>/dev/null | head -1)
|
|
15
|
+
sketch=$(ls -td .soly/sketches/*/ 2>/dev/null | head -1)
|
|
16
|
+
deliberation=$(ls .soly/deliberations/*.md 2>/dev/null | head -1)
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
| detected | handoff path |
|
|
20
|
+
|---|---|
|
|
21
|
+
| phase_slug | `.soly/phases/<phase_slug>/.continue-here.md` |
|
|
22
|
+
| spike | `.soly/spikes/<spike_slug>/.continue-here.md` |
|
|
23
|
+
| sketch | `.soly/sketches/<sketch_slug>/.continue-here.md` |
|
|
24
|
+
| deliberation | `.soly/deliberations/.continue-here.md` |
|
|
25
|
+
| (notes only) | `.soly/.continue-here.md` |
|
|
26
|
+
|
|
27
|
+
**2. Gather state.** Walk the conversation + recent diffs. Collect: current position (phase/plan/task + paths), work done this session (artifacts, not aspirations), work remaining, decisions (only those future-you must not re-litigate), blockers, human actions pending (API keys, approvals, manual tests), background processes, uncommitted files (`git status --porcelain`), and blocking constraints (anti-patterns discovered through actual failure — each tagged `blocking` or `advisory`).
|
|
28
|
+
|
|
29
|
+
If anything is ambiguous, return a `## Clarifications Needed` block — do not invent.
|
|
30
|
+
|
|
31
|
+
**3. Check for false completions.** `grep -l "To be filled\|placeholder\|TBD" .soly/phases/*/*.md 2>/dev/null` — report matches as incomplete.
|
|
32
|
+
|
|
33
|
+
**4. Write `.soly/HANDOFF.json`.** Timestamp via `date -u +"%Y-%m-%dT%H:%M:%SZ"` (no SDK).
|
|
34
|
+
|
|
35
|
+
```json
|
|
36
|
+
{
|
|
37
|
+
"version": "1.0",
|
|
38
|
+
"timestamp": "<ts>",
|
|
39
|
+
"phase": <n|null>, "phase_name": "<str|null>", "phase_dir": "<path|null>",
|
|
40
|
+
"plan": <n|null>, "task": <n|null>, "total_tasks": <n|null>,
|
|
41
|
+
"status": "paused",
|
|
42
|
+
"completed_tasks": [{"id": 1, "name": "<n>", "status": "done", "commit": "<hash>"},
|
|
43
|
+
{"id": 2, "name": "<n>", "status": "in_progress", "progress": "<what>"}],
|
|
44
|
+
"remaining_tasks": [{"id": 3, "name": "<n>", "status": "not_started"}],
|
|
45
|
+
"blockers": [{"description": "<x>", "type": "technical|human_action|external", "workaround": "<if any>"}],
|
|
46
|
+
"human_actions_pending": [{"action": "<x>", "context": "<why>", "blocking": true}],
|
|
47
|
+
"decisions": [{"decision": "<x>", "rationale": "<why>", "phase": <n|null>}],
|
|
48
|
+
"uncommitted_files": [],
|
|
49
|
+
"next_action": "<specific first action when resuming>",
|
|
50
|
+
"context_notes": "<mental state, approach>"
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Use JSON `null`, never the string `"null"`.
|
|
55
|
+
|
|
56
|
+
**5. Write `<handoff-path>/.continue-here.md`:**
|
|
57
|
+
|
|
58
|
+
```markdown
|
|
59
|
+
---
|
|
60
|
+
context: <phase|spike|sketch|deliberation|research|default>
|
|
61
|
+
phase: <slug-or-empty> task: <n> total_tasks: <m>
|
|
62
|
+
status: in_progress last_updated: <ts>
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
# BLOCKING CONSTRAINTS — read first
|
|
66
|
+
> Each was discovered through actual failure. Acknowledge before proceeding.
|
|
67
|
+
- [ ] CONSTRAINT: <name> — <what> — <structural mitigation>
|
|
68
|
+
|
|
69
|
+
_If none, remove this section._
|
|
70
|
+
|
|
71
|
+
## Critical Anti-Patterns
|
|
72
|
+
| Pattern | What + how it manifested | Severity | Structural prevention |
|
|
73
|
+
|---|---|---|---|
|
|
74
|
+
| <name> | <desc> | blocking | <mechanism — not just acknowledgment> |
|
|
75
|
+
| <name> | <desc> | advisory | <guidance> |
|
|
76
|
+
|
|
77
|
+
`blocking` rows are enforced by discuss-phase / execute-phase as a mandatory understanding check.
|
|
78
|
+
|
|
79
|
+
<current_state><immediate context, paths, last commits></current_state>
|
|
80
|
+
|
|
81
|
+
<completed_work>
|
|
82
|
+
- Task 1: <name> - done (commit <h>)
|
|
83
|
+
- Task 2: <name> - in_progress, <what's done>
|
|
84
|
+
</completed_work>
|
|
85
|
+
|
|
86
|
+
<remaining_work>
|
|
87
|
+
- Task 3: <what's left>
|
|
88
|
+
- Task 4: not started
|
|
89
|
+
</remaining_work>
|
|
90
|
+
|
|
91
|
+
<decisions_made>
|
|
92
|
+
- <decision>: <rationale>
|
|
93
|
+
</decisions_made>
|
|
94
|
+
|
|
95
|
+
<blockers>
|
|
96
|
+
- <blocker>: <status/workaround>
|
|
97
|
+
</blockers>
|
|
98
|
+
|
|
99
|
+
## Required Reading (in order)
|
|
100
|
+
1. <doc> — <why>
|
|
101
|
+
2. `.soly/METHODOLOGY.md` if it exists — project lenses
|
|
102
|
+
|
|
103
|
+
## Infrastructure State
|
|
104
|
+
- <service/env>: <state>
|
|
105
|
+
|
|
106
|
+
## Pre-Execution Critique Required
|
|
107
|
+
<!-- only if pausing between design and execution -->
|
|
108
|
+
- Design artifact: <path>
|
|
109
|
+
- Critique focus: <questions>
|
|
110
|
+
- Gate: do NOT execute until critique complete + design revised
|
|
111
|
+
|
|
112
|
+
<context><mental state, plan, what you were thinking></context>
|
|
113
|
+
<next_action>Start with: <specific first action></next_action>
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Specific enough that a fresh worker can resume without re-deriving from git history.
|
|
117
|
+
|
|
118
|
+
**6. Commit:**
|
|
119
|
+
```bash
|
|
120
|
+
git add .soly/HANDOFF.json <handoff-md-path>
|
|
121
|
+
git commit -m "chore(soly): pause work — create handoff"
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
**7. Return:**
|
|
125
|
+
```
|
|
126
|
+
Handoff created:
|
|
127
|
+
- .soly/HANDOFF.json
|
|
128
|
+
- <handoff-md-path>
|
|
129
|
+
State: <context>, <location>, task <x>/<m>, in_progress, <n> blockers (<m> human)
|
|
130
|
+
Resume: `soly resume`
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
</process>
|
|
134
|
+
|
|
135
|
+
<hard_rules>
|
|
136
|
+
- No production code. Handoff only.
|
|
137
|
+
- A summary with `TBD`/`placeholder`/`To be filled` is incomplete — report it.
|
|
138
|
+
- `null` is JSON `null`, not the string `"null"`.
|
|
139
|
+
- Do not modify `.soly/rules/`. Do not run subagents (you ARE one).
|
|
140
|
+
- Commit message: `chore(soly): pause work — create handoff`.
|
|
141
|
+
- Return: paths, state summary, blocker count, `soly resume` command.
|
|
142
|
+
</hard_rules>
|