@dtlabs/ai-toolkit 0.17.4 → 0.18.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/CHANGELOG.md +30 -0
- package/lib/agent-registry.js +39 -0
- package/lib/workflow-control.js +65 -13
- package/package.json +1 -1
- package/src/claude/agents/gaia-generate-requirements-use-case.md +97 -0
- package/src/claude/agents/gaia-generate-requirements.md +22 -27
- package/src/claude/agents/gaia-generate-tech-spec-component.md +93 -0
- package/src/claude/agents/gaia-generate-tech-spec.md +47 -103
- package/src/claude/agents/gaia-generate-work-breakdown-task.md +151 -0
- package/src/claude/agents/gaia-generate-work-breakdown.md +94 -100
- package/src/claude/agents/gaia-validate-feature-docs.md +13 -8
- package/src/claude/commands/assemble-docs.md +16 -0
- package/src/claude/commands/feature-status.md +9 -4
- package/src/claude/scripts/ac-task-matrix.js +87 -0
- package/src/claude/scripts/assemble-docs.js +66 -0
- package/src/claude/scripts/req-assembler.js +127 -0
- package/src/claude/scripts/req-graph-checks.js +71 -0
- package/src/claude/scripts/req-skeleton-check.js +64 -0
- package/src/claude/scripts/tech-spec-assembler.js +188 -0
- package/src/claude/scripts/tech-spec-graph-checks.js +84 -0
- package/src/claude/scripts/templates/gaia-component-template.md +64 -0
- package/src/claude/scripts/templates/gaia-dependency-graph-template.md +85 -0
- package/src/claude/scripts/templates/gaia-requirements-index-template.md +144 -0
- package/src/claude/scripts/templates/gaia-task-template.md +92 -0
- package/src/claude/scripts/templates/gaia-tech-spec-index-template.md +137 -0
- package/src/claude/scripts/templates/gaia-use-case-template.md +56 -0
- package/src/claude/scripts/templates/gaia-user-story-template.md +61 -0
- package/src/claude/scripts/wb-graph-checks.js +754 -0
- package/src/claude/scripts/wb-render.js +6 -11
- package/src/claude/scripts/wb-skeleton-check.js +99 -0
- package/src/claude/scripts/wb-validate.js +49 -655
- package/src/claude/scripts/wbs-assembler.js +368 -0
- package/src/claude/skills/implement-feature/SKILL.md +12 -6
- package/src/claude/workflows/pm-phase1.js +342 -16
- package/src/claude/workflows/pm-phase2.js +277 -14
package/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,34 @@
|
|
|
1
1
|
## 0.1.4 (2026-07-21)
|
|
2
|
+
## [0.18.0](https://github.com/dtlab-tech/ai-toolkit/compare/v0.17.5...v0.18.0) (2026-10-19)
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
* **planning-pipeline:** split Work Breakdown and Requirements generation into skeleton+per-item passes ([f7e7b66](https://github.com/dtlab-tech/ai-toolkit/commit/f7e7b66efe94a860bbd867402a250c5d92d56f4a))
|
|
8
|
+
* **pm-phase1/pm-phase2:** split-only document generation with on-demand assembly ([40d8700](https://github.com/dtlab-tech/ai-toolkit/commit/40d87007d2125789c7943348ee4000467bffc882))
|
|
9
|
+
* **pm-phase1:** split Tech-Spec generation into skeleton+per-component passes ([a42a83c](https://github.com/dtlab-tech/ai-toolkit/commit/a42a83c9413275888c7e0fa5bfae80a165da3d71))
|
|
10
|
+
* **pm-phase1:** tag Tech-Spec File Inventory with AC IDs and extend the traceability matrix ([4a15510](https://github.com/dtlab-tech/ai-toolkit/commit/4a15510c4d2da110445976d1b9586b6d45252c6f))
|
|
11
|
+
* **pm-phase2:** render an AC-to-Task traceability matrix at Gate 2 ([d975942](https://github.com/dtlab-tech/ai-toolkit/commit/d9759423771454a8d677f747bc0d4fc1e00de375))
|
|
12
|
+
* **templates:** move the FTR-020 doc templates into the toolkit and make generation use them ([de7ffca](https://github.com/dtlab-tech/ai-toolkit/commit/de7ffca19b42ae324d8c8f8460cc9aeda23d8298))
|
|
13
|
+
* traceability matrix, template relocation, split-only doc generation (FTR-025) ([bf17caa](https://github.com/dtlab-tech/ai-toolkit/commit/bf17caa1517fa28a4f28b3efb44f7a327661e184))
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
### Bug Fixes
|
|
17
|
+
|
|
18
|
+
* **pm-phase1:** host-compute each use case's Related Business Rules/Acceptance Criteria ([507ecfa](https://github.com/dtlab-tech/ai-toolkit/commit/507ecfa94cb8094049a3543dbf44d47c2ea38f80))
|
|
19
|
+
* **tech-spec-assembler:** make the component Change/Tests heading scan fence-aware ([90af9ca](https://github.com/dtlab-tech/ai-toolkit/commit/90af9ca0585d3280ee12a97d3f745bae7de5fe69))
|
|
20
|
+
* **wb-graph-checks:** scope AC-task validation by a phase's own sourceUC, not its ID ([fab14cb](https://github.com/dtlab-tech/ai-toolkit/commit/fab14cbcb2f4fc180e5b2bb234dad25a5d7a2b61))
|
|
21
|
+
* **wbs:** wire the FTR-020 phase-detail template into real WB generation; fix a second sourceUC-drop ([54ed68e](https://github.com/dtlab-tech/ai-toolkit/commit/54ed68e5921e271a8b6ba4c54b0db748303648b1))
|
|
22
|
+
|
|
23
|
+
## [0.17.5](https://github.com/dtlab-tech/ai-toolkit/compare/v0.17.4...v0.17.5) (2026-10-13)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
### Bug Fixes
|
|
27
|
+
|
|
28
|
+
* **pm-phase1:** detect truncated Requirements/Tech-Spec instead of silently accepting them ([0783fe1](https://github.com/dtlab-tech/ai-toolkit/commit/0783fe1639258ea9701bffc647b9d0a54a85d3cd))
|
|
29
|
+
* **workflow-control, pm-phase1:** retry transient API errors; catch truncated Gate 1 docs ([47d4f2c](https://github.com/dtlab-tech/ai-toolkit/commit/47d4f2c47f79ac62b5247b44aac13dd2c80a33ad))
|
|
30
|
+
* **workflow-control:** retry worker dispatch on transient CLI/SDK API errors ([d75d02b](https://github.com/dtlab-tech/ai-toolkit/commit/d75d02b866a51ffde51bb276fdf21a60bd38c578))
|
|
31
|
+
|
|
2
32
|
## [0.17.4](https://github.com/dtlab-tech/ai-toolkit/compare/v0.17.3...v0.17.4) (2026-10-13)
|
|
3
33
|
|
|
4
34
|
|
package/lib/agent-registry.js
CHANGED
|
@@ -168,6 +168,19 @@ const CATALOG = [
|
|
|
168
168
|
deprecationTarget: null,
|
|
169
169
|
platforms: ['claude'],
|
|
170
170
|
},
|
|
171
|
+
{
|
|
172
|
+
agentId: 'gaia.agent.planner.requirements-use-case',
|
|
173
|
+
nativeNames: { claude: 'gaia-generate-requirements-use-case' },
|
|
174
|
+
relativeInstallPath: '.claude/agents/gaia-generate-requirements-use-case.md',
|
|
175
|
+
role: 'planner',
|
|
176
|
+
type: 'requirements',
|
|
177
|
+
authorisedPhases: ['planning'],
|
|
178
|
+
allowedPipelines: ['implement-feature'],
|
|
179
|
+
minimumToolkitVersion: '0.13.0',
|
|
180
|
+
deprecated: false,
|
|
181
|
+
deprecationTarget: null,
|
|
182
|
+
platforms: ['claude'],
|
|
183
|
+
},
|
|
171
184
|
{
|
|
172
185
|
agentId: 'gaia.agent.planner.tech-spec',
|
|
173
186
|
nativeNames: { claude: 'gaia-generate-tech-spec' },
|
|
@@ -181,6 +194,19 @@ const CATALOG = [
|
|
|
181
194
|
deprecationTarget: null,
|
|
182
195
|
platforms: ['claude'],
|
|
183
196
|
},
|
|
197
|
+
{
|
|
198
|
+
agentId: 'gaia.agent.planner.tech-spec-component',
|
|
199
|
+
nativeNames: { claude: 'gaia-generate-tech-spec-component' },
|
|
200
|
+
relativeInstallPath: '.claude/agents/gaia-generate-tech-spec-component.md',
|
|
201
|
+
role: 'planner',
|
|
202
|
+
type: 'tech-spec',
|
|
203
|
+
authorisedPhases: ['planning'],
|
|
204
|
+
allowedPipelines: ['implement-feature'],
|
|
205
|
+
minimumToolkitVersion: '0.13.0',
|
|
206
|
+
deprecated: false,
|
|
207
|
+
deprecationTarget: null,
|
|
208
|
+
platforms: ['claude'],
|
|
209
|
+
},
|
|
184
210
|
{
|
|
185
211
|
agentId: 'gaia.agent.planner.work-breakdown',
|
|
186
212
|
nativeNames: { claude: 'gaia-generate-work-breakdown' },
|
|
@@ -194,6 +220,19 @@ const CATALOG = [
|
|
|
194
220
|
deprecationTarget: null,
|
|
195
221
|
platforms: ['claude'],
|
|
196
222
|
},
|
|
223
|
+
{
|
|
224
|
+
agentId: 'gaia.agent.planner.work-breakdown-task',
|
|
225
|
+
nativeNames: { claude: 'gaia-generate-work-breakdown-task' },
|
|
226
|
+
relativeInstallPath: '.claude/agents/gaia-generate-work-breakdown-task.md',
|
|
227
|
+
role: 'planner',
|
|
228
|
+
type: 'work-breakdown',
|
|
229
|
+
authorisedPhases: ['planning'],
|
|
230
|
+
allowedPipelines: ['implement-feature'],
|
|
231
|
+
minimumToolkitVersion: '0.13.0',
|
|
232
|
+
deprecated: false,
|
|
233
|
+
deprecationTarget: null,
|
|
234
|
+
platforms: ['claude'],
|
|
235
|
+
},
|
|
197
236
|
{
|
|
198
237
|
agentId: 'gaia.agent.planner.validate-feature-docs',
|
|
199
238
|
nativeNames: { claude: 'gaia-validate-feature-docs' },
|
package/lib/workflow-control.js
CHANGED
|
@@ -169,28 +169,56 @@ function createControl(options) {
|
|
|
169
169
|
});
|
|
170
170
|
(options.log || (() => {}))('Worker evidence: ' + evidence.file);
|
|
171
171
|
try {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
172
|
+
// Retry a bounded number of times, but ONLY for a recognizable transient
|
|
173
|
+
// infrastructure failure — a CLI/SDK-level "API Error: ..." (stream idle
|
|
174
|
+
// timeout, overload, etc.), never a permission denial, schema violation,
|
|
175
|
+
// or any other deterministic content failure, which would just fail the
|
|
176
|
+
// same way again. Confirmed safe to retry: every agent dispatched through
|
|
177
|
+
// this path is read-only by design (no Write tool — see this function's
|
|
178
|
+
// own comment on why outputs are host-written, not agent-written; any
|
|
179
|
+
// Bash access granted is explicitly scoped to read-only assessment), so
|
|
180
|
+
// there is no partial side effect from a dead stream to clean up before
|
|
181
|
+
// retrying. Token usage from EVERY attempt is accumulated — a failed
|
|
182
|
+
// attempt still burns real output tokens before the stream dies — and
|
|
183
|
+
// each attempt's outcome is kept in evidence for diagnosing a recurring
|
|
184
|
+
// pattern like this one, rather than only ever seeing the last attempt.
|
|
185
|
+
let result;
|
|
186
|
+
let accumulatedTokens = 0;
|
|
187
|
+
const attempts = [];
|
|
188
|
+
for (let attempt = 1; attempt <= WORKER_MAX_ATTEMPTS; attempt++) {
|
|
189
|
+
result = await (options.dispatch || spawnClaudeAgent)({
|
|
190
|
+
claudePath: options.claudePath, cwd: root, args: cliArgs, prompt,
|
|
191
|
+
taskTimeoutMs: options.taskTimeoutMs || 1800000,
|
|
192
|
+
});
|
|
193
|
+
const usage = result.result?.usage;
|
|
194
|
+
const counts = usage && [usage.input_tokens, usage.output_tokens,
|
|
195
|
+
usage.cache_read_input_tokens ?? 0, usage.cache_creation_input_tokens ?? 0];
|
|
196
|
+
const tokens = counts && counts.every(n => Number.isInteger(n) && n >= 0)
|
|
197
|
+
? counts.reduce((a, b) => a + b, 0) : null;
|
|
198
|
+
const attemptTokens = Number.isSafeInteger(tokens) && tokens > 0 ? tokens : null;
|
|
199
|
+
if (attemptTokens) accumulatedTokens += attemptTokens;
|
|
200
|
+
attempts.push({ attempt, exitCode: result.exitCode, isError: result.result?.is_error ?? null,
|
|
201
|
+
resultPreview: typeof result.result?.result === 'string' ? result.result.result.slice(0, 300) : null,
|
|
202
|
+
tokens: attemptTokens });
|
|
203
|
+
evidence.save({ attempts });
|
|
204
|
+
if (!_isTransientWorkerApiError(result) || attempt === WORKER_MAX_ATTEMPTS) break;
|
|
205
|
+
await _sleep(WORKER_RETRY_BACKOFF_MS[attempt - 1]);
|
|
206
|
+
}
|
|
176
207
|
// Count usage before any business/protocol check, including denied tools.
|
|
177
|
-
|
|
178
|
-
const counts = usage && [usage.input_tokens, usage.output_tokens,
|
|
179
|
-
usage.cache_read_input_tokens ?? 0, usage.cache_creation_input_tokens ?? 0];
|
|
180
|
-
const tokens = counts && counts.every(n => Number.isInteger(n) && n >= 0)
|
|
181
|
-
? counts.reduce((a, b) => a + b, 0) : null;
|
|
182
|
-
measuredTokens = Number.isSafeInteger(tokens) && tokens > 0 ? tokens : null;
|
|
208
|
+
measuredTokens = accumulatedTokens > 0 ? accumulatedTokens : null;
|
|
183
209
|
spent += measuredTokens || 0;
|
|
184
210
|
tokenLedger.push({ agent: identity.nativeName, model: definition.model,
|
|
185
|
-
phase_delta_tokens: measuredTokens, usage: usage || null, evidence_path: evidence.file });
|
|
186
|
-
evidence.save({ response: result });
|
|
211
|
+
phase_delta_tokens: measuredTokens, usage: result.result?.usage || null, evidence_path: evidence.file });
|
|
212
|
+
evidence.save({ response: result, attempts });
|
|
187
213
|
const denials = result.result?.permission_denials;
|
|
188
214
|
if (Array.isArray(denials) && denials.length) {
|
|
189
215
|
const tools = [...new Set(denials.map(d => d.tool_name || 'unknown'))].join(', ');
|
|
190
216
|
throw new Error('Worker permission denied: ' + id + '; tools: ' + tools);
|
|
191
217
|
}
|
|
192
218
|
if (result.exitCode !== 0 || result.parseError || result.timedOut ||
|
|
193
|
-
!result.result || result.result.is_error !== false)
|
|
219
|
+
!result.result || result.result.is_error !== false) {
|
|
220
|
+
throw new Error('Worker failed: ' + id + (attempts.length > 1 ? ' (after ' + attempts.length + ' attempts)' : ''));
|
|
221
|
+
}
|
|
194
222
|
let payload = opts.schema ? result.result.structured_output : result.result.result;
|
|
195
223
|
let usedTextFallback = false;
|
|
196
224
|
// The CLI's structured-output extraction is turn-bound: it only populates
|
|
@@ -305,6 +333,30 @@ function createControl(options) {
|
|
|
305
333
|
return api;
|
|
306
334
|
}
|
|
307
335
|
|
|
336
|
+
// worker()'s retry policy for transient CLI/SDK-level infrastructure failures (e.g. "API
|
|
337
|
+
// Error: Stream idle timeout - no chunks received") — confirmed against a real pipeline run
|
|
338
|
+
// that failed 3/3 identically with no automatic recovery, forcing the whole workflow to be
|
|
339
|
+
// retried by hand from the CLI. 3 total attempts, waiting 5s then 20s between them: long
|
|
340
|
+
// enough for a brief network stall to clear, short enough not to turn a real, deterministic
|
|
341
|
+
// failure into a multi-minute stall before it's reported.
|
|
342
|
+
const WORKER_MAX_ATTEMPTS = 3;
|
|
343
|
+
const WORKER_RETRY_BACKOFF_MS = [5000, 20000];
|
|
344
|
+
|
|
345
|
+
function _sleep(ms) {
|
|
346
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
// Recognizes ONLY the CLI/SDK's own infrastructure-error reporting convention — never a
|
|
350
|
+
// blanket "any failure is retryable" rule. A permission denial, a schema violation, or any
|
|
351
|
+
// other content-level failure will fail the exact same way on a retry, so retrying those
|
|
352
|
+
// would only burn tokens and time for no benefit; this checks specifically for the "API
|
|
353
|
+
// Error:" prefix the CLI uses for its own transport/provider-level errors, which (unlike
|
|
354
|
+
// those) are plausibly transient.
|
|
355
|
+
function _isTransientWorkerApiError(result) {
|
|
356
|
+
return !!(result && result.result && result.result.is_error === true &&
|
|
357
|
+
typeof result.result.result === 'string' && /^API Error:/i.test(result.result.result.trim()));
|
|
358
|
+
}
|
|
359
|
+
|
|
308
360
|
// A model asked to emit a JSON blob as part of a chat reply (rather than through a real
|
|
309
361
|
// serializer, i.e. whenever structured_output didn't get populated and extraction has to
|
|
310
362
|
// recover the payload from free text) is prone to one specific, well-understood defect: a
|
package/package.json
CHANGED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gaia-generate-requirements-use-case
|
|
3
|
+
description: "Generates one use case's full detail (flows, postconditions) from its index-table row. Input: UC row + compact sibling index + feature.md"
|
|
4
|
+
model: haiku
|
|
5
|
+
tools: Read, Glob, Grep
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Generate One Use Case's Detail
|
|
9
|
+
|
|
10
|
+
Given one use case's index-table row (ID, Title, Actor, Priority), the compact index of every
|
|
11
|
+
other use case in this feature, and `feature.md`, produce that use case's full detail: the field
|
|
12
|
+
table plus Main flow, Alternative flows, Error flows, and Postconditions — exactly the Section 2
|
|
13
|
+
content `gaia-generate-requirements` produced inline before this feature (FTR-021) split it out
|
|
14
|
+
into one bounded call per use case.
|
|
15
|
+
|
|
16
|
+
## Input
|
|
17
|
+
|
|
18
|
+
The host supplies, in the dispatch prompt:
|
|
19
|
+
1. This use case's own index-table row, verbatim: `id`, `title`, `actor`, `priority`.
|
|
20
|
+
2. The compact full use-case index: every use case's `id` + `title` + `actor` only (for
|
|
21
|
+
cross-use-case awareness — so this use case's flow doesn't silently assume another use case's
|
|
22
|
+
behavior without naming it).
|
|
23
|
+
3. The path to `feature.md` — read it in full before proceeding, to ground this use case's flow
|
|
24
|
+
in the feature's actual described behavior rather than inventing detail the row alone would
|
|
25
|
+
not carry.
|
|
26
|
+
|
|
27
|
+
You do not read `req/index.md` yourself and you never decide which use cases exist — that is
|
|
28
|
+
already fixed by the skeleton call that produced the row you were given.
|
|
29
|
+
|
|
30
|
+
Read `.claude/scripts/templates/gaia-use-case-template.md` before writing your response for the
|
|
31
|
+
canonical field-table/flow structure. Note: that template also shows "Related Business Rules"/
|
|
32
|
+
"Related Acceptance Criteria" cross-reference lines at the end of the file — do NOT produce them
|
|
33
|
+
yourself. The host computes both, mechanically, from `req/index.md`'s own Business Rules/
|
|
34
|
+
Acceptance Criteria tables, and appends them to your response after you return it — you are not
|
|
35
|
+
given that table data (and must not re-read `req/index.md` yourself to get it), so any version you
|
|
36
|
+
wrote would risk being wrong or duplicated. The Output section below is your actual, complete
|
|
37
|
+
output contract; stop after Postconditions.
|
|
38
|
+
|
|
39
|
+
## Mandatory instruction
|
|
40
|
+
|
|
41
|
+
Restate the given **Title**, **Actor**, and **Priority** exactly as given in your field table —
|
|
42
|
+
do not reword, re-derive, or second-guess them. Your only new content is **Preconditions**,
|
|
43
|
+
**Trigger**, **Main flow**, **Alternative flows**, **Error flows**, and **Postconditions**.
|
|
44
|
+
|
|
45
|
+
## Output
|
|
46
|
+
|
|
47
|
+
Return exactly this block as your final response, and nothing else (no preamble, no "here is the
|
|
48
|
+
use case", no Markdown code fence wrapping the whole thing) — you do not have a Write tool; the
|
|
49
|
+
host persists your response verbatim to `req/use-cases/{UC-ID}.md`:
|
|
50
|
+
|
|
51
|
+
```markdown
|
|
52
|
+
### {UC-ID}: {Title}
|
|
53
|
+
|
|
54
|
+
| Field | Value |
|
|
55
|
+
|-------|-------|
|
|
56
|
+
| Actor | {Actor} |
|
|
57
|
+
| Preconditions | ... |
|
|
58
|
+
| Trigger | ... |
|
|
59
|
+
| Priority | {Priority} |
|
|
60
|
+
|
|
61
|
+
**Main flow:**
|
|
62
|
+
1. Step 1
|
|
63
|
+
2. Step 2
|
|
64
|
+
3. ...
|
|
65
|
+
|
|
66
|
+
**Alternative flows:**
|
|
67
|
+
- [condition] → [behavior]
|
|
68
|
+
|
|
69
|
+
**Error flows:**
|
|
70
|
+
- [error condition] → [system response]
|
|
71
|
+
|
|
72
|
+
**Postconditions:**
|
|
73
|
+
- [expected state after completion]
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
If this use case has no alternative flows or no error flows worth documenting, write `- none`
|
|
77
|
+
under that heading rather than omitting the heading — every use case file keeps the same four
|
|
78
|
+
subsections, even when one is trivially empty, so a reader (or a future parser) never has to
|
|
79
|
+
guess whether a missing heading means "none" or "forgotten".
|
|
80
|
+
|
|
81
|
+
## Clarification Protocol
|
|
82
|
+
|
|
83
|
+
If `feature.md` is ambiguous or missing information needed to write a complete flow for this one
|
|
84
|
+
use case, do not guess or invent behavior. Write the flow as far as the source supports, and add
|
|
85
|
+
an explicit note under **Postconditions** naming the open gap (e.g. "Open question: `feature.md`
|
|
86
|
+
does not specify what happens if X") — the host owns surfacing unresolved gaps to the user at
|
|
87
|
+
Gate 1, this agent only has to avoid silently inventing an answer.
|
|
88
|
+
|
|
89
|
+
## Guidelines
|
|
90
|
+
|
|
91
|
+
- Write in **English**
|
|
92
|
+
- Be specific and testable — avoid vague steps like "the system processes the request"
|
|
93
|
+
- Include error scenarios and edge cases relevant to this one use case
|
|
94
|
+
- Derive all content strictly from `feature.md` and the given row — do not invent behavior not
|
|
95
|
+
described there
|
|
96
|
+
- Given/When/Then phrasing is not used here (that convention belongs to Section 7's Acceptance
|
|
97
|
+
Criteria, which the skeleton call already produced) — write flows as plain numbered steps
|
|
@@ -1,18 +1,30 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: gaia-generate-requirements
|
|
3
|
-
description: "Generates
|
|
3
|
+
description: "Generates the Requirements skeleton (everything except per-use-case flow detail) from a feature description. Input: path to feature.md"
|
|
4
4
|
model: haiku
|
|
5
5
|
tools: Read, Glob, Grep
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
# Generate Functional Requirements
|
|
8
|
+
# Generate Functional Requirements Skeleton
|
|
9
9
|
|
|
10
|
-
Given a feature description document, produce
|
|
10
|
+
Given a feature description document, produce the **Requirements skeleton**: every section of
|
|
11
|
+
the functional requirements document except each use case's own flow detail (preconditions,
|
|
12
|
+
trigger, main/alternative/error flows, postconditions). Section 2 (Use Cases) is reduced to an
|
|
13
|
+
index table only — one row per use case, no flow body. A separate call (one per use case,
|
|
14
|
+
dispatched by the host after this skeleton is accepted) fills in each use case's full detail from
|
|
15
|
+
the row you write here; your response is never the final document by itself, it is assembled
|
|
16
|
+
together with those per-use-case files afterward (FTR-021).
|
|
11
17
|
|
|
12
18
|
## Input
|
|
13
19
|
|
|
14
20
|
The user provides the path to a `feature.md` file. Read it in full before proceeding.
|
|
15
21
|
|
|
22
|
+
Also read `.claude/scripts/templates/gaia-requirements-index-template.md` before writing your
|
|
23
|
+
response — it is the canonical, authoritative structure for `req/index.md` (section order,
|
|
24
|
+
exact headings, table column contracts, and the parsing contract `req-skeleton-check.js`/
|
|
25
|
+
`req-assembler.js` rely on). The Output Structure section below summarizes it; the template
|
|
26
|
+
itself is the source of truth if the two ever disagree.
|
|
27
|
+
|
|
16
28
|
## Process
|
|
17
29
|
|
|
18
30
|
1. **Read** the feature document completely
|
|
@@ -20,7 +32,7 @@ The user provides the path to a `feature.md` file. Read it in full before procee
|
|
|
20
32
|
3. **Identify** all functional areas described
|
|
21
33
|
3. **Extract** actors, use cases, business rules, acceptance criteria
|
|
22
34
|
4. **Organize** into a structured requirements document
|
|
23
|
-
5. **Return** the
|
|
35
|
+
5. **Return** the skeleton as your final response — every section except each use case's flow detail. You do not have a Write tool; the host persists your response to `req/index.md` verbatim. Do not attempt to write any file yourself, and do not write a use case's flow body inline in Section 2 — list it in the index table only.
|
|
24
36
|
|
|
25
37
|
## Output Filename (for your reference only — you do not write this file)
|
|
26
38
|
|
|
@@ -61,30 +73,13 @@ What is in scope and out of scope.
|
|
|
61
73
|
|
|
62
74
|
## 2. Use Cases
|
|
63
75
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
| Field | Value |
|
|
69
|
-
|-------|-------|
|
|
70
|
-
| Actor | ... |
|
|
71
|
-
| Preconditions | ... |
|
|
72
|
-
| Trigger | ... |
|
|
73
|
-
| Priority | Must / Should / Could |
|
|
74
|
-
|
|
75
|
-
**Main flow:**
|
|
76
|
-
1. Step 1
|
|
77
|
-
2. Step 2
|
|
78
|
-
3. ...
|
|
79
|
-
|
|
80
|
-
**Alternative flows:**
|
|
81
|
-
- [condition] → [behavior]
|
|
82
|
-
|
|
83
|
-
**Error flows:**
|
|
84
|
-
- [error condition] → [system response]
|
|
76
|
+
| UC ID | Title | Actor | Priority | File |
|
|
77
|
+
|-------|-------|-------|----------|------|
|
|
78
|
+
| UC-XX | [Title] | [Actor] | Must / Should / Could | use-cases/UC-XX.md |
|
|
85
79
|
|
|
86
|
-
|
|
87
|
-
|
|
80
|
+
> One row per use case you identify. Do NOT write the use case's flow here — a separate call
|
|
81
|
+
> generates each use case's full detail (preconditions, trigger, main/alternative/error flows,
|
|
82
|
+
> postconditions) from this row.
|
|
88
83
|
|
|
89
84
|
## 3. Business Rules
|
|
90
85
|
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: gaia-generate-tech-spec-component
|
|
3
|
+
description: "Generates one component's full technical design (Change, Algorithm/Schema, Tests) from its index-table row. Input: component row + compact sibling index + feature.md/Requirements excerpt"
|
|
4
|
+
model: haiku
|
|
5
|
+
tools: Read, Glob, Grep
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Generate One Component's Technical Design
|
|
9
|
+
|
|
10
|
+
Given one component's index-table row (Path, Domain, Addresses), the compact index of every
|
|
11
|
+
other component in this feature, and the relevant `feature.md`/Requirements excerpt, produce that
|
|
12
|
+
component's full technical design: `Change` (what changes and why), its actual design (whichever
|
|
13
|
+
of the monolithic template's Backend/Frontend/External-Integration shape matches this one file's
|
|
14
|
+
real nature — real code/schema, not prose), and `Tests` (the specific test file(s) and cases for
|
|
15
|
+
this component). This is `gaia-generate-tech-spec`'s per-component counterpart (FTR-024) — that
|
|
16
|
+
agent decides the skeleton (file list, feature-wide sections) once; this agent fills in one row's
|
|
17
|
+
own detail, one call per component.
|
|
18
|
+
|
|
19
|
+
## Input
|
|
20
|
+
|
|
21
|
+
The host supplies, in the dispatch prompt:
|
|
22
|
+
1. This component's own index-table row, verbatim: `Path`, `Domain`, `Addresses`.
|
|
23
|
+
2. The compact full component index: every component's `Path` + `Domain` only (cross-component
|
|
24
|
+
awareness — e.g. "does another component already define this DTO?").
|
|
25
|
+
3. The relevant excerpt of `feature.md`/`{PREFIX}-Requirements.md` (host-selected) — read it, but
|
|
26
|
+
do not re-search the full documents yourself.
|
|
27
|
+
|
|
28
|
+
You do not read `spec/index.md` yourself and you never decide which components exist — that is
|
|
29
|
+
already fixed by the skeleton call that produced the row you were given.
|
|
30
|
+
|
|
31
|
+
Read `.claude/scripts/templates/gaia-component-template.md` before writing your response — it is
|
|
32
|
+
the canonical, authoritative structure for your output (Change/design-body/Tests, and the parsing
|
|
33
|
+
contract `tech-spec-assembler.js`'s `parseComponentDetail` relies on). The Output section below is
|
|
34
|
+
a summary; the template itself is the source of truth if the two ever disagree.
|
|
35
|
+
|
|
36
|
+
## Mandatory instruction
|
|
37
|
+
|
|
38
|
+
Restate the given **Path**, **Domain**, and **Addresses** exactly as given — do not reword,
|
|
39
|
+
re-derive, or second-guess them. Your only new content is this component's own `Change`
|
|
40
|
+
description, its actual design, and its `Tests` section.
|
|
41
|
+
|
|
42
|
+
## Output
|
|
43
|
+
|
|
44
|
+
Return exactly this block as your final response, and nothing else (no preamble, no "here is the
|
|
45
|
+
component", no Markdown code fence wrapping the whole thing) — you do not have a Write tool; the
|
|
46
|
+
host persists your response verbatim to `spec/components/{fileSlug}.md`:
|
|
47
|
+
|
|
48
|
+
```markdown
|
|
49
|
+
# {Path} — {New | Modified}
|
|
50
|
+
|
|
51
|
+
## Change
|
|
52
|
+
|
|
53
|
+
<one paragraph: what changes about this file and why — name the specific functions/sections
|
|
54
|
+
affected, not just "this file is updated to support the new feature". If New: what it exports and
|
|
55
|
+
the shape of its inputs/outputs. If Modified: what specifically is added, replaced, or removed,
|
|
56
|
+
and what is explicitly left unchanged.>
|
|
57
|
+
|
|
58
|
+
## {Algorithm | Data Model | Service Interface | Component Props | whichever name fits this
|
|
59
|
+
component's own real nature — pick one, do not invent multiple competing headings}
|
|
60
|
+
|
|
61
|
+
<real pseudocode or real code, not a prose description of "what it does". If this component
|
|
62
|
+
relocates logic from an existing file, name the exact source file and line ranges if known.>
|
|
63
|
+
|
|
64
|
+
## Tests
|
|
65
|
+
|
|
66
|
+
<the specific test file(s) this component's change requires, and the key cases that matter — not
|
|
67
|
+
a generic "add tests for X".>
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
If this component genuinely needs no design content beyond `Change` (e.g. a trivial
|
|
71
|
+
configuration file), omit the middle heading entirely rather than inventing content — but
|
|
72
|
+
`Change` and `Tests` are always required; `tech-spec-assembler.js` requires both of those two
|
|
73
|
+
headings to exist, in that relative order, to parse this file correctly.
|
|
74
|
+
|
|
75
|
+
## Clarification Protocol
|
|
76
|
+
|
|
77
|
+
If the given excerpt is ambiguous or missing information needed to write this one component's
|
|
78
|
+
complete design, do not guess or invent behavior. Design as far as the source supports, and add
|
|
79
|
+
an explicit note under `Change` naming the open gap — the host owns surfacing unresolved gaps to
|
|
80
|
+
the user at Gate 1, this agent only has to avoid silently inventing an answer.
|
|
81
|
+
|
|
82
|
+
## Guidelines
|
|
83
|
+
|
|
84
|
+
- Write in **English**
|
|
85
|
+
- Include actual code snippets for key definitions (models, DTOs, interfaces, components) using
|
|
86
|
+
the project's real language and conventions — reference `AGENTS.md`'s patterns if the relevant
|
|
87
|
+
excerpt doesn't already establish them
|
|
88
|
+
- Do not include implementation code for every method — focus on interfaces, contracts, and key
|
|
89
|
+
algorithms, the same restraint `gaia-generate-tech-spec` already applies
|
|
90
|
+
- For external API calls, document the full request/response including headers and error
|
|
91
|
+
scenarios, if this component is the one implementing that integration
|
|
92
|
+
- Derive all content strictly from the given row and excerpt — do not invent behavior not
|
|
93
|
+
described there
|