@abianbiya/specflow 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Abian Nur Amin
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,46 @@
1
+ # @abianbiya/specflow
2
+
3
+ Spec-driven development for [pi](https://pi.dev) — full SpecFlow workflow (Requirements → Design → Tasks → Execution with explicit review gates) plus a live cockpit panel that shows where every spec stands and when the agent is waiting on your approval.
4
+
5
+ Installing this package gives you two things:
6
+
7
+ 1. **The `specflow` skill** — the structured five-phase workflow: drafting `.specflow/specs/{feature}/` documents (requirements, design, tasks), explicit approval gates between phases, validated task execution, and lifecycle management (complete, archive, list, resume).
8
+ 2. **The SpecFlow TUI extension** — a live cockpit panel for the active spec (phase, progress, next actionable task, traceability warnings, and a gate badge when the agent is parked awaiting your review), plus a `/specflow` command that can **launch work** — execute a task, approve a gate and resume, validate — as well as switch specs and read documents. The extension itself never writes to `.specflow/`: every action reaches the agent as an explicit user message, so the skill stays the only writer.
9
+
10
+ ## Install
11
+
12
+ ```bash
13
+ pi install npm:@abianbiya/specflow
14
+ ```
15
+
16
+ Or try it without installing:
17
+
18
+ ```bash
19
+ pi -e npm:@abianbiya/specflow
20
+ ```
21
+
22
+ For development against a local checkout:
23
+
24
+ ```bash
25
+ pi install -l /absolute/path/to/specflow-pi
26
+ ```
27
+
28
+ ## Usage
29
+
30
+ - Ask for a feature and the agent drafts requirements, then design, then tasks — each stopping for your approval (the panel shows `awaiting your review` at every stop).
31
+ - Live panel — the selected spec's name, phase (Requirements / Design / Tasks / Executing), done/total task count, status, and gate badge, updating within ~0.5 s of file edits.
32
+ - `/specflow` — act on the active spec without leaving the terminal:
33
+ - **Execute a task…** — pick from the unfinished tasks (`▶` ready, `⏸` blocked, with what they wait on); the chosen task is sent to the agent as `Execute task 2.1 of the rate-limit spec.`
34
+ - **Approve gate and resume** — appears only while a review gate is pending
35
+ - **Validate implementation** / **Open document…** — `requirements.md`, `design.md`, `tasks.md`, or `project.md` in a scrollable popup
36
+ - **Hide/Show panel**, and the spec list to switch which spec the panel follows
37
+ - Panel rows, beyond the phase: `Next: 2.1 Wire the Fastify hook` (first task whose dependencies are done), and one warning row when traceability is incomplete — `⚠ 1 unclaimed AC · 1 orphan criterion · 1 dangling dep`, i.e. requirements no task implements, citations of ACs that don't exist, and `Depends on:` ids that don't resolve.
38
+ - `resume` / `complete` / `archive` — lifecycle routes from the skill; the panel reflects the reconciled state.
39
+
40
+ ## Companion package
41
+
42
+ [`@abianbiya/speclet`](https://www.npmjs.com/package/@abianbiya/speclet) is the lightweight sibling: single-file specs for small features. Use specflow for mid-to-large features with multiple review gates.
43
+
44
+ ## License
45
+
46
+ MIT
@@ -0,0 +1,323 @@
1
+ /**
2
+ * specflow-pi — Pi extension. Shows the active specflow's phase as a live
3
+ * widget above the editor and registers the /specflow picker command, which
4
+ * also opens requirements.md / design.md / tasks.md / project.md in a
5
+ * scrollable markdown popup.
6
+ *
7
+ * State is always read from `<cwd>/.specflow/`; this extension never writes
8
+ * there (the skill owns gate metadata). A 500 ms non-overlapping poll keeps
9
+ * the panel current.
10
+ *
11
+ * Declared fork of speclet-tui/index.ts (AC7). Deliberately absent: the
12
+ * speclet task inspector and its `shift+up` registration — dropping the only
13
+ * global shortcut is what lets both extensions coexist in one session.
14
+ */
15
+
16
+ import { join } from "node:path";
17
+ import { lstat, readFile } from "node:fs/promises";
18
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
19
+ import { matchesKey, Markdown, truncateToWidth, type MarkdownTheme } from "@earendil-works/pi-tui";
20
+ import { SpecflowController } from "../src/controller.js";
21
+ import { discoverSpecflows, type SpecflowSpec } from "../src/parse.js";
22
+ import { renderScrollbar, stripControlSequences } from "../src/shared.js";
23
+ import {
24
+ actionOptions,
25
+ documentOptions,
26
+ listText,
27
+ pickerOptions,
28
+ renderWidgetLines,
29
+ renderDetailsLines,
30
+ taskOptions,
31
+ type CockpitAction,
32
+ type Styler,
33
+ } from "../src/render.js";
34
+
35
+ const WIDGET_KEY = "specflow";
36
+ const MAX_LINES = 6;
37
+ const INDENT = " ";
38
+ /** Viewer ceiling: larger or binary documents are reported, never rendered (F5). */
39
+ const MAX_DOC_BYTES = 512 * 1024;
40
+
41
+ function popupColors() {
42
+ return {
43
+ heading: "accent",
44
+ meta: "muted",
45
+ phase: "text",
46
+ gate: "warning",
47
+ next: "text",
48
+ warn: "warning",
49
+ body: "text",
50
+ more: "dim",
51
+ rule: "borderMuted",
52
+ } as const;
53
+ }
54
+
55
+ function makeStyler(theme: any): Styler {
56
+ const colors = popupColors();
57
+ return (text, kind) => theme.fg(colors[kind], text);
58
+ }
59
+
60
+ function markdownThemeFrom(theme: any): MarkdownTheme {
61
+ return {
62
+ heading: (t) => theme.fg("accent", theme.bold(t)),
63
+ link: (t) => theme.fg("accent", t),
64
+ linkUrl: (t) => theme.fg("dim", t),
65
+ code: (t) => theme.fg("warning", t),
66
+ codeBlock: (t) => theme.fg("dim", t),
67
+ codeBlockBorder: (t) => theme.fg("borderMuted", t),
68
+ quote: (t) => theme.fg("dim", t),
69
+ quoteBorder: (t) => theme.fg("borderMuted", t),
70
+ hr: (t) => theme.fg("borderMuted", t),
71
+ listBullet: (t) => theme.fg("accent", t),
72
+ bold: (t) => theme.bold(t),
73
+ italic: (t) => theme.italic(t),
74
+ strikethrough: (t) => theme.strikethrough(t),
75
+ underline: (t) => theme.underline(t),
76
+ };
77
+ }
78
+
79
+ interface PopupCtx {
80
+ ui: {
81
+ custom: (factory: unknown, options?: unknown) => Promise<void>;
82
+ notify: (message: string, type?: string) => void;
83
+ };
84
+ }
85
+
86
+ /**
87
+ * Open one document overlay: themed markdown, padded box, scrollbar, esc/q
88
+ * closes (AC4). A missing or unreadable file reports the file name and opens
89
+ * nothing.
90
+ */
91
+ async function openDocumentPopup(
92
+ popupCtx: PopupCtx,
93
+ spec: SpecflowSpec,
94
+ doc: { label: string; path: string },
95
+ ): Promise<void> {
96
+ let content: string;
97
+ try {
98
+ const stats = await lstat(doc.path);
99
+ if (stats.size > MAX_DOC_BYTES) {
100
+ popupCtx.ui.notify(
101
+ `specflow: cannot display ${doc.label}: ${Math.round(stats.size / 1024)} kB exceeds the ${MAX_DOC_BYTES / 1024} kB viewer limit`,
102
+ "error",
103
+ );
104
+ return;
105
+ }
106
+ content = await readFile(doc.path, "utf8");
107
+ } catch (e) {
108
+ popupCtx.ui.notify(`specflow: cannot read ${doc.label}: ${String(e)}`, "error");
109
+ return;
110
+ }
111
+ if (content.includes("\u0000")) {
112
+ popupCtx.ui.notify(`specflow: cannot display ${doc.label}: binary file`, "error");
113
+ return;
114
+ }
115
+ const header = `${spec.name} · ${doc.label}`;
116
+
117
+ await popupCtx.ui.custom(
118
+ (tui: any, theme: any, _keybindings: unknown, close: () => void) => {
119
+ let offset = 0;
120
+ const styler = makeStyler(theme);
121
+ const mdTheme = markdownThemeFrom(theme);
122
+ let md: Markdown | undefined;
123
+ let mdBodyLines: string[] = [];
124
+ let mdWidth = -1;
125
+ const height = () => Math.max(8, Math.floor(tui.terminal.rows * 0.7));
126
+ return {
127
+ render(width: number): string[] {
128
+ // true inner width: border(4) + indent(2) + scrollbar column(2)
129
+ const contentWidth = Math.max(10, width - 8);
130
+ if (!md || mdWidth !== contentWidth) {
131
+ md = new Markdown(content, 0, 0, mdTheme);
132
+ mdWidth = contentWidth;
133
+ mdBodyLines = md.render(contentWidth);
134
+ offset = Math.max(0, Math.min(offset, Math.max(0, mdBodyLines.length - 1)));
135
+ }
136
+ const h = height();
137
+ const visibleRows = Math.max(1, h - 3);
138
+ const bar = renderScrollbar(mdBodyLines.length, visibleRows, offset).map((c) =>
139
+ c === "█" ? theme.fg("accent", "█") : theme.fg("borderMuted", "░"),
140
+ );
141
+ return renderDetailsLines(header, mdBodyLines, width, h, offset, truncateToWidth, styler, {
142
+ indent: INDENT,
143
+ scrollbar: bar,
144
+ plainBody: true,
145
+ border: true,
146
+ });
147
+ },
148
+ handleInput(data: string): void {
149
+ if (matchesKey(data, "escape") || data === "q") {
150
+ close();
151
+ return;
152
+ }
153
+ const page = Math.max(1, height() - 4);
154
+ const delta = matchesKey(data, "down")
155
+ ? 1
156
+ : matchesKey(data, "up")
157
+ ? -1
158
+ : matchesKey(data, "pageDown")
159
+ ? page
160
+ : matchesKey(data, "pageUp")
161
+ ? -page
162
+ : matchesKey(data, "home")
163
+ ? -Infinity
164
+ : matchesKey(data, "end")
165
+ ? Infinity
166
+ : 0;
167
+ if (delta === 0) return;
168
+ const visibleRows = Math.max(1, height() - 3);
169
+ offset = Math.max(0, Math.min(offset + delta, Math.max(0, mdBodyLines.length - visibleRows)));
170
+ tui.requestRender();
171
+ },
172
+ invalidate(): void {
173
+ md = undefined;
174
+ },
175
+ };
176
+ },
177
+ { overlay: true, overlayOptions: { width: "80%", margin: 2 } },
178
+ );
179
+ }
180
+
181
+ /**
182
+ * Run one cockpit action (AC6). Every action reaches the agent as an explicit
183
+ * user message via pi.sendUserMessage — this extension never writes to
184
+ * `.specflow/` itself, so the skill/agent stays the only writer. Cancelling a
185
+ * chooser performs nothing (AC7).
186
+ */
187
+ async function runCockpitAction(
188
+ pi: ExtensionAPI,
189
+ ctx: { ui: { select: (title: string, options: string[]) => Promise<string | undefined>; notify: (m: string, t?: string) => void } },
190
+ spec: SpecflowSpec,
191
+ action: CockpitAction,
192
+ projectFile: string,
193
+ ): Promise<void> {
194
+ const confirm = (message: string) => {
195
+ pi.sendUserMessage(message);
196
+ ctx.ui.notify(`Sent: ${message}`, "info");
197
+ };
198
+
199
+ switch (action) {
200
+ case "execute": {
201
+ const tasks = taskOptions(spec);
202
+ if (tasks.length === 0) {
203
+ ctx.ui.notify(`No unfinished task in ${spec.name}.`, "info");
204
+ return;
205
+ }
206
+ const choice = await ctx.ui.select(`Execute which task of ${spec.name}?`, tasks.map((t) => t.label));
207
+ if (choice === undefined) return;
208
+ const picked = tasks.find((t) => t.label === choice);
209
+ if (!picked) return;
210
+ confirm(`Execute task ${picked.task.id} of the ${spec.name} spec.`);
211
+ return;
212
+ }
213
+ case "approve":
214
+ confirm(`Approve and resume the ${spec.name} spec.`);
215
+ return;
216
+ case "validate":
217
+ confirm(`Validate the ${spec.name} spec implementation.`);
218
+ return;
219
+ case "document": {
220
+ const docs = documentOptions(spec, projectFile);
221
+ const picked = await ctx.ui.select(`Document: ${spec.name}`, docs.map((d) => d.label));
222
+ if (picked === undefined) return;
223
+ const doc = docs.find((d) => d.label === picked);
224
+ if (doc) await openDocumentPopup(ctx, spec, doc);
225
+ return;
226
+ }
227
+ case "toggle":
228
+ return; // handled by the caller, which owns the controller
229
+ }
230
+ }
231
+
232
+ export default function specflowTui(pi: ExtensionAPI) {
233
+ let controller: SpecflowController | undefined;
234
+
235
+ // Re-register the widget from current controller state. setWidget with a
236
+ // factory triggers a repaint; the component re-reads state on each render so
237
+ // resize always reflows. No specflow widget when the panel has no content.
238
+ function repaint(ctx: { ui: { setWidget: (key: string, content: unknown) => void } }) {
239
+ if (!controller) return;
240
+ const spec = controller.active();
241
+ if (!spec || controller.hidden) {
242
+ ctx.ui.setWidget(WIDGET_KEY, undefined);
243
+ return;
244
+ }
245
+
246
+ ctx.ui.setWidget(WIDGET_KEY, (_tui, theme) => ({
247
+ render(width: number): string[] {
248
+ const current = controller?.active();
249
+ if (!current) return [];
250
+ return renderWidgetLines(current, width, MAX_LINES, truncateToWidth, makeStyler(theme));
251
+ },
252
+ }));
253
+ }
254
+
255
+ pi.on("session_start", (_event, ctx) => {
256
+ // Interactive-only: no timer or widget in rpc/json/print modes (AC6).
257
+ if (ctx.mode !== "tui") return;
258
+ const sessionCtx = ctx;
259
+ controller = new SpecflowController(join(ctx.cwd, ".specflow"), {
260
+ onUpdate: () => repaint(sessionCtx),
261
+ onDiagnostic: (msg) => sessionCtx.ui.notify(`specflow: ${msg}`, "warning"),
262
+ });
263
+ repaint(sessionCtx);
264
+ controller.start();
265
+ });
266
+
267
+ pi.on("session_shutdown", () => {
268
+ // Stop polling and drop session state (incl. pinned selection) — AC6.
269
+ controller?.stop();
270
+ controller = undefined;
271
+ });
272
+
273
+ pi.registerCommand("specflow", {
274
+ description: "Act on the active specflow: execute a task, approve a gate, validate, or read a document",
275
+ handler: async (_args, ctx) => {
276
+ const specflowDir = join(ctx.cwd, ".specflow");
277
+
278
+ // Non-interactive modes: textual listing, never a dialog (AC3, AC8).
279
+ // A partial discovery failure must not hide the specs that did resolve (F4).
280
+ if (ctx.mode !== "tui" || !controller) {
281
+ const { specs, dirError } = await discoverSpecflows(specflowDir);
282
+ const listing = specs.length > 0 ? listText(specs) : "No specflows found.";
283
+ const text = stripControlSequences(dirError ? `${dirError}\n${listing}` : listing);
284
+ if (ctx.hasUI) {
285
+ ctx.ui.notify(text, "info");
286
+ } else {
287
+ console.log(text);
288
+ }
289
+ return;
290
+ }
291
+
292
+ if (controller.specs.length === 0) {
293
+ ctx.ui.notify("No specflows found.", "info");
294
+ return;
295
+ }
296
+
297
+ const active = controller.active();
298
+ const options = pickerOptions(controller.specs);
299
+ const actions = active ? actionOptions(active, controller.hidden) : [];
300
+ const choice = await ctx.ui.select(active ? `Specflow: ${active.name}` : "Specflow:", [
301
+ ...actions.map((a) => a.label),
302
+ ...options.map((o) => o.label),
303
+ ]);
304
+ if (choice === undefined) return; // cancelled — keep current selection (AC3, AC7)
305
+
306
+ const action = actions.find((a) => a.label === choice);
307
+ if (action && active) {
308
+ if (action.action === "toggle") {
309
+ controller.hidden ? controller.show() : controller.hide();
310
+ return;
311
+ }
312
+ await runCockpitAction(pi, ctx, active, action.action, join(specflowDir, "project.md"));
313
+ return;
314
+ }
315
+
316
+ const picked = options.find((o) => o.label === choice);
317
+ if (picked) {
318
+ controller.pin(picked.dir);
319
+ controller.show(); // picking a specflow also reveals the panel
320
+ }
321
+ },
322
+ });
323
+ }
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@abianbiya/specflow",
3
+ "version": "0.1.0",
4
+ "description": "SpecFlow for pi: spec-driven development with review gates (skill), plus a live spec cockpit panel, /specflow picker, and in-terminal document viewer (TUI extension).",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "keywords": [
8
+ "pi-package",
9
+ "spec-driven",
10
+ "specflow",
11
+ "skills",
12
+ "agent"
13
+ ],
14
+ "files": [
15
+ "skills",
16
+ "extensions",
17
+ "src",
18
+ "README.md",
19
+ "LICENSE"
20
+ ],
21
+ "scripts": {
22
+ "test": "bun test",
23
+ "prepublishOnly": "bun run scripts/sync-skill.ts --check && bun run scripts/check-fork.ts"
24
+ },
25
+ "pi": {
26
+ "extensions": ["./extensions"],
27
+ "skills": ["./skills"]
28
+ },
29
+ "peerDependencies": {
30
+ "@earendil-works/pi-coding-agent": "*",
31
+ "@earendil-works/pi-tui": "*"
32
+ },
33
+ "peerDependenciesMeta": {
34
+ "@earendil-works/pi-coding-agent": { "optional": true },
35
+ "@earendil-works/pi-tui": { "optional": true }
36
+ }
37
+ }
@@ -0,0 +1,48 @@
1
+ ---
2
+ name: specflow
3
+ description: "Plan and implement features through approved requirements, design, and tasks. Use for spec-driven development with explicit review gates and validated execution."
4
+ ---
5
+
6
+ # SpecFlow
7
+
8
+ ## Core Contract
9
+
10
+ Work through Phase 1 (Requirements), Phase 2 (Design), Phase 3 (Tasks), then Phase 4 (Execution). Present each planning document for review and obtain explicit approval before advancing; revise and seek approval again after feedback. Existing files alone are not approval. When updating an earlier phase, reconcile affected downstream documents through the same gates before execution.
11
+
12
+ Phase 4 defaults to one task, followed by a report and a stop for user review. Only an explicitly requested task range or list authorizes a batch. Phase 5 manages completion, archiving, listing, and resumption; it is not an additional planning gate.
13
+
14
+ Whenever work pauses for a review — a planning document or a Phase 4 task report — record `gate: review` in the spec's `tasks.md` frontmatter (create a metadata-only `tasks.md` when none exists) and clear the field once approval to resume is received.
15
+
16
+ Load the relevant reference when entering a phase; reuse context already loaded and unchanged. Start the requested work without an unsolicited workflow explanation.
17
+
18
+ ## Entry Points
19
+
20
+ | User intent | Route / reference |
21
+ |-------------|-------------------|
22
+ | First spec / missing project.md | [Project setup](references/project-setup.md), then requested phase |
23
+ | New feature / new spec / update requirements | [Phase 1: Requirements](references/requirements-phase.md) |
24
+ | Grill me / ask me questions first / let's discuss this | [Phase 1: Grilling](references/requirements-phase.md#grilling-optional) |
25
+ | Update design / grill the design / discuss architecture first | [Phase 2: Design](references/design-phase.md) |
26
+ | Update tasks | [Phase 3: Tasks](references/tasks-phase.md) |
27
+ | Execute a task / execute next task | [Phase 4: Execution](references/execution-phase.md) |
28
+ | Execute tasks 1.1–1.4 / an explicit task list | [Phase 4: Execution](references/execution-phase.md) within that scope |
29
+ | Execute an authorized batch in parallel | [Phase 4: Parallel execution](references/execution-phase.md#parallel-execution-optional) |
30
+ | Validate implementation | [Phase 4: Validation](references/execution-phase.md#validation) |
31
+ | Continue / resume spec | [Phase 5: Resume](references/lifecycle-phase.md#resume) to determine the current phase |
32
+ | Complete spec / mark spec done | [Phase 5: Complete](references/lifecycle-phase.md#complete) |
33
+ | Archive spec | [Phase 5: Archive](references/lifecycle-phase.md#archive) |
34
+ | List / show specs, optionally by status | [Phase 5: List](references/lifecycle-phase.md#list) |
35
+
36
+ ## Directory Layout
37
+
38
+ ```text
39
+ .specflow/
40
+ ├── project.md
41
+ └── specs/
42
+ └── {feature-name}/
43
+ ├── requirements.md
44
+ ├── design.md
45
+ └── tasks.md
46
+ ```
47
+
48
+ Use descriptive kebab-case feature names. Status lives in `tasks.md` frontmatter; paths stay stable. Older versions used `active/`, `completed/`, and `archived/` directories: preserve compatibility as described in [Lifecycle](references/lifecycle-phase.md#status-and-legacy-layout).
@@ -0,0 +1,27 @@
1
+ # Phase 2: Design
2
+
3
+ Use the approved requirements and current project context to create or update `design.md` in the active feature directory. Follow the [planning approval gate](../SKILL.md#core-contract).
4
+
5
+ Research the codebase and external dependencies as needed. Summarize findings with sources and links in the conversation; do not create separate research files. Record unresolved research limitations and their impact. Consult relevant completed specs through the dependency links in requirements.
6
+
7
+ ## Grilling (Optional)
8
+
9
+ When requested, use the [grilling format](requirements-phase.md#grilling-optional) for architectural decisions that materially affect the design: data ownership and models, coupling, consistency, API contracts, and access boundaries. Capture confirmed choices and rationale in Design Decisions.
10
+
11
+ ## Document Content
12
+
13
+ | Section | Required content |
14
+ |---------|------------------|
15
+ | Overview | Technical approach and how it meets requirements |
16
+ | Architecture | System context, component boundaries and interactions, Mermaid diagram |
17
+ | Design Decisions | Options considered, choice, rationale |
18
+ | Components and Interfaces | Responsibilities, dependencies, method signatures, parameters and return types |
19
+ | Data Models | Fields, types, constraints, relationships; diagram where useful |
20
+ | API Design (if applicable) | Methods, paths, requests, responses, error contracts |
21
+ | Error Handling | Error categories, user impact, recovery/retry/fallback behavior |
22
+ | Testing Strategy | Unit, integration, and E2E scenarios as applicable; component coverage and project testing standards |
23
+ | Security Considerations | Access controls, relevant threats, data privacy |
24
+ | Performance Considerations | Expected load, capacity, caching and query behavior as applicable |
25
+ | Requirements Traceability | Map every requirement to design components using the [requirement IDs](requirements-phase.md#document-content) |
26
+
27
+ Keep the design sufficient to implement and verify all requirements without prescribing unrelated layers or technologies. Present it with a summary of key decisions for review.
@@ -0,0 +1,55 @@
1
+ # Phase 4: Execution
2
+
3
+ ## Session Context
4
+
5
+ Identify the active spec and verify the [planning approvals](../SKILL.md#core-contract). Project context must exist; all three planning documents must be approved.
6
+
7
+ At the start of an execution session, read `.specflow/project.md` and the feature's `requirements.md`, `design.md`, and `tasks.md` in full once. Load referenced completed-spec context only where relevant. Retain the requirement mapping, design structure, task order/dependencies, and project conventions in session context.
8
+
9
+ An execution session spans successive task requests for the same spec while that context remains available. A user-review pause does not start a new session. If context is lost or a different spec is selected, establish the full baseline again. If files change, refresh affected sections and dependencies; changes to approved planning content must pass the root approval gates before execution resumes.
10
+
11
+ ## Task Scope and Delta Reads
12
+
13
+ For “execute next task,” select the first unchecked task in listed order whose declared dependencies are validated and integrated. For a specified task, verify that it is unchecked and its dependencies are complete. An explicit range such as “execute tasks 1.1–1.4” or list authorizes those tasks only, in dependency order, sequentially by default; do not silently add prerequisites or expand the range. Skip already checked tasks and report them as skipped.
14
+
15
+ For each task after the baseline, load only:
16
+
17
+ - Its current unchecked task line and scope/reference sub-bullets, plus dependency or parent status needed to select it.
18
+ - The referenced requirement IDs and their acceptance criteria, using the [ID convention](requirements-phase.md#document-content).
19
+ - The design sections it touches, including relevant shared interfaces and constraints.
20
+
21
+ Reuse unchanged project and broader spec context; do not reload entire documents per task. Resolve unclear scope from these excerpts before asking the user. Missing IDs, unmet dependencies, or remaining ambiguity block execution of that task.
22
+
23
+ Implement within this scope using the approved design and project conventions. Requirements and design are read-only during execution; route needed changes to their planning phase. Clarified task wording may be updated without silently changing approved scope.
24
+
25
+ ## Parallel Execution (Optional)
26
+
27
+ Use subagents only within an explicitly authorized batch, when the user permits delegation and the harness supports it. Otherwise follow the same dependency flow sequentially. Only ready tasks with no dependency between them may run together.
28
+
29
+ The parent assigns bounded task scopes, relevant context excerpts, and file ownership. Use disjoint files where shared-tree parallel writers are permitted; otherwise use separate worktrees or run sequentially. Account for shared interfaces, generated files, and mutable test resources as well as dependency edges. Follow harness limits and repository delegation rules.
30
+
31
+ Children implement and return changes plus validation evidence; the parent owns integration, final validation, and `tasks.md` updates. A child report alone does not complete a task. Integrate and validate prerequisite results before launching dependents.
32
+
33
+ On an unresolved failure, stop dispatching new tasks, safely pause or collect already-running work, preserve edits, and report completed, failed, and unstarted tasks. Do not start dependents of failed work.
34
+
35
+ ## Validation
36
+
37
+ Before changing a task checkbox, verify all three levels:
38
+
39
+ | Level | Evidence required |
40
+ |-------|-------------------|
41
+ | Requirements | Every referenced acceptance criterion passes, including its specified edge, error, and success cases. A whole-requirement reference includes all its criteria. |
42
+ | Design | Touched components/layers, schemas and relationships, interfaces, API behavior, error handling, and state management match the approved design. |
43
+ | Quality | Tests for new testable logic cover normal and error paths; project tests, lint, and applicable type checks pass; functionality runs without errors or warnings. Find commands in project context or repository configuration. |
44
+
45
+ If a task cannot independently satisfy its referenced criteria, resolve the task/spec mismatch through planning rather than claiming partial validation as a pass. If checks fail, fix within the authorized task and revalidate. If blocked or unable to run required checks, leave it unchecked, report the evidence and resolution options, and stop for user guidance. For a parallel batch, apply the failure handling above.
46
+
47
+ Only after all levels pass, change that task from `- [ ]` to `- [x]`. Complete children before checking a parent; check the parent's own scope too. In sequential execution, validate and update each task before starting the next; parallel execution follows the integration rules above.
48
+
49
+ For “validate implementation,” apply these same levels to the requested scope (the whole implementation if unspecified), using the session/delta context rules. Report findings without implementing fixes or changing checkboxes unless requested.
50
+
51
+ ## Report and Stop
52
+
53
+ Report task IDs and outcomes, changed files, requirement/criterion evidence, design conformance, checks run and results, and any blockers or remaining work. For a batch, give one consolidated report with per-task results, including skipped or unexecuted tasks.
54
+
55
+ Stop after the default single task or the explicitly authorized batch and wait for the user before further execution. When all tasks are checked, report readiness for the explicit [complete spec](lifecycle-phase.md#complete) action; do not change its lifecycle status automatically.
@@ -0,0 +1,57 @@
1
+ # Phase 5: Lifecycle
2
+
3
+ ## Status and Legacy Layout
4
+
5
+ New specs use the flat [layout](../SKILL.md#directory-layout). `tasks.md` frontmatter status is authoritative: `active` for development, `completed` for implementation references, `archived` for obsolete or abandoned history. Before a new plan exists, treat the spec as active. Listing, resuming, and archiving are available before implementation finishes.
6
+
7
+ Older versions stored specs under `specs/active/`, `specs/completed/`, and `specs/archived/`. Discover both layouts; for legacy specs without status metadata, infer status from the containing directory. Metadata takes precedence if present. Update legacy specs in place without moving directories or migrating automatically. A flat spec with a task file but missing or invalid status needs clarification before a lifecycle write.
8
+
9
+ Resolve names across both layouts, using actual paths to distinguish duplicates. Use the sole eligible spec if unambiguous; otherwise ask which spec. Report missing specs or already-achieved states without changing anything.
10
+
11
+ ## Complete
12
+
13
+ On an explicit completion request, verify the active spec's tasks are all checked and their completion is backed by [execution validation](execution-phase.md#validation). Unchecked or unvalidated work blocks completion; report what remains. This command does not implement tasks or check boxes on the user's behalf.
14
+
15
+ Set completion metadata in place. Confirm the spec path, status, and completion date. Completed specs remain available as reference documentation.
16
+
17
+ ## Archive
18
+
19
+ On an archive request, set archive metadata on an active or completed spec in place. Use the user's reason if supplied; otherwise ask and wait for it. Confirm the spec path, status, reason, and archive date.
20
+
21
+ Archive rather than delete specs. Preserve all documents and historical metadata; lifecycle transitions do not move directories. Verify metadata after writing and report failures. Archived specs can be referenced but not modified.
22
+
23
+ ## Metadata
24
+
25
+ Store lifecycle metadata in YAML frontmatter at the top of `tasks.md`, preserving unrelated fields and body. For an early archive with no task file, create a metadata-only `tasks.md`; this is not an approved implementation plan.
26
+
27
+ | Field | Rule |
28
+ |-------|------|
29
+ | status | Set `active` when creating a plan; preserve existing status on plan edits; set `completed` or `archived` only through the corresponding transition |
30
+ | gate | Only defined value is `review`: set when stopping for a review in any phase (planning documents and every Phase 4 per-task stop); clear when approval to resume is received |
31
+ | created_at | Preserve if present; record only if the creation date is known |
32
+ | completed_at | Set to today's ISO date (YYYY-MM-DD) on completion; preserve on later archive |
33
+ | archived_at | Set to today's ISO date on archive |
34
+ | archive_reason | User-supplied reason, required on archive |
35
+
36
+ Use status resolution above for legacy plans. A metadata-only task file is not evidence of planning approval.
37
+
38
+ ## List
39
+
40
+ Show specs grouped by active/completed/archived, or restrict to the requested status. Task counts, lifecycle dates, and archive reasons may supplement names. Distinguish executable-task progress from parent group checkboxes when reporting counts.
41
+
42
+ ## Resume
43
+
44
+ Locate the active spec and determine progress from documents plus known approvals, not file existence alone. If approval is unknown, request review of the relevant document before advancing.
45
+
46
+ | State | Route |
47
+ |-------|-------|
48
+ | No requirements | Phase 1: [Requirements](requirements-phase.md) |
49
+ | Requirements awaiting approval | Phase 1 review |
50
+ | Requirements approved; design missing or awaiting approval | Phase 2: [Design](design-phase.md) / review |
51
+ | Design approved; tasks missing or awaiting approval | Phase 3: [Tasks](tasks-phase.md) / review |
52
+ | All three approved, work remains | Phase 4: [Execution](execution-phase.md), default next task |
53
+ | All tasks validated and checked | Report readiness for Complete; await explicit completion request |
54
+
55
+ Reconcile recorded gate state on resume: a `gate: review` field that no longer matches a pending review — for example one left behind by an interrupted session — must be cleared.
56
+
57
+ Report the current phase, progress if available, and next action. Let the selected phase load its relevant context; resumption does not itself mandate full-document re-reading.
@@ -0,0 +1,9 @@
1
+ # Project Setup
2
+
3
+ `.specflow/project.md` holds shared tech stack, conventions, and patterns. Use it when creating or updating specs; retain unchanged context during the session. Execution loading and refresh rules are defined in [Phase 4](execution-phase.md#session-context).
4
+
5
+ If missing, create it before the first spec using [templates/project.md](../templates/project.md). Inspect available project information and ask the user for missing stack or convention details needed to fill it out.
6
+
7
+ The template is the canonical starting point. Add project-specific package-manager and lint/format tooling, actual test/lint/type-check/dev-server commands where applicable, directory layout, and integration notes when available; these operational details supplement its existing sections.
8
+
9
+ Update project context when the stack, conventions, or major directory structure changes. Current project context takes precedence over conflicting completed-spec conventions; resolve conflicts with active approved specs through their planning gates.