pi-soly 1.13.4 → 1.14.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 +9 -10
- package/artifact/index.ts +3 -3
- package/artifact/render.ts +2 -2
- package/ask/README.md +3 -1
- package/ask/index.ts +16 -2
- package/codemap.ts +2 -2
- package/commands.ts +40 -67
- package/config.ts +20 -12
- package/core.ts +16 -18
- package/docs.ts +4 -4
- package/index.ts +39 -29
- package/init.ts +7 -7
- package/intent.ts +12 -12
- package/iteration.ts +12 -12
- package/mcp/ext-apps-bridge.ts +76 -0
- package/mcp/index.ts +5 -0
- package/mcp/metadata-cache.ts +1 -1
- package/mcp/tool-metadata.ts +1 -1
- package/mcp/ui-resource-handler.ts +4 -4
- package/mcp/ui-server.ts +1 -1
- package/notification.ts +1 -1
- package/notifications-log.ts +2 -2
- package/nudge.ts +41 -6
- package/package.json +1 -2
- package/skills/soly-framework/SKILL.md +34 -42
- package/status.ts +2 -2
- package/tools.ts +14 -14
- package/util.ts +2 -2
- package/visual/welcome.ts +3 -3
- package/workflows/execute.ts +16 -16
- package/workflows/index.ts +4 -14
- package/workflows/inspect.ts +16 -15
- package/workflows/parser.ts +2 -3
- package/workflows/pause.ts +5 -5
- package/workflows/planning.ts +18 -18
- package/workflows/quick.ts +7 -7
- package/workflows/resume.ts +14 -14
- package/workflows-data/discuss-phase.md +9 -9
- package/workflows-data/execute-phase.md +4 -4
- package/workflows-data/execute-plan.md +8 -8
- package/workflows-data/execute-task.md +7 -7
- package/workflows-data/pause-work.md +18 -18
- package/workflows-data/plan-phase.md +7 -7
- package/workflows-data/plan-task.md +18 -18
- package/migrate.ts +0 -258
- package/workflows/migrate.ts +0 -85
package/workflows/parser.ts
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
/** Verbs currently supported by the workflow handlers. */
|
|
19
19
|
export type WorkflowVerb =
|
|
20
20
|
| "execute" | "pause" | "compact" | "resume" | "status" | "log" | "diff"
|
|
21
|
-
| "plan" | "discuss" | "help" | "doctor" | "iterations" | "phase" | "todos" | "verify"
|
|
21
|
+
| "plan" | "discuss" | "help" | "doctor" | "iterations" | "phase" | "todos" | "verify";
|
|
22
22
|
|
|
23
23
|
export interface SolyCommand {
|
|
24
24
|
verb: WorkflowVerb;
|
|
@@ -67,8 +67,7 @@ export function parseSolyCommand(text: string): SolyCommand | null {
|
|
|
67
67
|
verb !== "iterations" &&
|
|
68
68
|
verb !== "phase" &&
|
|
69
69
|
verb !== "todos" &&
|
|
70
|
-
verb !== "verify"
|
|
71
|
-
verb !== "migrate"
|
|
70
|
+
verb !== "verify"
|
|
72
71
|
) {
|
|
73
72
|
return null;
|
|
74
73
|
}
|
package/workflows/pause.ts
CHANGED
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
//
|
|
8
8
|
// Like execute, we transform the input into a detailed LLM instruction that
|
|
9
9
|
// walks the LLM through the soly pause-work workflow. The LLM produces both:
|
|
10
|
-
// - .
|
|
11
|
-
// - .
|
|
10
|
+
// - .agents/HANDOFF.json (machine-readable state for resume)
|
|
11
|
+
// - .agents/.continue-here.md (human-readable context)
|
|
12
12
|
//
|
|
13
13
|
// For `compact`, we additionally call ctx.compact() AFTER the handoff files
|
|
14
14
|
// are written — but we still let the LLM drive the handoff generation, since
|
|
@@ -94,7 +94,7 @@ export function buildPauseTransform(
|
|
|
94
94
|
return {
|
|
95
95
|
handled: true,
|
|
96
96
|
transformedText:
|
|
97
|
-
`soly: no .
|
|
97
|
+
`soly: no .agents/ directory found in cwd (${state.solyDir || "<cwd>"}) — nothing to pause.\n` +
|
|
98
98
|
`If you wanted to start a soly project, see the soly quickstart.`,
|
|
99
99
|
triggerCompact: false,
|
|
100
100
|
};
|
|
@@ -122,7 +122,7 @@ export function buildPauseTransform(
|
|
|
122
122
|
|
|
123
123
|
${actionLine}
|
|
124
124
|
|
|
125
|
-
Current position (from .
|
|
125
|
+
Current position (from .agents/STATE.md):
|
|
126
126
|
${state.position
|
|
127
127
|
? ` phase: ${state.position.phase}\n plan: ${state.position.plan}\n status: ${state.position.status}`
|
|
128
128
|
: " (no position set — likely pre-planning or paused at a milestone boundary)"}
|
|
@@ -139,7 +139,7 @@ Follow the workflow below VERBATIM — these are the user-approved soly instruct
|
|
|
139
139
|
${workflow}
|
|
140
140
|
=== END WORKFLOW ===
|
|
141
141
|
|
|
142
|
-
After you write both .
|
|
142
|
+
After you write both .agents/HANDOFF.json and .agents/.continue-here.md, tell the user:
|
|
143
143
|
- where the files were written (absolute paths)
|
|
144
144
|
- the resume command: soly resume
|
|
145
145
|
- ${isCompact ? "session will be compacted at end of this turn" : "session state preserved as-is"}
|
package/workflows/planning.ts
CHANGED
|
@@ -67,7 +67,7 @@ export function buildPlanTransform(cmd: SolyCommand, state: SolyState): Planning
|
|
|
67
67
|
return {
|
|
68
68
|
handled: true,
|
|
69
69
|
transformedText:
|
|
70
|
-
`soly plan: no .
|
|
70
|
+
`soly plan: no .agents/ directory in cwd (${state.solyDir || "<cwd>"}) — cannot plan.\n` +
|
|
71
71
|
`Initialize a soly project first.`,
|
|
72
72
|
};
|
|
73
73
|
}
|
|
@@ -123,8 +123,8 @@ export function buildPlanTransform(cmd: SolyCommand, state: SolyState): Planning
|
|
|
123
123
|
**Iteration context file written:** \`${iter.relPath}\` (${iter.tokens} tokens, ${iter.bytes} bytes)
|
|
124
124
|
The planner reads this file first — it contains intent, STATE, ROADMAP row for this phase, phase CONTEXT, phase RESEARCH, and prior SUMMARYs.
|
|
125
125
|
|
|
126
|
-
**0-POINT CHECK — read .
|
|
127
|
-
These documents hold the project's INTENT — business context, design vision, what the user wants this app to be. Plans that ignore intent produce code that "works" but doesn't fit. If the plan would diverge from anything in .
|
|
126
|
+
**0-POINT CHECK — read .agents/docs/ first.**
|
|
127
|
+
These documents hold the project's INTENT — business context, design vision, what the user wants this app to be. Plans that ignore intent produce code that "works" but doesn't fit. If the plan would diverge from anything in .agents/docs/, surface that as a discussion point before committing to it.
|
|
128
128
|
|
|
129
129
|
Phase directory: ${phase.dir}
|
|
130
130
|
Current state: planCount=${phase.planCount}, context=${phase.contextExists}, research=${phase.researchExists}
|
|
@@ -155,11 +155,11 @@ ${workflow}
|
|
|
155
155
|
|
|
156
156
|
Hard rules:
|
|
157
157
|
- Do not write production code. Planning only.
|
|
158
|
-
- One task = one PLAN.md under .
|
|
158
|
+
- One task = one PLAN.md under .agents/phases/<NN>-<slug>/tasks/<task-id>/ (task id = <short-slug>-<4hex>).
|
|
159
159
|
- Each task PLAN.md starts with frontmatter: id, kind, status: ready, depends-on: [task ids], optional feature. The cross-task dependency graph must be acyclic.
|
|
160
160
|
- Each task PLAN needs requirements, must_haves.truths, must_haves.artifacts, must_haves.key_links.
|
|
161
|
-
- PATH DISCIPLINE: all task PLAN.md / phase CONTEXT.md / RESEARCH.md go under \`.
|
|
162
|
-
- Update .
|
|
161
|
+
- PATH DISCIPLINE: all task PLAN.md / phase CONTEXT.md / RESEARCH.md go under \`.agents/phases/<NN>-<slug>/\`. Never write to the project root.
|
|
162
|
+
- Update .agents/STATE.md Current Position at the end.
|
|
163
163
|
- Return: created task ids, the dependency order (which tasks are ready first), open questions.
|
|
164
164
|
\`
|
|
165
165
|
})
|
|
@@ -231,7 +231,7 @@ The planner reads this file first — it contains intent, STATE, the feature REA
|
|
|
231
231
|
**Inline plan summary (so you have the must-haves even before reading the file):**
|
|
232
232
|
${inlineSummary}
|
|
233
233
|
|
|
234
|
-
**0-POINT CHECK.** Re-read .
|
|
234
|
+
**0-POINT CHECK.** Re-read .agents/docs/ (intent) and .agents/features/${task.feature}/README.md (feature context) before refining the plan.
|
|
235
235
|
|
|
236
236
|
This task already has PLAN.md. Your job is to flesh it out / improve it based on intent and feature context — not to start from scratch.
|
|
237
237
|
|
|
@@ -265,7 +265,7 @@ Hard rules:
|
|
|
265
265
|
- Preserve the existing frontmatter (id, kind, feature, status, etc.) — only update if you find a bug.
|
|
266
266
|
- If you change the plan body materially, commit it as \`chore(tasks): refine plan <task-id>\`.
|
|
267
267
|
- If you only add small clarifications, no commit needed (or include in same commit).
|
|
268
|
-
- PATH DISCIPLINE: PLAN.md lives at \`.
|
|
268
|
+
- PATH DISCIPLINE: PLAN.md lives at \`.agents/features/<feature>/tasks/<id>/PLAN.md\`. Never write to the project root.
|
|
269
269
|
- Return: what changed, open questions, dependencies discovered.
|
|
270
270
|
\`
|
|
271
271
|
})
|
|
@@ -289,8 +289,8 @@ When the subagent returns, summarize what was refined. Do not execute — planni
|
|
|
289
289
|
return {
|
|
290
290
|
handled: true,
|
|
291
291
|
transformedText:
|
|
292
|
-
`soly plan: could not create .
|
|
293
|
-
`Create it manually: \`mkdir -p .
|
|
292
|
+
`soly plan: could not create .agents/features/${target.feature}/tasks/ (${(e as Error).message}). ` +
|
|
293
|
+
`Create it manually: \`mkdir -p .agents/features/${target.feature}/tasks/\``,
|
|
294
294
|
};
|
|
295
295
|
}
|
|
296
296
|
try {
|
|
@@ -305,8 +305,8 @@ When the subagent returns, summarize what was refined. Do not execute — planni
|
|
|
305
305
|
return {
|
|
306
306
|
handled: true,
|
|
307
307
|
transformedText:
|
|
308
|
-
`soly plan: created .
|
|
309
|
-
`Continue manually: \`touch .
|
|
308
|
+
`soly plan: created .agents/features/${target.feature}/tasks/ but failed to write README.md (${(e as Error).message}). ` +
|
|
309
|
+
`Continue manually: \`touch .agents/features/${target.feature}/README.md\``,
|
|
310
310
|
};
|
|
311
311
|
}
|
|
312
312
|
// Re-read state so the planner sees the new feature
|
|
@@ -331,13 +331,13 @@ When the subagent returns, summarize what was refined. Do not execute — planni
|
|
|
331
331
|
**Slug:** ${target.slug}
|
|
332
332
|
**Feature README:** ${featureDir}/README.md
|
|
333
333
|
|
|
334
|
-
**0-POINT CHECK.** Re-read .
|
|
334
|
+
**0-POINT CHECK.** Re-read .agents/docs/ (intent) and .agents/features/${target.feature}/README.md (feature context) before planning.
|
|
335
335
|
|
|
336
336
|
**Step 1 — generate task ID.** The task ID is \`<slug>-<4hex>\` (e.g. \`${target.slug}-a3f9\`). Generate 4 lowercase hex chars (use \`crypto.randomBytes(2).toString('hex')\` in node, or any 4-char [0-9a-f]{4} string if you don't have a shell handy).
|
|
337
337
|
|
|
338
338
|
**Step 2 — create the dir:**
|
|
339
339
|
\`\`\`
|
|
340
|
-
mkdir -p .
|
|
340
|
+
mkdir -p .agents/features/${target.feature}/tasks/<id>
|
|
341
341
|
\`\`\`
|
|
342
342
|
|
|
343
343
|
**Step 3 — write PLAN.md** with the frontmatter below + the plan body.
|
|
@@ -379,7 +379,7 @@ ${workflow}
|
|
|
379
379
|
Hard rules:
|
|
380
380
|
- Do not write production code. Planning only.
|
|
381
381
|
- Generate the task id as \`<slug>-<4hex>\` (e.g. \`${target.slug}-a3f9\`) — use 4 lowercase hex chars.
|
|
382
|
-
- Create the dir \`.
|
|
382
|
+
- Create the dir \`.agents/features/${target.feature}/tasks/<id>/\` first.
|
|
383
383
|
- Write PLAN.md with the frontmatter (id, kind, feature, status: ready, priority, parallelizable, depends-on).
|
|
384
384
|
- Pick a \`kind:\` value matching the work (be|fe|infra|docs|integration).
|
|
385
385
|
- Pick a reasonable \`priority:\` (default: medium).
|
|
@@ -457,7 +457,7 @@ export function buildDiscussTransform(
|
|
|
457
457
|
return {
|
|
458
458
|
handled: true,
|
|
459
459
|
transformedText:
|
|
460
|
-
`soly discuss: no .
|
|
460
|
+
`soly discuss: no .agents/ directory in cwd (${state.solyDir || "<cwd>"}) — cannot discuss.\n` +
|
|
461
461
|
`Initialize a soly project first.`,
|
|
462
462
|
};
|
|
463
463
|
}
|
|
@@ -594,7 +594,7 @@ soly_ask_user({
|
|
|
594
594
|
{ category: "<cat>", choice: "<what was chosen>", rationale: "<why>" },
|
|
595
595
|
...
|
|
596
596
|
],
|
|
597
|
-
canonical_refs: [".
|
|
597
|
+
canonical_refs: [".agents/docs/<file>", ".agents/ROADMAP.md", ...],
|
|
598
598
|
deferred_ideas: ["<scope creep for future phase>", ...],
|
|
599
599
|
codebase_context: ["src/components/Card.tsx — has rounded/shadow variants, reuse", ...],
|
|
600
600
|
})
|
|
@@ -608,7 +608,7 @@ soly_ask_user({
|
|
|
608
608
|
- ${hasAskPro ? "`ask_pro` — multi-question tabbed picker (PREFERRED)" : "`soly_ask_user` — single-question picker (fallback)"}
|
|
609
609
|
- \`soly_save_discuss_checkpoint\` — save partial progress (use after each answer)
|
|
610
610
|
- \`soly_finish_discuss\` — finalize: writes CONTEXT.md, deletes checkpoint
|
|
611
|
-
- \`soly_read\`, \`soly_snippet\`, \`soly_doc_search\` — read .
|
|
611
|
+
- \`soly_read\`, \`soly_snippet\`, \`soly_doc_search\` — read .agents/ artifacts as needed (intent docs are already in your system prompt)
|
|
612
612
|
- \`soly_log_decision\` — log to STATE.md Decisions table (use sparingly)
|
|
613
613
|
- Standard pi tools: \`read\`, \`bash\`, \`grep\`, \`find\` for codebase context
|
|
614
614
|
|
package/workflows/quick.ts
CHANGED
|
@@ -36,7 +36,7 @@ export function showStatus(
|
|
|
36
36
|
config?: SolyConfig,
|
|
37
37
|
): void {
|
|
38
38
|
if (!state.exists) {
|
|
39
|
-
ui.notify("soly: no .
|
|
39
|
+
ui.notify("soly: no .agents/ directory in cwd", "error");
|
|
40
40
|
return;
|
|
41
41
|
}
|
|
42
42
|
const maxPhases = config?.display.maxPhasesInStatus ?? 20;
|
|
@@ -122,7 +122,7 @@ const DECISIONS_TABLE_ROW = /^\|\s*([^|]+)\s*\|\s*([^|]+)\s*\|\s*([^|]+)\s*\|\s*
|
|
|
122
122
|
|
|
123
123
|
export function showLog(cmd: SolyCommand, state: SolyState, ui: QuickUI): void {
|
|
124
124
|
if (!state.exists) {
|
|
125
|
-
ui.notify("soly log: no .
|
|
125
|
+
ui.notify("soly log: no .agents/ directory in cwd", "error");
|
|
126
126
|
return;
|
|
127
127
|
}
|
|
128
128
|
|
|
@@ -214,7 +214,7 @@ export async function showDiff(
|
|
|
214
214
|
state: SolyState,
|
|
215
215
|
ui: QuickUI,
|
|
216
216
|
): Promise<void> {
|
|
217
|
-
// Graceful without .
|
|
217
|
+
// Graceful without .agents/: use cwd as project root, skip the .agents/ filter
|
|
218
218
|
const projectRoot = state.solyDir ? path.dirname(state.solyDir) : process.cwd();
|
|
219
219
|
const solyDir = state.solyDir; // may be empty when run outside a soly project
|
|
220
220
|
|
|
@@ -222,7 +222,7 @@ export async function showDiff(
|
|
|
222
222
|
const status = await safeExec("git", ["status", "--short", "--branch"], projectRoot);
|
|
223
223
|
// 2. git diff (tracked changes, no untracked)
|
|
224
224
|
const diff = await safeExec("git", ["diff", "--stat"], projectRoot);
|
|
225
|
-
// 3. uncommitted .
|
|
225
|
+
// 3. uncommitted .agents/ file changes (since last commit)
|
|
226
226
|
const solyChanges = await safeExec(
|
|
227
227
|
"git",
|
|
228
228
|
["status", "--short", "--", solyDir],
|
|
@@ -230,7 +230,7 @@ export async function showDiff(
|
|
|
230
230
|
);
|
|
231
231
|
|
|
232
232
|
const out: string[] = [];
|
|
233
|
-
out.push(state.exists ? "=== soly diff ===" : "=== git diff (no .
|
|
233
|
+
out.push(state.exists ? "=== soly diff ===" : "=== git diff (no .agents/ in cwd) ===");
|
|
234
234
|
out.push("");
|
|
235
235
|
|
|
236
236
|
if (status.code !== 0) {
|
|
@@ -246,10 +246,10 @@ export async function showDiff(
|
|
|
246
246
|
}
|
|
247
247
|
if (solyDir) {
|
|
248
248
|
if (solyChanges.stdout.trim()) {
|
|
249
|
-
out.push("uncommitted .
|
|
249
|
+
out.push("uncommitted .agents/ changes:");
|
|
250
250
|
out.push(solyChanges.stdout.trim());
|
|
251
251
|
} else {
|
|
252
|
-
out.push("uncommitted .
|
|
252
|
+
out.push("uncommitted .agents/ changes: (none)");
|
|
253
253
|
}
|
|
254
254
|
}
|
|
255
255
|
}
|
package/workflows/resume.ts
CHANGED
|
@@ -7,11 +7,11 @@
|
|
|
7
7
|
// session context from the last handoff.
|
|
8
8
|
//
|
|
9
9
|
// Reads:
|
|
10
|
-
// - .
|
|
11
|
-
// - .
|
|
10
|
+
// - .agents/HANDOFF.json (machine-readable state, written by pause/compact)
|
|
11
|
+
// - .agents/.continue-here.md (human-readable context, written by pause/compact)
|
|
12
12
|
//
|
|
13
13
|
// If neither file exists, falls back to a "no prior handoff" message that
|
|
14
|
-
// tells the LLM to load context from .
|
|
14
|
+
// tells the LLM to load context from .agents/STATE.md + ROADMAP.md normally.
|
|
15
15
|
// =============================================================================
|
|
16
16
|
|
|
17
17
|
import * as fs from "node:fs";
|
|
@@ -73,7 +73,7 @@ function formatListSection(label: string, items: string[] | undefined): string {
|
|
|
73
73
|
function formatHandoffSummary(h: HandoffJson): string {
|
|
74
74
|
const lines: string[] = [];
|
|
75
75
|
|
|
76
|
-
lines.push("=== From .
|
|
76
|
+
lines.push("=== From .agents/HANDOFF.json ===");
|
|
77
77
|
if (h.generated_at) lines.push(` generated_at: ${h.generated_at}`);
|
|
78
78
|
if (h.milestone) lines.push(` milestone: ${h.milestone}${h.milestone_name ? ` — ${h.milestone_name}` : ""}`);
|
|
79
79
|
if (h.status) lines.push(` status: ${h.status}`);
|
|
@@ -112,7 +112,7 @@ export function buildResumeTransform(cmd: SolyCommand, state: SolyState): Resume
|
|
|
112
112
|
return {
|
|
113
113
|
handled: true,
|
|
114
114
|
transformedText:
|
|
115
|
-
`soly resume: no .
|
|
115
|
+
`soly resume: no .agents/ directory in cwd (${state.solyDir || "<cwd>"}) — nothing to resume.\n` +
|
|
116
116
|
`Initialize a soly project first, or run \`soly pause\` later to create handoff files.`,
|
|
117
117
|
};
|
|
118
118
|
}
|
|
@@ -149,24 +149,24 @@ export function buildResumeTransform(cmd: SolyCommand, state: SolyState): Resume
|
|
|
149
149
|
}
|
|
150
150
|
|
|
151
151
|
if (!handoff && !continueMd) {
|
|
152
|
-
// No prior handoff — fall back to loading from .
|
|
152
|
+
// No prior handoff — fall back to loading from .agents/STATE.md directly.
|
|
153
153
|
const fallbackScope = phaseFilter != null
|
|
154
154
|
? `Focus: phase ${phaseFilter}.`
|
|
155
155
|
: "Scope: full project.";
|
|
156
156
|
return {
|
|
157
157
|
handled: true,
|
|
158
158
|
transformedText:
|
|
159
|
-
`soly resume: no handoff files found (looked for .
|
|
160
|
-
`No prior \`soly pause\` was run — loading context from .
|
|
159
|
+
`soly resume: no handoff files found (looked for .agents/HANDOFF.json and .agents/.continue-here.md).\n` +
|
|
160
|
+
`No prior \`soly pause\` was run — loading context from .agents/STATE.md and .agents/ROADMAP.md directly.\n\n` +
|
|
161
161
|
`${fallbackScope}\n\n` +
|
|
162
|
-
`Read .
|
|
162
|
+
`Read .agents/STATE.md (Current Position, Decisions, Blockers sections) and .agents/ROADMAP.md.\n` +
|
|
163
163
|
`Summarize: where the project is, what's next, what's blocking. Then ask the user what to focus on first.`,
|
|
164
164
|
};
|
|
165
165
|
}
|
|
166
166
|
|
|
167
167
|
const handoffBlock = handoff ? formatHandoffSummary(handoff) : "(no HANDOFF.json found)";
|
|
168
168
|
const continueBlock = continueMd
|
|
169
|
-
? `\n=== From .
|
|
169
|
+
? `\n=== From .agents/.continue-here.md ===\n${continueMd.trim()}\n`
|
|
170
170
|
: "";
|
|
171
171
|
|
|
172
172
|
const focusLine = phaseFilter != null
|
|
@@ -182,10 +182,10 @@ ${continueBlock}
|
|
|
182
182
|
|
|
183
183
|
=== Resume protocol ===
|
|
184
184
|
|
|
185
|
-
1. **Read .
|
|
186
|
-
2. Read .
|
|
187
|
-
3. Read .
|
|
188
|
-
4. Compare handoff's "work remaining" with the actual repo state (git status, recent commits, .
|
|
185
|
+
1. **Read .agents/docs/ first** — the project's 0-point intent. Pickup is meaningless without knowing what the user is building toward.
|
|
186
|
+
2. Read .agents/STATE.md to confirm current position (the handoff may be stale).
|
|
187
|
+
3. Read .agents/ROADMAP.md and any CONTEXT.md / RESEARCH.md for the active phase.
|
|
188
|
+
4. Compare handoff's "work remaining" with the actual repo state (git status, recent commits, .agents/ files).
|
|
189
189
|
5. Produce a one-screen "Where we are" summary:
|
|
190
190
|
- current phase + plan
|
|
191
191
|
- what's actually been done (verified via filesystem / git)
|
|
@@ -10,7 +10,7 @@ canonical CONTEXT.md. For design/architecture forks you may reach for
|
|
|
10
10
|
markdown is background context, not a strict protocol.</purpose>
|
|
11
11
|
|
|
12
12
|
<path_discipline>
|
|
13
|
-
**All soly-managed files live under `.
|
|
13
|
+
**All soly-managed files live under `.agents/`.** CONTEXT.md, RESEARCH.md, and the discuss checkpoint all go in `.agents/phases/<NN>-<slug>/`. Never write these to the project root. Use absolute paths.
|
|
14
14
|
|
|
15
15
|
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.
|
|
16
16
|
</path_discipline>
|
|
@@ -36,7 +36,7 @@ The iteration context file (path given by the parent in the task prompt) is your
|
|
|
36
36
|
**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.
|
|
37
37
|
</interactive_flow>
|
|
38
38
|
|
|
39
|
-
<read_first>`.
|
|
39
|
+
<read_first>`.agents/docs/` (INTENT, 0-point) · `.agents/STATE.md` · `.agents/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>
|
|
40
40
|
|
|
41
41
|
<philosophy>
|
|
42
42
|
**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.
|
|
@@ -90,7 +90,7 @@ PHASE=$1
|
|
|
90
90
|
# Worker subagent inherits the parent's cwd (the project root), so
|
|
91
91
|
# `pwd` IS the project root. The previous `cd .. && pwd` was a bug.
|
|
92
92
|
PROJECT_ROOT="$(pwd)"
|
|
93
|
-
SOLY_DIR="$PROJECT_ROOT/.
|
|
93
|
+
SOLY_DIR="$PROJECT_ROOT/.agents"
|
|
94
94
|
PHASE_DIR=$(ls -d "$SOLY_DIR/phases/"*"-$PHASE-"* 2>/dev/null | head -1) || { echo "Phase $PHASE not found" >&2; exit 1; }
|
|
95
95
|
PADDED_PHASE=$(printf "%02d" "$(echo "$PHASE" | grep -oE '^[0-9]+' | sed 's/^0*//')")
|
|
96
96
|
PHASE_SLUG=$(basename "$PHASE_DIR")
|
|
@@ -137,7 +137,7 @@ If you cannot answer from `.continue-here.md`, return `## Clarifications Needed`
|
|
|
137
137
|
[ -f "$SOLY_DIR/DECISIONS-INDEX.md" ] && echo "DECISIONS-INDEX.md (prefer over per-phase if present)"
|
|
138
138
|
```
|
|
139
139
|
|
|
140
|
-
Most-recent 3 prior `*-CONTEXT.md` files (prefer DECISIONS-INDEX if present). Extract `<decisions>`, `<specifics>`, and patterns (e.g., "user prefers minimal UI"). If `.
|
|
140
|
+
Most-recent 3 prior `*-CONTEXT.md` files (prefer DECISIONS-INDEX if present). Extract `<decisions>`, `<specifics>`, and patterns (e.g., "user prefers minimal UI"). If `.agents/spikes/MANIFEST.md` or `.agents/sketches/MANIFEST.md` exist with `WRAPPED: true` frontmatter, read as validated findings.
|
|
141
141
|
|
|
142
142
|
**6. Cross-reference todos.** (Worker doesn't have `soly_todos`; use `bash` + `grep` with phase-domain keywords.)
|
|
143
143
|
|
|
@@ -217,9 +217,9 @@ Requirements locked by SPEC.md. Do not re-litigate.
|
|
|
217
217
|
</decisions>
|
|
218
218
|
|
|
219
219
|
<canonical_refs> <!-- MANDATORY -->
|
|
220
|
-
- `.
|
|
221
|
-
- `.
|
|
222
|
-
- `.
|
|
220
|
+
- `.agents/docs/<file>` — <why>
|
|
221
|
+
- `.agents/features/<feat>/README.md` — <why>
|
|
222
|
+
- `.agents/contracts/<file>` — <why>
|
|
223
223
|
- (no external docs referenced) <!-- only if literally none -->
|
|
224
224
|
</canonical_refs>
|
|
225
225
|
|
|
@@ -289,8 +289,8 @@ Update after every round. Delete after `write_context` succeeds.
|
|
|
289
289
|
<hard_rules>
|
|
290
290
|
- No production code. Discussion/planning only.
|
|
291
291
|
- No PLAN.md from this workflow — that's `soly plan`.
|
|
292
|
-
- Don't assume missing intent. If `.
|
|
292
|
+
- Don't assume missing intent. If `.agents/docs/` is silent, ask.
|
|
293
293
|
- No scope creep. Deferred ideas → `<deferred_ideas>`, not decisions.
|
|
294
|
-
- No subagents (you ARE one). No `.
|
|
294
|
+
- No subagents (you ARE one). No `.agents/rules/` edits.
|
|
295
295
|
- Return: structured output per output_protocol + checkpoint updates. Parent relays to user.
|
|
296
296
|
</hard_rules>
|
|
@@ -3,12 +3,12 @@
|
|
|
3
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
4
|
|
|
5
5
|
<path_discipline>
|
|
6
|
-
**All soly-managed files live under `.
|
|
6
|
+
**All soly-managed files live under `.agents/`.** Never write PLAN.md, CONTEXT.md, RESEARCH.md, SUMMARY.md, iteration files, or handoffs to the project root. All phase files go in `.agents/phases/<NN>-<slug>/`. Use absolute paths (or paths starting with `$SOLY_DIR`) — never bare relative names that could land in cwd.
|
|
7
7
|
|
|
8
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
9
|
</path_discipline>
|
|
10
10
|
|
|
11
|
-
<read_first>`.
|
|
11
|
+
<read_first>`.agents/STATE.md` (single source of truth for "where am I") · `.agents/ROADMAP.md` (phase goal + reqs) · `.agents/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 `.agents/` missing → stop + error.</read_first>
|
|
12
12
|
|
|
13
13
|
<core_principle>
|
|
14
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.
|
|
@@ -28,7 +28,7 @@ PHASE="$1"
|
|
|
28
28
|
# would fall back to the `write` tool with a relative path, polluting
|
|
29
29
|
# the project root).
|
|
30
30
|
PROJECT_ROOT="$(pwd)"
|
|
31
|
-
SOLY_DIR="$PROJECT_ROOT/.
|
|
31
|
+
SOLY_DIR="$PROJECT_ROOT/.agents"
|
|
32
32
|
PHASE_DIR=$(ls -d "$SOLY_DIR/phases/"*"-$PHASE-"* 2>/dev/null | head -1) || { echo "Phase $PHASE not found" >&2; exit 1; }
|
|
33
33
|
PADDED_PHASE=$(printf "%02d" "$(echo "$PHASE" | grep -oE '^[0-9]+' | sed 's/^0*//')")
|
|
34
34
|
PHASE_SLUG=$(basename "$PHASE_DIR")
|
|
@@ -190,7 +190,7 @@ phase: <N> phase_slug: <slug> status: pending generated: <ISO>
|
|
|
190
190
|
</process>
|
|
191
191
|
|
|
192
192
|
<hard_rules>
|
|
193
|
-
- No `.
|
|
193
|
+
- No `.agents/rules/` edits. No subagents (`maxSubagentDepth: 1`).
|
|
194
194
|
- No silent skip of partial-state plans — surface and stop.
|
|
195
195
|
- No flipping VERIFICATION.md to `passed` yourself.
|
|
196
196
|
- No silent architectural decisions — use `execute-plan.md`'s Rule 4 + checkpoint.
|
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
<purpose>Execute one PLAN.md, produce a matching SUMMARY.md, update STATE.md/ROADMAP.md. Single worker — no sub-subagents.</purpose>
|
|
4
4
|
|
|
5
5
|
<path_discipline>
|
|
6
|
-
**All soly-managed files live under `.
|
|
6
|
+
**All soly-managed files live under `.agents/`.** Never write PLAN.md, CONTEXT.md, RESEARCH.md, SUMMARY.md, iteration files, or handoffs to the project root. All phase files go in `.agents/phases/<NN>-<slug>/`. Use absolute paths (or paths starting with `$SOLY_DIR`) — never bare relative names that could land in cwd.
|
|
7
7
|
|
|
8
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
9
|
</path_discipline>
|
|
10
10
|
|
|
11
|
-
<read_first>`.
|
|
11
|
+
<read_first>`.agents/STATE.md` · `.agents/ROADMAP.md` · `PLAN.md` (the contract) · `<phase>-CONTEXT.md` if exists (honor user decisions) · `<phase>-RESEARCH.md` if exists (use chosen libs/patterns). If `.agents/` missing → stop + error.</read_first>
|
|
12
12
|
|
|
13
13
|
<atomic_close_out>
|
|
14
14
|
**Only legal close-out order:** `production-code commit(s) → SUMMARY commit → STATE/ROADMAP update`.
|
|
@@ -24,7 +24,7 @@ PHASE="$1"; PLAN="$2" # PLAN optional — defaults to next unfinished
|
|
|
24
24
|
# Worker subagent inherits the parent's cwd (the project root), so
|
|
25
25
|
# `pwd` IS the project root. The previous `cd .. && pwd` was a bug.
|
|
26
26
|
PROJECT_ROOT="$(pwd)"
|
|
27
|
-
SOLY_DIR="$PROJECT_ROOT/.
|
|
27
|
+
SOLY_DIR="$PROJECT_ROOT/.agents"
|
|
28
28
|
PHASE_DIR=$(ls -d "$SOLY_DIR/phases/"*"-$PHASE-"* 2>/dev/null | head -1) || { echo "Phase $PHASE not found" >&2; exit 1; }
|
|
29
29
|
PADDED_PHASE=$(printf "%02d" "$(echo "$PHASE" | grep -oE '^[0-9]+' | sed 's/^0*//')")
|
|
30
30
|
PHASE_SLUG=$(basename "$PHASE_DIR")
|
|
@@ -60,7 +60,7 @@ PARTIAL_PLAN=$([ "$COMMIT_COUNT" -gt 0 ] && [ "$SUMMARY_EXISTS" = false ] && ech
|
|
|
60
60
|
**5. Execute tasks in order.** Per task:
|
|
61
61
|
|
|
62
62
|
1. **Read first** — open every `<read_first>` file.
|
|
63
|
-
2. **Implement** — minimal correct change, follow project patterns. No speculative scaffolding. No `.
|
|
63
|
+
2. **Implement** — minimal correct change, follow project patterns. No speculative scaffolding. No `.agents/rules/` edits.
|
|
64
64
|
3. **Verify acceptance criteria (HARD GATE):**
|
|
65
65
|
- Run the grep/file-check/CLI for each criterion in `<acceptance_criteria>`.
|
|
66
66
|
- Log PASS/FAIL with output. If ANY fails → fix immediately, re-run ALL.
|
|
@@ -123,7 +123,7 @@ Can't talk to user directly. Stop, return structured block, parent relays.
|
|
|
123
123
|
|
|
124
124
|
**9. Pre-commit hook failure:**
|
|
125
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 `.
|
|
126
|
+
**Do NOT use `--no-verify`** unless project's `.agents/docs/` or ROADMAP.md explicitly opts out.
|
|
127
127
|
|
|
128
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
129
|
|
|
@@ -212,7 +212,7 @@ git commit -m "chore(${PADDED_PHASE}-${PLAN_NUM}): complete plan <N>"
|
|
|
212
212
|
- Bump `current_plan` in "Current Position".
|
|
213
213
|
- Add `key-decisions` to "Decisions" table (skip if trivial).
|
|
214
214
|
- Update `last_updated`.
|
|
215
|
-
- Keep < 150 lines — archive long-form to `.
|
|
215
|
+
- Keep < 150 lines — archive long-form to `.agents/DECISIONS-INDEX.md` if it grows.
|
|
216
216
|
|
|
217
217
|
**Update ROADMAP.md** — phase's progress row: increment completed plan count; status → `In Progress` (more plans) or `Complete` (last) with date.
|
|
218
218
|
|
|
@@ -222,7 +222,7 @@ git commit -m "chore(${PADDED_PHASE}-${PLAN_NUM}): complete plan <N>"
|
|
|
222
222
|
REQUIREMENTS=$(grep -A1 "^requirements:" "$PLAN_PATH" | tail -1 | sed -E 's/.*\[([^]]+)\].*/\1/' | tr ',' ' ')
|
|
223
223
|
```
|
|
224
224
|
|
|
225
|
-
For each ID, find line in `.
|
|
225
|
+
For each ID, find line in `.agents/REQUIREMENTS.md`, flip status to `Complete`.
|
|
226
226
|
|
|
227
227
|
**15. Return:**
|
|
228
228
|
|
|
@@ -241,7 +241,7 @@ For each ID, find line in `.soly/REQUIREMENTS.md`, flip status to `Complete`.
|
|
|
241
241
|
</process>
|
|
242
242
|
|
|
243
243
|
<hard_rules>
|
|
244
|
-
- No `.
|
|
244
|
+
- No `.agents/rules/` edits. No `.agents/docs/` edits without explicit user decision in conversation.
|
|
245
245
|
- No subagents (you ARE one). `maxSubagentDepth: 1` is enforced.
|
|
246
246
|
- **Never skip `<acceptance_criteria>` HARD GATE.** Not optional.
|
|
247
247
|
- **Never emit narrative between SUMMARY `write` and `git commit`** (truncation is a known failure mode).
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
# Execute Task
|
|
2
2
|
|
|
3
|
-
<purpose>Execute ONE task (atomic unit — a feature slice, one endpoint, one page, one contract wire). Produce SUMMARY.md. Tasks live under `.
|
|
3
|
+
<purpose>Execute ONE task (atomic unit — a feature slice, one endpoint, one page, one contract wire). Produce SUMMARY.md. Tasks live under `.agents/features/<feature>/tasks/<task-id>/` with PLAN.md as the contract.</purpose>
|
|
4
4
|
|
|
5
5
|
<path_discipline>
|
|
6
|
-
**All soly-managed files live under `.
|
|
6
|
+
**All soly-managed files live under `.agents/`.** Never write PLAN.md, SUMMARY.md, iteration files, or handoffs to the project root. Task files go in `.agents/features/<feature>/tasks/<task-id>/`. Use absolute paths — never bare relative names that could land in cwd.
|
|
7
7
|
|
|
8
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
9
|
</path_discipline>
|
|
10
10
|
|
|
11
|
-
<read_first>`.
|
|
11
|
+
<read_first>`.agents/STATE.md` · `.agents/docs/` (INTENT, 0-point) · `.agents/features/<feature>/README.md` · `PLAN.md` (the contract) · `.agents/contracts/*` if PLAN.md references it. If `.agents/features/` or task dir missing → error + stop, do not invent paths.</read_first>
|
|
12
12
|
|
|
13
13
|
<task_frontmatter>
|
|
14
14
|
PLAN.md frontmatter (executor must respect all fields; **flag** incomplete ones in your report, don't silently fill):
|
|
@@ -46,13 +46,13 @@ STATUS=$(awk '/^---$/{c++; next} c==1{print}' "$TASK_DIR/PLAN.md" | grep -E '^st
|
|
|
46
46
|
|
|
47
47
|
If not → return `## Blocker` to parent, stop. Do NOT start a blocked task.
|
|
48
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 `.
|
|
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 `.agents/contracts/*` (if it exists) only if the task touches API surfaces.
|
|
50
50
|
|
|
51
51
|
**3. Execute** with standard worker self-audit:
|
|
52
52
|
|
|
53
53
|
1. Write code.
|
|
54
54
|
2. Run build / typecheck / lint — **0 warnings**.
|
|
55
|
-
3. Cross-check diff against `.
|
|
55
|
+
3. Cross-check diff against `.agents/rules/coding/*` (or `.editorconfig`).
|
|
56
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
57
|
5. Commit production-code changes (one or more commits).
|
|
58
58
|
|
|
@@ -101,7 +101,7 @@ You may combine into one commit, but the SUMMARY must be on disk before the fron
|
|
|
101
101
|
</process>
|
|
102
102
|
|
|
103
103
|
<hard_rules>
|
|
104
|
-
- No `.
|
|
104
|
+
- No `.agents/rules/` edits. No subagents (you ARE one).
|
|
105
105
|
- No starting tasks with un-`done` `depends-on:`.
|
|
106
106
|
- If rule gap → add via the rule-authoring skill. **No silent workarounds** (`#pragma`, `severity = none`).
|
|
107
107
|
- Return: changed files, commands + exit codes, validation evidence, surprises, decisions needing parent approval.
|
|
@@ -112,5 +112,5 @@ You may combine into one commit, but the SUMMARY must be on disk before the fron
|
|
|
112
112
|
</interactive_rules_out_of_scope>
|
|
113
113
|
|
|
114
114
|
<dual_mode_note>
|
|
115
|
-
Project may also have `.
|
|
115
|
+
Project may also have `.agents/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
116
|
</dual_mode_note>
|
|
@@ -1,36 +1,36 @@
|
|
|
1
1
|
# Pause Work
|
|
2
2
|
|
|
3
|
-
<purpose>Create `.
|
|
3
|
+
<purpose>Create `.agents/HANDOFF.json` (machine-readable) and a `.continue-here.md` (human-readable) to preserve work state across sessions. `soly resume` consumes both.</purpose>
|
|
4
4
|
|
|
5
|
-
<read_first>.
|
|
5
|
+
<read_first>.agents/STATE.md (current position) · the most recent `.agents/phases/*/SUMMARY.md` if any</read_first>
|
|
6
6
|
|
|
7
7
|
<process>
|
|
8
8
|
|
|
9
|
-
**1. Detect context.** First match wins; nothing detectable → `.
|
|
9
|
+
**1. Detect context.** First match wins; nothing detectable → `.agents/.continue-here.md` (note ambiguity in `<current_state>`).
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
|
-
phase=$(ls -t .
|
|
12
|
+
phase=$(ls -t .agents/phases/*/PLAN.md 2>/dev/null | head -1)
|
|
13
13
|
phase_slug=$(echo "$phase" | grep -oP 'phases/\K[^/]+')
|
|
14
|
-
spike=$(ls -td .
|
|
15
|
-
sketch=$(ls -td .
|
|
16
|
-
deliberation=$(ls .
|
|
14
|
+
spike=$(ls -td .agents/spikes/*/ 2>/dev/null | head -1)
|
|
15
|
+
sketch=$(ls -td .agents/sketches/*/ 2>/dev/null | head -1)
|
|
16
|
+
deliberation=$(ls .agents/deliberations/*.md 2>/dev/null | head -1)
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
| detected | handoff path |
|
|
20
20
|
|---|---|
|
|
21
|
-
| phase_slug | `.
|
|
22
|
-
| spike | `.
|
|
23
|
-
| sketch | `.
|
|
24
|
-
| deliberation | `.
|
|
25
|
-
| (notes only) | `.
|
|
21
|
+
| phase_slug | `.agents/phases/<phase_slug>/.continue-here.md` |
|
|
22
|
+
| spike | `.agents/spikes/<spike_slug>/.continue-here.md` |
|
|
23
|
+
| sketch | `.agents/sketches/<sketch_slug>/.continue-here.md` |
|
|
24
|
+
| deliberation | `.agents/deliberations/.continue-here.md` |
|
|
25
|
+
| (notes only) | `.agents/.continue-here.md` |
|
|
26
26
|
|
|
27
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
28
|
|
|
29
29
|
If anything is ambiguous, return a `## Clarifications Needed` block — do not invent.
|
|
30
30
|
|
|
31
|
-
**3. Check for false completions.** `grep -l "To be filled\|placeholder\|TBD" .
|
|
31
|
+
**3. Check for false completions.** `grep -l "To be filled\|placeholder\|TBD" .agents/phases/*/*.md 2>/dev/null` — report matches as incomplete.
|
|
32
32
|
|
|
33
|
-
**4. Write `.
|
|
33
|
+
**4. Write `.agents/HANDOFF.json`.** Timestamp via `date -u +"%Y-%m-%dT%H:%M:%SZ"` (no SDK).
|
|
34
34
|
|
|
35
35
|
```json
|
|
36
36
|
{
|
|
@@ -98,7 +98,7 @@ _If none, remove this section._
|
|
|
98
98
|
|
|
99
99
|
## Required Reading (in order)
|
|
100
100
|
1. <doc> — <why>
|
|
101
|
-
2. `.
|
|
101
|
+
2. `.agents/METHODOLOGY.md` if it exists — project lenses
|
|
102
102
|
|
|
103
103
|
## Infrastructure State
|
|
104
104
|
- <service/env>: <state>
|
|
@@ -117,14 +117,14 @@ Specific enough that a fresh worker can resume without re-deriving from git hist
|
|
|
117
117
|
|
|
118
118
|
**6. Commit:**
|
|
119
119
|
```bash
|
|
120
|
-
git add .
|
|
120
|
+
git add .agents/HANDOFF.json <handoff-md-path>
|
|
121
121
|
git commit -m "chore(soly): pause work — create handoff"
|
|
122
122
|
```
|
|
123
123
|
|
|
124
124
|
**7. Return:**
|
|
125
125
|
```
|
|
126
126
|
Handoff created:
|
|
127
|
-
- .
|
|
127
|
+
- .agents/HANDOFF.json
|
|
128
128
|
- <handoff-md-path>
|
|
129
129
|
State: <context>, <location>, task <x>/<m>, in_progress, <n> blockers (<m> human)
|
|
130
130
|
Resume: `soly resume`
|
|
@@ -136,7 +136,7 @@ Resume: `soly resume`
|
|
|
136
136
|
- No production code. Handoff only.
|
|
137
137
|
- A summary with `TBD`/`placeholder`/`To be filled` is incomplete — report it.
|
|
138
138
|
- `null` is JSON `null`, not the string `"null"`.
|
|
139
|
-
- Do not modify `.
|
|
139
|
+
- Do not modify `.agents/rules/`. Do not run subagents (you ARE one).
|
|
140
140
|
- Commit message: `chore(soly): pause work — create handoff`.
|
|
141
141
|
- Return: paths, state summary, blocker count, `soly resume` command.
|
|
142
142
|
</hard_rules>
|