一键导入
sdd
Spec-driven development — the practice of writing the spec before the code. With the 9-section template and the three pnpm spec-check gates.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Spec-driven development — the practice of writing the spec before the code. With the 9-section template and the three pnpm spec-check gates.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
How to consume a GitHub issue body as an agent task prompt. The 9-section template, the lifecycle, the failure modes.
The 12 design principles this codebase is built on. Read first, before any task.
Differences and deterministic behavior of the mock ADT server used by adt-bench smoke runs.
How to return a strict scenario result JSON with evidence and no extra prose.
Test-driven loop for ABAP — inspect, change, check syntax, run unit tests, diagnose, fix.
Standard ABAP object workflow (discover, create or edit, check, activate, validate).
| name | sdd |
| description | Spec-driven development — the practice of writing the spec before the code. With the 9-section template and the three pnpm spec-check gates. |
Spec-driven development (SDD) is the load-bearing rule of this
codebase. The spec is the source of truth; the code is correct
when it matches the spec. The pnpm spec-check gate enforces it.
Every package has a specs/SPEC.md with 9 sections (see below).
The spec is written before the code. The pnpm spec-check
script runs three checks:
spec-mtime — SPEC.md is newer than src/.spec-coverage — every export in src/index.ts is documented
in SPEC.md. Every top-level symbol in src/ is documented.spec-drift — every test in the ## 6. Test matrix exists in
code. Every test in code is in the matrix.If any of these fail, the PR is blocked.
# Spec: <package-name>
## 1. Purpose
One paragraph, no marketing.
## 2. Public surface
Every TypeScript symbol exported from src/index.ts, in fenced
code blocks, with the full signature. (The spec-coverage tool
greps for these and fails if any export is missing.)
## 3. Behaviour contracts
One subsection per exported function/class/method. For each:
- Inputs and outputs, with edge cases.
- Error model.
- Ordering guarantees (for async / I/O code).
## 4. Invariants
Numbered list of must-hold properties. Reference by number
("Inv. 4") in tests and PRs.
## 5. Error model
What throws, what returns, what shapes (for Zod schemas).
## 6. Test matrix
Markdown table with two columns:
| Test name | Covers contract |
The "Test name" is the full describe > describe > it path.
The "Covers contract" references §3 subsections or §4 invariants.
## 7. Non-goals
Explicit list of things this package does NOT do. Not a TODO
list — a fence.
## 8. Dependencies
Every runtime and dev dependency. For internal packages, also
state which other @adt-bench/* packages this one imports.
The order is fixed. Renumbering the sections will break the spec-check tools.
spec-mtime (cheap, runs first)If you changed the code, you also changed the spec.
For every package, specs/SPEC.md's mtime MUST be at least as
new as the newest src/** file. If you edit result.ts but not
SPEC.md, this fails.
Use touch specs/SPEC.md after updating the spec.
This catches the most common drift: I changed the code but forgot the spec.
spec-coverage (medium, runs second)Every export is documented. Every internal symbol is too.
The tool extracts every export const|let|var|function|class|interface|async function
from src/index.ts and asserts that the symbol name appears (as
a whole word) somewhere in specs/SPEC.md. It also walks
every top-level const|let|var|function|class|interface|type
declaration in any src/** file and asserts the same.
This catches:
It does NOT catch:
spec-drift (slowest, runs last)Every test in the spec exists in code. Every test in code is in the spec.
The tool parses the ## 6. Test matrix section and asserts:
it('...') or
test('...') declaration in some *.spec.ts in the same
package.it('...') or test('...') declaration in any
*.spec.ts file in the same package has a matching row in
the matrix.The test name in the matrix is the full path through any
nested describe blocks, joined with >. Example:
evaluate (rule-based) > fails when self-reported status is "fail"
The tool extracts the test name from the source file (correctly handling nested describes, regex literals, URL strings, and escaped quotes) and matches it against the matrix row.
This catches:
specs/SPEC.md first, following the 9-section template.src/index.ts, src/<module>.ts, etc.src/<module>.spec.ts with the test names from §6.pnpm spec-check must pass before opening the PR.If you write code first, the spec-check will fail and you'll have to backtrack. Write the spec first.
src/ to match. Reference the spec change in the
commit body.pnpm spec-check must pass.If the change is purely internal (no exported signature change,
no behavior change, no test name change), a touch specs/SPEC.md is enough to satisfy spec-mtime.
| Symptom | Fix |
|---|---|
spec-mtime says SPEC.md is older than src/ | touch specs/SPEC.md after updating it. |
spec-coverage says an export is undocumented | Add the symbol to §2 with its full signature. |
spec-coverage says an internal symbol is undocumented | Add the symbol to §3 in the relevant behavior contract. |
spec-drift says a test is in spec but not code | Either add the test, or remove the row from the matrix. |
spec-drift says a test is in code but not spec | Add the row to §6 with the full path. |
spec-drift says a test name has a quote mismatch | The matrix row must match the source it('...') verbatim. Including the quotes. |
run() does what §3
says. Unit tests are the proof. The test matrix in §6 maps
tests to contract sections; if a contract is not in the
matrix, it's untested.printConsoleReport's exact format is in
the code, not the spec. The spec only says "prints a tabular
report" and the test asserts the right number of lines.When in doubt: add a test. The spec is a contract; the test is the proof the contract is honored.
The friction is real: writing the spec is more work than skipping it. The pay-off is also real: you can trust the code to do what the spec says, and you can change the code without breaking the contract.
See also: principles/SKILL.md §1 ("Spec-driven development is
the load-bearing rule").