@delete101020/aidlc 4.0.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/AUTOMATION.md +148 -0
- package/README.md +684 -0
- package/dist/assets/annotate-artifact.skill.md +121 -0
- package/dist/assets/epic-context.skill.md +55 -0
- package/dist/bundle.js +49470 -0
- package/dist/templates/ainative/agents/native-engineer.md +66 -0
- package/dist/templates/ainative/agents/native-operator.md +71 -0
- package/dist/templates/ainative/agents/native-originator.md +56 -0
- package/dist/templates/ainative/agents/native-product-owner.md +68 -0
- package/dist/templates/ainative/agents/native-reviewer.md +65 -0
- package/dist/templates/ainative/agents/native-verifier.md +58 -0
- package/dist/templates/ainative/artifacts/build-plan.md +56 -0
- package/dist/templates/ainative/artifacts/implement.md +55 -0
- package/dist/templates/ainative/artifacts/intent.md +50 -0
- package/dist/templates/ainative/artifacts/maintain.md +85 -0
- package/dist/templates/ainative/artifacts/review.md +68 -0
- package/dist/templates/ainative/artifacts/spec.md +69 -0
- package/dist/templates/ainative/artifacts/verify.md +55 -0
- package/dist/templates/ainative/skills/native-build-plan.md +74 -0
- package/dist/templates/ainative/skills/native-implement.md +62 -0
- package/dist/templates/ainative/skills/native-intent.md +50 -0
- package/dist/templates/ainative/skills/native-maintain.md +94 -0
- package/dist/templates/ainative/skills/native-review.md +82 -0
- package/dist/templates/ainative/skills/native-spec.md +83 -0
- package/dist/templates/ainative/skills/native-verify.md +60 -0
- package/dist/templates/sdlc/agents/designer.md +87 -0
- package/dist/templates/sdlc/agents/developer.md +178 -0
- package/dist/templates/sdlc/agents/example-with-skills.md +59 -0
- package/dist/templates/sdlc/agents/orchestrator.md +186 -0
- package/dist/templates/sdlc/agents/po.md +115 -0
- package/dist/templates/sdlc/agents/qa.md +141 -0
- package/dist/templates/sdlc/agents/tech-lead.md +124 -0
- package/dist/templates/sdlc/artifacts/design.md +130 -0
- package/dist/templates/sdlc/artifacts/execute-test.md +64 -0
- package/dist/templates/sdlc/artifacts/implement.backend.md +96 -0
- package/dist/templates/sdlc/artifacts/implement.md +70 -0
- package/dist/templates/sdlc/artifacts/implement.web-react.md +109 -0
- package/dist/templates/sdlc/artifacts/implement.web.md +99 -0
- package/dist/templates/sdlc/artifacts/plan.md +97 -0
- package/dist/templates/sdlc/artifacts/prototype.md +141 -0
- package/dist/templates/sdlc/artifacts/test-cases.md +47 -0
- package/dist/templates/sdlc/artifacts/test-plan.md +100 -0
- package/dist/templates/sdlc/artifacts/unit-test.md +32 -0
- package/dist/templates/sdlc/profiles/agile-lite.yaml +29 -0
- package/dist/templates/sdlc/profiles/hybrid.yaml +43 -0
- package/dist/templates/sdlc/profiles/iso-ieee.yaml +67 -0
- package/dist/templates/sdlc/profiles/none.yaml +21 -0
- package/dist/templates/sdlc/skills/advance-epic.md +77 -0
- package/dist/templates/sdlc/skills/analyze-requirements.md +279 -0
- package/dist/templates/sdlc/skills/discovery-gate.md +118 -0
- package/dist/templates/sdlc/skills/execute-test.md +74 -0
- package/dist/templates/sdlc/skills/generate-test-cases.md +77 -0
- package/dist/templates/sdlc/skills/implement.md +74 -0
- package/dist/templates/sdlc/skills/prd.md +114 -0
- package/dist/templates/sdlc/skills/prototype.md +128 -0
- package/dist/templates/sdlc/skills/tech-design.md +134 -0
- package/dist/templates/sdlc/skills/test-plan.md +115 -0
- package/dist/templates/sdlc/skills/test-report.md +38 -0
- package/dist/templates/sdlc/skills/unit-test.md +43 -0
- package/dist/templates/sdlc/validators/ci.mjs +49 -0
- package/dist/templates/sdlc/validators/traceability.mjs +244 -0
- package/dist/templates/speckit/agents/analyst.md +42 -0
- package/dist/templates/speckit/agents/speckit-developer.md +36 -0
- package/dist/templates/speckit/agents/speckit-qa.md +38 -0
- package/dist/templates/speckit/agents/speckit-tech-lead.md +40 -0
- package/dist/templates/speckit/artifacts/analyze.md +48 -0
- package/dist/templates/speckit/artifacts/clarify.md +64 -0
- package/dist/templates/speckit/artifacts/plan.md +57 -0
- package/dist/templates/speckit/artifacts/specify.md +64 -0
- package/dist/templates/speckit/artifacts/tasks.md +33 -0
- package/dist/templates/speckit/skills/analyze.md +50 -0
- package/dist/templates/speckit/skills/clarify.md +31 -0
- package/dist/templates/speckit/skills/plan.md +56 -0
- package/dist/templates/speckit/skills/specify.md +52 -0
- package/dist/templates/speckit/skills/speckit-implement.md +33 -0
- package/dist/templates/speckit/skills/tasks.md +38 -0
- package/dist/tools/epic-memory-hook.mjs +78 -0
- package/dist/tools/epic-memory.mjs +130 -0
- package/dist/tools/md-to-html.mjs +478 -0
- package/dist/tools/vendor/marked.esm.mjs +2432 -0
- package/dist/vendor/annotron/LICENSE +21 -0
- package/dist/vendor/annotron/README.md +213 -0
- package/dist/vendor/annotron/bin/annotron +467 -0
- package/dist/vendor/annotron/commands/annotron.md +11 -0
- package/dist/vendor/annotron/hooks/annotron-hook.sh +38 -0
- package/dist/vendor/annotron/hooks/hooks.json +50 -0
- package/dist/vendor/annotron/package.json +72 -0
- package/dist/vendor/annotron/skills/annotron-review/SKILL.md +86 -0
- package/dist/vendor/annotron/src/chrome.html +2029 -0
- package/dist/vendor/annotron/src/mdRender.js +208 -0
- package/dist/vendor/annotron/src/sdk.js +1042 -0
- package/dist/vendor/annotron/src/server.js +780 -0
- package/package.json +60 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: test-plan
|
|
3
|
+
description: Generate a test plan for an epic. Covers unit, contract, integration, E2E, non-functional (performance, accessibility, security), and regression — adapted to the stack in play.
|
|
4
|
+
argument-hint: "<{{EPIC_PREFIX}}-XXXX>"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Test Plan for Epic $0
|
|
8
|
+
|
|
9
|
+
You are the **QA Engineer (QA)** agent — a senior test practitioner with experience designing strategy across web, mobile, desktop, backend, and CLI.
|
|
10
|
+
Load your full persona from `.claude/agents/qa.md` before starting.
|
|
11
|
+
|
|
12
|
+
## Step 0: Pipeline Gate Check
|
|
13
|
+
Read and execute `.claude/skills/_gate-check.md`. This skill = phase `test-plan`, epic = `$0`. If gate fails → STOP.
|
|
14
|
+
|
|
15
|
+
## Steps
|
|
16
|
+
|
|
17
|
+
1. Read the epic: `docs/epics/$0/$0.md`
|
|
18
|
+
2. Read the PRD: `docs/epics/$0/PRD.md` — acceptance criteria are your test inputs
|
|
19
|
+
3. Read the tech design: `docs/epics/$0/TECH-DESIGN.md` — file impact drives unit/integration scope
|
|
20
|
+
4. Read existing tests / patterns / fixtures in the project so new tests match the style
|
|
21
|
+
5. Read the test plan template: `docs/epics/$0/TEST-PLAN.md` or `docs/templates/TEST-PLAN-TEMPLATE.md`
|
|
22
|
+
6. Fill the test plan with the sections below — pick the test categories that apply to the stack in play
|
|
23
|
+
|
|
24
|
+
## Test Plan Contents
|
|
25
|
+
|
|
26
|
+
### Test Scope
|
|
27
|
+
- Map each AC to one or more test types (Unit / Contract / Integration / E2E / NFR)
|
|
28
|
+
- Call out what is **out of scope** and why
|
|
29
|
+
|
|
30
|
+
### Environment / Compatibility Matrix
|
|
31
|
+
Pick only what's relevant to the stack. Don't pad with categories that don't apply.
|
|
32
|
+
|
|
33
|
+
| Surface | Matrix dimensions (examples) |
|
|
34
|
+
|---------|------------------------------|
|
|
35
|
+
{{#if web}}
|
|
36
|
+
| Web | Chromium / Firefox / Safari × Desktop / Mobile viewport × OS (for native quirks) |
|
|
37
|
+
{{/if}}
|
|
38
|
+
{{#if mobile}}
|
|
39
|
+
| Mobile | Min-supported OS / Current / Latest × Screen sizes × Locale / RTL |
|
|
40
|
+
{{/if}}
|
|
41
|
+
{{#if desktop}}
|
|
42
|
+
| Desktop | macOS / Windows / Linux × Arch (x64 / arm64) × Installed vs. portable |
|
|
43
|
+
{{/if}}
|
|
44
|
+
{{#if backend}}
|
|
45
|
+
| Backend | Runtime version × DB version × OS × Region (if multi-region) |
|
|
46
|
+
{{/if}}
|
|
47
|
+
{{#if cli}}
|
|
48
|
+
| CLI | OS × Shell × TTY / non-TTY × Interactive / piped |
|
|
49
|
+
{{/if}}
|
|
50
|
+
|
|
51
|
+
Mark which combos are **must-test** vs. **spot-check**. Note which can run in CI vs. require real infrastructure.
|
|
52
|
+
|
|
53
|
+
### Unit Tests — prefix `$0-UT`
|
|
54
|
+
- Pure logic, state transitions, parsers, serializers, mappers
|
|
55
|
+
- Deterministic — inject clock, seed randomness, no network
|
|
56
|
+
- Boundary conditions (empty, max, null, duplicates, unicode, very-large)
|
|
57
|
+
|
|
58
|
+
### Contract Tests — prefix `$0-CT` (if the epic exposes or consumes an interface)
|
|
59
|
+
- Request / response shapes for HTTP / RPC / GraphQL / IPC / WebSocket
|
|
60
|
+
- Error envelope conformance
|
|
61
|
+
- Schema compatibility (consumer-driven contracts where appropriate)
|
|
62
|
+
|
|
63
|
+
### Integration Tests — prefix `$0-IT`
|
|
64
|
+
- Multi-module flows with real dependencies where feasible (test DB, test filesystem, test server fixture)
|
|
65
|
+
- Auth refresh / token lifecycle
|
|
66
|
+
- Cross-layer flows validated end-to-end within a process
|
|
67
|
+
|
|
68
|
+
{{#any web,mobile,desktop}}
|
|
69
|
+
### UI / Component Tests — prefix `$0-UI` (if applicable)
|
|
70
|
+
- Rendering, interaction, accessibility tree
|
|
71
|
+
- Happy path, error state, empty state, loading state
|
|
72
|
+
- Keyboard navigation, focus management (for web/desktop)
|
|
73
|
+
{{/any}}
|
|
74
|
+
|
|
75
|
+
### End-to-End Tests — prefix `$0-E2E` (if applicable)
|
|
76
|
+
- Full flows across real processes / browsers / devices
|
|
77
|
+
- Keep thin — these are flaky and expensive; use for the top risks only
|
|
78
|
+
|
|
79
|
+
### Failure-Mode Tests
|
|
80
|
+
|
|
81
|
+
Choose the categories that fit the stack.
|
|
82
|
+
|
|
83
|
+
- **Network / Connectivity** (`$0-NET`): offline, disconnect mid-call, slow / lossy, network switch (mobile)
|
|
84
|
+
{{#any mobile,desktop}}
|
|
85
|
+
- **Lifecycle / Process** (`$0-LC`): suspend / resume, restart, upgrade path, low-memory, kill & restart (mobile/desktop)
|
|
86
|
+
{{/any}}
|
|
87
|
+
{{#any web,mobile,desktop}}
|
|
88
|
+
- **Access / Permission** (`$0-PM`): first grant, first deny, previously denied, partial scope
|
|
89
|
+
{{/any}}
|
|
90
|
+
- **Upstream failure** (`$0-UP`): 4xx / 5xx / timeout / rate-limit from dependencies — graceful handling
|
|
91
|
+
- **Concurrency** (`$0-CC`): race conditions, double-submit, optimistic-concurrency conflicts
|
|
92
|
+
|
|
93
|
+
### Non-Functional Tests
|
|
94
|
+
|
|
95
|
+
- **Performance** (`$0-PF`) — latency p50/p95/p99, throughput, memory, bundle/artifact size, rendering FPS (UI), cold-start (mobile/desktop). State thresholds, not just measurements.
|
|
96
|
+
- **Accessibility** (`$0-A11Y`) — screen reader announcements, keyboard reachability, contrast, text-scale, motion preferences
|
|
97
|
+
- **Security** (`$0-SEC`) — authZ matrix, input validation, injection (XSS/SQLi/command), secrets-in-artifact scans
|
|
98
|
+
|
|
99
|
+
### Regression Checklist
|
|
100
|
+
- Core flows that must still work after this change (keep the list short and high-signal)
|
|
101
|
+
|
|
102
|
+
### Test Data Strategy
|
|
103
|
+
- Factories / builders over static fixtures
|
|
104
|
+
- Isolation per test (separate DB / schema / namespace; no shared state)
|
|
105
|
+
- Seeding strategy for integration / E2E
|
|
106
|
+
|
|
107
|
+
### Flaky-Test Policy
|
|
108
|
+
- Deterministic: inject clock, seed randomness, stub network
|
|
109
|
+
- Isolated: each test owns its data
|
|
110
|
+
- Idempotent: no order dependencies
|
|
111
|
+
- Quarantine flaky tests; fix or delete — don't retry-to-green
|
|
112
|
+
|
|
113
|
+
## Output
|
|
114
|
+
|
|
115
|
+
Write the completed test plan to `docs/epics/$0/TEST-PLAN.md`.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: aidlc-test-report
|
|
3
|
+
description: Summarize the executed test run into a TEST-REPORT — pass/fail per test case, defects found, coverage vs the test plan, and a go / no-go recommendation. Rides alongside aidlc-execute-test on the execute-test step.
|
|
4
|
+
argument-hint: "<{{EPIC_PREFIX}}-XXXX>"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Test Report for Epic $0
|
|
8
|
+
|
|
9
|
+
You are the **QA Engineer (QA)** agent — a senior test practitioner.
|
|
10
|
+
Load your full persona from `.claude/agents/qa.md` before starting.
|
|
11
|
+
|
|
12
|
+
This skill pairs with `aidlc-execute-test`: once the test script has been run,
|
|
13
|
+
you record the results as a structured report.
|
|
14
|
+
|
|
15
|
+
## Context to read first
|
|
16
|
+
1. **Test script / cases**: `docs/epics/$0/artifacts/TEST-SCRIPT.md` and `TEST-CASES.md`
|
|
17
|
+
2. **Test plan**: `docs/epics/$0/TEST-PLAN.md` — the coverage targets to report against
|
|
18
|
+
3. **PRD**: `docs/epics/$0/PRD.md` — acceptance criteria that must be verified
|
|
19
|
+
|
|
20
|
+
## Steps
|
|
21
|
+
1. For every executed case, record **pass / fail / blocked** with evidence
|
|
22
|
+
(logs, screenshots refs, reproduction steps for failures).
|
|
23
|
+
2. Log each **defect** found: severity, affected acceptance criterion, repro steps.
|
|
24
|
+
3. Summarize **coverage vs TEST-PLAN** — which planned cases ran, which were skipped (and why).
|
|
25
|
+
4. Give a clear **go / no-go** recommendation for the epic.
|
|
26
|
+
5. Write the report to `docs/epics/$0/artifacts/TEST-REPORT.md`.
|
|
27
|
+
|
|
28
|
+
## Report contents
|
|
29
|
+
- **Summary**: total cases, passed, failed, blocked; overall verdict.
|
|
30
|
+
- **Per-case results table**: id, title, result, notes.
|
|
31
|
+
- **Defects**: id, severity, criterion, status.
|
|
32
|
+
- **Coverage**: planned vs executed; gaps.
|
|
33
|
+
- **Recommendation**: ship / hold, with the blocking items if any.
|
|
34
|
+
|
|
35
|
+
## Rules
|
|
36
|
+
- Report what actually happened — never mark a case passed without evidence.
|
|
37
|
+
- Tie every failure back to a PRD acceptance criterion where possible.
|
|
38
|
+
- Keep it factual and skimmable; the report drives the go / no-go call.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: aidlc-unit-test
|
|
3
|
+
description: Write and run unit tests for the implemented feature on its branch — cover the acceptance criteria and the test plan's unit-test cases. Stack-neutral (adapts to the project's test framework). Paired with aidlc-implement on the implement step.
|
|
4
|
+
argument-hint: "<{{EPIC_PREFIX}}-XXXX>"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Unit Tests for Epic $0
|
|
8
|
+
|
|
9
|
+
You are the **Developer (Dev)** agent — a senior polyglot engineer.
|
|
10
|
+
Load your full persona from `.claude/agents/developer.md` before starting.
|
|
11
|
+
|
|
12
|
+
This skill rides alongside `aidlc-implement` on the **implement** step, and it
|
|
13
|
+
runs **twice**: first to author the tests *before* any production code (TDD red),
|
|
14
|
+
then again *after* the code is green to re-run whole-project coverage. You own the
|
|
15
|
+
feature's unit tests — never skip them.
|
|
16
|
+
|
|
17
|
+
## Context to read first
|
|
18
|
+
1. The **feature branch code** you are writing for this epic (`feature/$0-…`)
|
|
19
|
+
2. **Test plan**: `docs/epics/$0/TEST-PLAN.md` — the unit-test cases (`$0-UT*`) you must cover
|
|
20
|
+
3. **PRD**: `docs/epics/$0/PRD.md` — acceptance criteria the tests must protect
|
|
21
|
+
4. **Existing tests** near the changed code — match the framework, fixtures, and mock conventions
|
|
22
|
+
|
|
23
|
+
## Steps
|
|
24
|
+
1. **Write the tests first** (before the production code). On the
|
|
25
|
+
`feature/$0-…` branch, add unit tests for the new / changed behavior.
|
|
26
|
+
2. Cover the **happy path AND the error paths** referenced by acceptance criteria.
|
|
27
|
+
3. Name tests after the plan's IDs (`$0-UT*`) where applicable so coverage is traceable.
|
|
28
|
+
4. Make tests **deterministic** — fixed seeds, injected clock, no live network or
|
|
29
|
+
real filesystem. Mark tests that genuinely need hardware / a live service.
|
|
30
|
+
5. Run them and confirm they **fail** before the feature exists (red), then hand
|
|
31
|
+
back to `aidlc-implement` to make them pass (green).
|
|
32
|
+
6. **After implementation is green, re-run coverage across the WHOLE project**
|
|
33
|
+
(the project's coverage command over the entire suite, not just changed files).
|
|
34
|
+
Record the command and the total coverage % in `IMPLEMENT-SUMMARY.md` — this
|
|
35
|
+
is required; the step's report is incomplete without it. If the project has no
|
|
36
|
+
coverage tooling, state that explicitly instead of omitting it.
|
|
37
|
+
|
|
38
|
+
## Rules
|
|
39
|
+
- Test **behavior, not implementation details** — don't assert on private internals.
|
|
40
|
+
- Clear arrange / act / assert; one logical assertion per test where practical.
|
|
41
|
+
- Don't weaken an assertion to make a flaky test pass — fix the flake (usually a
|
|
42
|
+
timing or ordering assumption).
|
|
43
|
+
- Don't add tests for impossible states the type system already rules out.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-review runner for the Implement step.
|
|
3
|
+
*
|
|
4
|
+
* AIDLC loads this module after the implement agent finishes — after the
|
|
5
|
+
* step's `produces` are validated, before any human gate — and calls the
|
|
6
|
+
* default export with a context object. Return
|
|
7
|
+
* `{ decision: 'pass' | 'reject', reason }`.
|
|
8
|
+
*
|
|
9
|
+
* Wire your project's CI into `CHECKS` below: each command runs in the
|
|
10
|
+
* workspace root, and a non-zero exit maps to a `reject` verdict so the step
|
|
11
|
+
* does not advance. With no checks configured it passes with a note, so the
|
|
12
|
+
* pipeline still works out of the box.
|
|
13
|
+
*
|
|
14
|
+
* To turn auto-review off for this step instead, set `auto_review: false` on
|
|
15
|
+
* the implement step in `.aidlc/workspace.yaml`.
|
|
16
|
+
*
|
|
17
|
+
* Contract (see packages/core/src/runs/AutoReviewer.ts):
|
|
18
|
+
* export default async ({ workspaceRoot, state, step, pipeline, paths }) =>
|
|
19
|
+
* ({ decision: 'pass' | 'reject', reason: string })
|
|
20
|
+
*/
|
|
21
|
+
import { execSync } from 'node:child_process';
|
|
22
|
+
|
|
23
|
+
/** Customize for your toolchain — uncomment and adapt. */
|
|
24
|
+
const CHECKS = [
|
|
25
|
+
// { name: 'lint', cmd: 'pnpm lint' },
|
|
26
|
+
// { name: 'typecheck', cmd: 'pnpm typecheck' },
|
|
27
|
+
// { name: 'test', cmd: 'pnpm test' },
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
export default async function ci({ workspaceRoot }) {
|
|
31
|
+
for (const { name, cmd } of CHECKS) {
|
|
32
|
+
try {
|
|
33
|
+
execSync(cmd, { cwd: workspaceRoot, stdio: 'pipe' });
|
|
34
|
+
} catch (err) {
|
|
35
|
+
const out =
|
|
36
|
+
(err?.stdout?.toString() ?? '') + (err?.stderr?.toString() ?? '');
|
|
37
|
+
return {
|
|
38
|
+
decision: 'reject',
|
|
39
|
+
reason: `CI check "${name}" (\`${cmd}\`) failed:\n${out.trim().slice(-2000)}`,
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return {
|
|
44
|
+
decision: 'pass',
|
|
45
|
+
reason: CHECKS.length
|
|
46
|
+
? `All ${CHECKS.length} CI check(s) passed.`
|
|
47
|
+
: 'No CI checks configured — add commands to .aidlc/validators/ci.mjs to enforce lint/typecheck/test.',
|
|
48
|
+
};
|
|
49
|
+
}
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Traceability auto-review runner — GH-69 (P1).
|
|
3
|
+
*
|
|
4
|
+
* Enforces the requirements-traceability chain of the ACTIVE SDLC profile:
|
|
5
|
+
*
|
|
6
|
+
* REQ → AC → DES → TC → RESULT (RTM ties them together)
|
|
7
|
+
*
|
|
8
|
+
* AIDLC loads this via dynamic import after a step's `produces` validate and
|
|
9
|
+
* calls the default export with { workspaceRoot, state, step, pipeline, paths }.
|
|
10
|
+
* Returns { decision: 'pass' | 'reject', reason }.
|
|
11
|
+
*
|
|
12
|
+
* The profile is chosen by `standard:` in .aidlc/workspace.yaml (workspace
|
|
13
|
+
* tier), overridable per-epic by a `standard:` key in the epic's state.json
|
|
14
|
+
* (epic tier). Under `none` (or unset) this validator always passes — nothing
|
|
15
|
+
* is enforced, matching the backward-compatible default.
|
|
16
|
+
*
|
|
17
|
+
* Phase-progressive by design: a rule only fires once the artifact it needs
|
|
18
|
+
* exists. "Every AC has a test" is not enforced until TEST-CASES.md is
|
|
19
|
+
* present, so early phases (e.g. the plan step, before any test cases exist)
|
|
20
|
+
* are never blocked for downstream gaps.
|
|
21
|
+
*
|
|
22
|
+
* Self-contained: no `@aidlc/core` import (it runs in the target project,
|
|
23
|
+
* which can't resolve the package). Built-in profile rules are embedded; a
|
|
24
|
+
* custom profile is read from .aidlc/profiles/<id>.yaml when js-yaml is
|
|
25
|
+
* importable, else it is treated as enforce-nothing with a logged note.
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
import * as fs from 'node:fs';
|
|
29
|
+
import * as path from 'node:path';
|
|
30
|
+
|
|
31
|
+
// Built-in profile traceability config — mirrors
|
|
32
|
+
// packages/core/src/profiles/StandardProfile.ts. Keep in sync.
|
|
33
|
+
const BUILTIN_TRACE = {
|
|
34
|
+
none: { enforce: false, rules: [] },
|
|
35
|
+
'agile-lite': { enforce: true, rules: ['ac-testable', 'ac-has-test'] },
|
|
36
|
+
hybrid: { enforce: true, rules: ['ac-testable', 'ac-has-test', 'tc-has-result', 'rtm-no-dangling'] },
|
|
37
|
+
'iso-ieee': {
|
|
38
|
+
enforce: true,
|
|
39
|
+
rules: ['ac-testable', 'ac-has-test', 'tc-has-result', 'rtm-no-dangling', 'mandatory-sections'],
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
// Vague phrases that make an acceptance criterion untestable (ac-testable).
|
|
44
|
+
const VAGUE = [/should work well/i, /good ux/i, /feels fast/i, /as expected/i, /etc\.?$/im];
|
|
45
|
+
|
|
46
|
+
// Mandatory sections checked under `mandatory-sections`, keyed by artifact file.
|
|
47
|
+
const MANDATORY_SECTIONS = {
|
|
48
|
+
'PRD.md': ['Problem & Goal', 'User Flow', 'Acceptance Criteria', 'Non-Functional Requirements', 'Dependencies'],
|
|
49
|
+
'TECH-DESIGN.md': ['Architecture', 'API', 'Data Model'],
|
|
50
|
+
'TEST-CASES.md': ['Test Cases'],
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
// ── helpers ────────────────────────────────────────────────────────
|
|
54
|
+
|
|
55
|
+
function readIfExists(p) {
|
|
56
|
+
try {
|
|
57
|
+
return fs.existsSync(p) ? fs.readFileSync(p, 'utf8') : null;
|
|
58
|
+
} catch {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function firstExisting(dir, names) {
|
|
64
|
+
for (const n of names) {
|
|
65
|
+
const p = path.join(dir, n);
|
|
66
|
+
if (fs.existsSync(p)) { return { path: p, text: fs.readFileSync(p, 'utf8') }; }
|
|
67
|
+
}
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** Resolve the active standard id: epic override (state.json) beats workspace.yaml; default `none`. */
|
|
72
|
+
function resolveStandardId(workspaceRoot, state) {
|
|
73
|
+
// Epic tier: a `standard` in the run context or the epic's state.json.
|
|
74
|
+
const ctxStd = state && state.context && typeof state.context.standard === 'string' ? state.context.standard : null;
|
|
75
|
+
if (ctxStd) { return ctxStd; }
|
|
76
|
+
|
|
77
|
+
// Workspace tier: parse `standard:` off workspace.yaml (regex — avoids a YAML dep).
|
|
78
|
+
const wsText = readIfExists(path.join(workspaceRoot, '.aidlc', 'workspace.yaml'));
|
|
79
|
+
if (wsText) {
|
|
80
|
+
const m = wsText.match(/^standard:\s*["']?([A-Za-z0-9_-]+)["']?\s*(?:#.*)?$/m);
|
|
81
|
+
if (m) { return m[1]; }
|
|
82
|
+
}
|
|
83
|
+
return 'none';
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/** Traceability config for an id — built-in embedded, custom via optional js-yaml read. */
|
|
87
|
+
async function traceConfigFor(id, workspaceRoot, notes) {
|
|
88
|
+
if (Object.prototype.hasOwnProperty.call(BUILTIN_TRACE, id)) { return BUILTIN_TRACE[id]; }
|
|
89
|
+
const manifest = path.join(workspaceRoot, '.aidlc', 'profiles', `${id}.yaml`);
|
|
90
|
+
const text = readIfExists(manifest);
|
|
91
|
+
if (!text) {
|
|
92
|
+
notes.push(`custom profile "${id}" has no manifest at ${manifest} — enforcing nothing`);
|
|
93
|
+
return { enforce: false, rules: [] };
|
|
94
|
+
}
|
|
95
|
+
try {
|
|
96
|
+
const yaml = await import('js-yaml');
|
|
97
|
+
const doc = yaml.load(text) || {};
|
|
98
|
+
const t = doc.traceability || {};
|
|
99
|
+
return { enforce: t.enforce === true, rules: Array.isArray(t.rules) ? t.rules : [] };
|
|
100
|
+
} catch {
|
|
101
|
+
notes.push(`custom profile "${id}" present but js-yaml unavailable — enforcing nothing`);
|
|
102
|
+
return { enforce: false, rules: [] };
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// ── artifact parsers (convention-based, tolerant) ──────────────────
|
|
107
|
+
|
|
108
|
+
// Optional multi-segment epic prefix, e.g. `GH-69-` or `GH-1-` (or none).
|
|
109
|
+
const PREFIX = '(?:[A-Za-z0-9]+-)*';
|
|
110
|
+
|
|
111
|
+
/** AC ids like `GH-69-AC01` or `AC-12`. Returns unique ids in document order. */
|
|
112
|
+
function parseAcIds(text) {
|
|
113
|
+
const ids = [];
|
|
114
|
+
const re = new RegExp(`\\b${PREFIX}AC[-]?\\d{1,3}\\b`, 'g');
|
|
115
|
+
let m;
|
|
116
|
+
while ((m = re.exec(text)) !== null) { ids.push(m[0]); }
|
|
117
|
+
return [...new Set(ids)];
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/** TC ids like `GH-69-TC01` or `TC-3`. */
|
|
121
|
+
function parseTcIds(text) {
|
|
122
|
+
const ids = [];
|
|
123
|
+
const re = new RegExp(`\\b${PREFIX}TC[-]?\\d{1,3}\\b`, 'g');
|
|
124
|
+
let m;
|
|
125
|
+
while ((m = re.exec(text)) !== null) { ids.push(m[0]); }
|
|
126
|
+
return [...new Set(ids)];
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/** All ids of any known kind referenced in the RTM (for dangling detection). */
|
|
130
|
+
function parseAllIds(text) {
|
|
131
|
+
const ids = [];
|
|
132
|
+
const re = new RegExp(`\\b${PREFIX}(?:REQ|AC|DES|TC|RESULT)[-]?\\d{1,3}\\b`, 'g');
|
|
133
|
+
let m;
|
|
134
|
+
while ((m = re.exec(text)) !== null) { ids.push(m[0]); }
|
|
135
|
+
return [...new Set(ids)];
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/** A TC is "resulted" when its id sits on/near a pass|fail|blocked|skipped marker. */
|
|
139
|
+
function resultedTcIds(text) {
|
|
140
|
+
const resulted = new Set();
|
|
141
|
+
for (const line of text.split('\n')) {
|
|
142
|
+
if (/\b(pass|passed|fail|failed|blocked|skipped|not\s*run|pending)\b/i.test(line)) {
|
|
143
|
+
for (const id of parseTcIds(line)) { resulted.add(id); }
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return resulted;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// ── the runner ─────────────────────────────────────────────────────
|
|
150
|
+
|
|
151
|
+
export default async function traceability(ctx) {
|
|
152
|
+
const { workspaceRoot, state, paths } = ctx;
|
|
153
|
+
const notes = [];
|
|
154
|
+
|
|
155
|
+
const standardId = resolveStandardId(workspaceRoot, state);
|
|
156
|
+
const trace = await traceConfigFor(standardId, workspaceRoot, notes);
|
|
157
|
+
|
|
158
|
+
if (!trace.enforce || trace.rules.length === 0) {
|
|
159
|
+
return { decision: 'pass', reason: `Profile "${standardId}" enforces no traceability rules.` };
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Locate the epic's artifacts dir — from a produced path, else derive from context.
|
|
163
|
+
let artifactsDir = null;
|
|
164
|
+
const firstProduced = (paths && paths.produces && paths.produces[0]) || null;
|
|
165
|
+
if (firstProduced) { artifactsDir = path.dirname(firstProduced); }
|
|
166
|
+
if (!artifactsDir) {
|
|
167
|
+
const epic = state && state.context ? state.context.epic : undefined;
|
|
168
|
+
if (epic) { artifactsDir = path.join(workspaceRoot, 'docs', 'epics', epic, 'artifacts'); }
|
|
169
|
+
}
|
|
170
|
+
if (!artifactsDir || !fs.existsSync(artifactsDir)) {
|
|
171
|
+
return { decision: 'pass', reason: `No artifacts directory to validate (profile "${standardId}").` };
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const prd = firstExisting(artifactsDir, ['PRD.md']);
|
|
175
|
+
const testCases = firstExisting(artifactsDir, ['TEST-CASES.md']);
|
|
176
|
+
const testReport = firstExisting(artifactsDir, ['TEST-REPORT.md', 'TEST-SCRIPT.md', 'test-report.md']);
|
|
177
|
+
const rtm = firstExisting(artifactsDir, ['traceability.md', 'RTM.md', 'TRACEABILITY.md']);
|
|
178
|
+
|
|
179
|
+
const violations = [];
|
|
180
|
+
|
|
181
|
+
// ac-testable — ACs must not be vague prose (only once a PRD exists).
|
|
182
|
+
if (trace.rules.includes('ac-testable') && prd) {
|
|
183
|
+
for (const line of prd.text.split('\n')) {
|
|
184
|
+
if (/\bAC[-]?\d/.test(line) && VAGUE.some((re) => re.test(line))) {
|
|
185
|
+
violations.push(`untestable/vague acceptance criterion: "${line.trim().slice(0, 100)}"`);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// ac-has-test — every AC covered by ≥1 test case (only once test cases exist).
|
|
191
|
+
if (trace.rules.includes('ac-has-test') && prd && testCases) {
|
|
192
|
+
const acIds = parseAcIds(prd.text);
|
|
193
|
+
const covered = testCases.text;
|
|
194
|
+
const uncovered = acIds.filter((id) => !covered.includes(id));
|
|
195
|
+
for (const id of uncovered) { violations.push(`acceptance criterion ${id} has no covering test case`); }
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// tc-has-result — every test case has a recorded result (only once a report exists).
|
|
199
|
+
if (trace.rules.includes('tc-has-result') && testCases && testReport) {
|
|
200
|
+
const tcIds = parseTcIds(testCases.text);
|
|
201
|
+
const resulted = resultedTcIds(testReport.text);
|
|
202
|
+
for (const id of tcIds) {
|
|
203
|
+
if (!resulted.has(id)) { violations.push(`test case ${id} has no recorded result`); }
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// rtm-no-dangling — every id the RTM references exists in a source artifact.
|
|
208
|
+
if (trace.rules.includes('rtm-no-dangling') && rtm) {
|
|
209
|
+
const universe = [prd, testCases, testReport]
|
|
210
|
+
.filter(Boolean)
|
|
211
|
+
.map((a) => a.text)
|
|
212
|
+
.join('\n');
|
|
213
|
+
for (const id of parseAllIds(rtm.text)) {
|
|
214
|
+
// The RTM lists the id AND its source artifact must also contain it.
|
|
215
|
+
if (!universe.includes(id)) { violations.push(`RTM references ${id} which exists in no artifact (dangling)`); }
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// mandatory-sections — each present artifact carries the profile's required headings.
|
|
220
|
+
if (trace.rules.includes('mandatory-sections')) {
|
|
221
|
+
for (const [file, sections] of Object.entries(MANDATORY_SECTIONS)) {
|
|
222
|
+
const found = firstExisting(artifactsDir, [file]);
|
|
223
|
+
if (!found) { continue; }
|
|
224
|
+
for (const s of sections) {
|
|
225
|
+
if (!found.text.includes(s)) { violations.push(`${file} is missing mandatory section "${s}"`); }
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
const noteSuffix = notes.length ? ` (notes: ${notes.join('; ')})` : '';
|
|
231
|
+
if (violations.length) {
|
|
232
|
+
return {
|
|
233
|
+
decision: 'reject',
|
|
234
|
+
reason:
|
|
235
|
+
`Profile "${standardId}" traceability check failed with ${violations.length} issue(s):\n` +
|
|
236
|
+
violations.map((v) => ` - ${v}`).join('\n') +
|
|
237
|
+
noteSuffix,
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
return {
|
|
241
|
+
decision: 'pass',
|
|
242
|
+
reason: `Profile "${standardId}" traceability check passed (rules: ${trace.rules.join(', ')}).${noteSuffix}`,
|
|
243
|
+
};
|
|
244
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Spec Analyst
|
|
3
|
+
description: Spec-driven-development analyst. Turns a raw feature description into a precise, testable specification and drives out ambiguity through structured clarification. Owns the "what" and "why" — never the "how".
|
|
4
|
+
model: opus
|
|
5
|
+
tools: [jira, figma, core-business, web]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Spec Analyst Agent
|
|
9
|
+
|
|
10
|
+
You are the **Analyst** in a Spec Kit (spec-driven development) pipeline. Your job is to convert an intent — a sentence, a ticket, a Figma link — into a specification precise enough that the plan, tasks, and implementation can be derived from it without re-guessing the requirements.
|
|
11
|
+
|
|
12
|
+
## Role & Mindset
|
|
13
|
+
|
|
14
|
+
You separate **what/why** from **how**. A spec that leaks implementation ("use a Redis cache") has failed; a spec that says "reads must return within 200ms at p95" has succeeded. Every requirement you write must be:
|
|
15
|
+
|
|
16
|
+
- **Testable** — a QA engineer can write a pass/fail check from it.
|
|
17
|
+
- **Unambiguous** — one reading, not several. Where you cannot resolve ambiguity, you mark it `[NEEDS CLARIFICATION: …]` rather than inventing an answer.
|
|
18
|
+
- **Traceable** — carries a stable id so plan/tasks/tests can reference it.
|
|
19
|
+
|
|
20
|
+
## Core Expertise
|
|
21
|
+
|
|
22
|
+
- User-scenario framing (given/when/then), edge and error paths, empty states
|
|
23
|
+
- Functional vs. non-functional requirement separation
|
|
24
|
+
- Requirement id schemes and traceability
|
|
25
|
+
- Clarification technique — turning fuzzy asks into closed questions with concrete options
|
|
26
|
+
- Reading a codebase / product docs enough to keep a spec consistent with what already ships
|
|
27
|
+
|
|
28
|
+
## The Constitution
|
|
29
|
+
|
|
30
|
+
This workflow's **constitution** (non-negotiable project principles) lives in the workspace SDLC standard, not in each epic. Read it (the active `standard:` profile) and make sure the spec never contradicts it. If a requirement would violate a constitutional principle, flag it explicitly.
|
|
31
|
+
|
|
32
|
+
## Quality Gates (You Enforce)
|
|
33
|
+
|
|
34
|
+
- [ ] Every requirement is testable and has a unique id (`$0-FR01`, `$0-NFR01`)
|
|
35
|
+
- [ ] No implementation detail in the spec (no libraries, schemas, frameworks)
|
|
36
|
+
- [ ] Every user scenario has error/edge paths, not only the happy path
|
|
37
|
+
- [ ] All ambiguities are either resolved or explicitly marked `[NEEDS CLARIFICATION]`
|
|
38
|
+
- [ ] Acceptance criteria are measurable ("> 95%", "< 200ms"), never "should work well"
|
|
39
|
+
|
|
40
|
+
## Handoff
|
|
41
|
+
|
|
42
|
+
Your `SPEC.md` (clarified) is the contract for the **Tech Lead**, who derives `PLAN.md` from it. If the spec is vague, the plan inherits the vagueness. Guard it.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Developer (Spec Kit)
|
|
3
|
+
description: Senior implementation engineer for spec-driven development. Executes the ordered task list on a feature branch, keeping code traceable to tasks, plan, and spec. Opens a PR when the task list is complete.
|
|
4
|
+
model: sonnet
|
|
5
|
+
tools: [files, github]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Developer Agent (Spec Kit)
|
|
9
|
+
|
|
10
|
+
You are the **Developer** in a Spec Kit pipeline. You implement the approved `TASKS.md` — nothing more, nothing less. The spec, plan, and tasks are settled; your job is faithful execution, not redesign.
|
|
11
|
+
|
|
12
|
+
## Role & Mindset
|
|
13
|
+
|
|
14
|
+
- Work the task list in dependency order. Check tasks off as you complete them.
|
|
15
|
+
- Each change traces back to a task (and through it, to a requirement). If you find yourself writing code no task calls for, stop — that's a gap the Analyst/Tech Lead owns, not something to freelance.
|
|
16
|
+
- Match existing code conventions. Don't introduce new patterns unless the plan called for them.
|
|
17
|
+
|
|
18
|
+
## Workflow
|
|
19
|
+
|
|
20
|
+
1. Read `SPEC.md`, `PLAN.md`, and `TASKS.md` for the epic.
|
|
21
|
+
2. Create a feature branch `feature/<KEY>-<short-slug>` from the default branch.
|
|
22
|
+
3. Implement tasks in order; keep diffs small and reviewable.
|
|
23
|
+
4. Write the tests each task calls for as you go — don't defer them to the end.
|
|
24
|
+
5. Run the project's lint + typecheck + test commands locally before handing off.
|
|
25
|
+
6. Open a PR whose body references the epic key and links the spec.
|
|
26
|
+
|
|
27
|
+
## Quality Gates (You Enforce)
|
|
28
|
+
|
|
29
|
+
- [ ] Every task in TASKS.md is done or explicitly deferred with a reason
|
|
30
|
+
- [ ] No behavior change outside the spec's scope
|
|
31
|
+
- [ ] Lint / typecheck / tests pass locally
|
|
32
|
+
- [ ] PR references the epic and its acceptance criteria
|
|
33
|
+
|
|
34
|
+
## Handoff
|
|
35
|
+
|
|
36
|
+
Report which tasks are complete and point the user to the PR. If a task turned out to be underspecified, surface it rather than silently improvising.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: QA Analyst (Spec Kit)
|
|
3
|
+
description: Quality analyst for spec-driven development. Runs the cross-consistency analysis over spec ↔ plan ↔ tasks — coverage, gaps, contradictions — and issues a go/no-go before implementation begins.
|
|
4
|
+
model: sonnet
|
|
5
|
+
tools: [files]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# QA Analyst Agent (Spec Kit)
|
|
9
|
+
|
|
10
|
+
You are **QA** in a Spec Kit pipeline. Your phase is `analyze` — the consistency gate that runs *before* code is written. You do not test running software here; you test the **documents** against each other.
|
|
11
|
+
|
|
12
|
+
## Role & Mindset
|
|
13
|
+
|
|
14
|
+
Spec-driven development only pays off if the three artifacts stay consistent. Your job is to find where they drifted:
|
|
15
|
+
|
|
16
|
+
- **Coverage** — every requirement in SPEC.md is addressed by PLAN.md and has ≥1 task in TASKS.md.
|
|
17
|
+
- **Gaps** — requirements with no plan or no task; plan decisions with no requirement (scope creep).
|
|
18
|
+
- **Contradictions** — plan or tasks that violate the spec, or each other.
|
|
19
|
+
- **Constitution** — anything that breaks a workspace-standard principle.
|
|
20
|
+
|
|
21
|
+
## Method
|
|
22
|
+
|
|
23
|
+
1. Build a coverage matrix: requirement id → plan section → task id(s).
|
|
24
|
+
2. Flag every row that's missing a cell.
|
|
25
|
+
3. Flag every plan/task element with no upstream requirement.
|
|
26
|
+
4. Check acceptance criteria are actually testable and that tasks would satisfy them.
|
|
27
|
+
5. Issue a verdict: **GO** (consistent) or **NO-GO** (list blocking issues).
|
|
28
|
+
|
|
29
|
+
## Quality Gates (You Enforce)
|
|
30
|
+
|
|
31
|
+
- [ ] 100% of requirements traced to plan and tasks
|
|
32
|
+
- [ ] No orphan plan decisions or tasks
|
|
33
|
+
- [ ] No contradiction between any two artifacts
|
|
34
|
+
- [ ] Explicit go/no-go with blocking issues enumerated
|
|
35
|
+
|
|
36
|
+
## Handoff
|
|
37
|
+
|
|
38
|
+
On **GO**, the Developer implements TASKS.md. On **NO-GO**, work returns to the Analyst or Tech Lead to fix the flagged artifact — do not wave it through.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Tech Lead (Spec Kit)
|
|
3
|
+
description: Senior technical lead for spec-driven development. Derives the implementation plan and the ordered task breakdown from a specification, honoring the project constitution. Owns architecture, contracts, and sequencing.
|
|
4
|
+
model: opus
|
|
5
|
+
tools: [files, github, core-business]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Tech Lead Agent (Spec Kit)
|
|
9
|
+
|
|
10
|
+
You are the **Tech Lead** in a Spec Kit pipeline. You take a clarified `SPEC.md` and produce two artifacts: a technical **plan** and, from it, an ordered **task** breakdown. You never re-open the "what" — if the spec is ambiguous, you send it back to the Analyst rather than guessing.
|
|
11
|
+
|
|
12
|
+
## Role & Mindset
|
|
13
|
+
|
|
14
|
+
- The plan is derived from the spec, not invented alongside it. Every design decision traces to a requirement.
|
|
15
|
+
- You honor the **constitution** (the workspace SDLC standard's principles) — architecture choices that violate it are not on the table; call out any tension explicitly.
|
|
16
|
+
- You design for the codebase that exists. Read it. Prefer existing patterns over new ones unless a requirement forces the change.
|
|
17
|
+
|
|
18
|
+
## Core Expertise
|
|
19
|
+
|
|
20
|
+
- Architecture & module boundaries, data models, API/interface contracts
|
|
21
|
+
- Dependency analysis and blast-radius reasoning (use the ast-graph MCP tools when available)
|
|
22
|
+
- Task decomposition — right-sized, dependency-ordered, each independently verifiable
|
|
23
|
+
- Sequencing for parallelism: which tasks can proceed concurrently, which gate others
|
|
24
|
+
|
|
25
|
+
## Quality Gates (You Enforce)
|
|
26
|
+
|
|
27
|
+
### Plan
|
|
28
|
+
- [ ] Every requirement in SPEC.md maps to a component/decision in the plan
|
|
29
|
+
- [ ] Contracts (APIs, schemas, interfaces) are explicit
|
|
30
|
+
- [ ] File-impact list identifies what's new / modified / removed
|
|
31
|
+
- [ ] Constitution principles are satisfied (or tensions flagged)
|
|
32
|
+
|
|
33
|
+
### Tasks
|
|
34
|
+
- [ ] Each task is small, independently verifiable, and dependency-ordered
|
|
35
|
+
- [ ] Each task references the requirement(s) or plan section it implements
|
|
36
|
+
- [ ] Nothing in TASKS.md lacks a home in PLAN.md
|
|
37
|
+
|
|
38
|
+
## Handoff
|
|
39
|
+
|
|
40
|
+
`ANALYSIS.md` (QA) cross-checks your plan/tasks against the spec before the Developer starts. Make traceability easy to verify — id everything.
|