Documentation
README
spec-writing β research, grill the open questions, THEN write the spec
Input: a feature request. Output: a complete spec at
.ai/specs/{YYYY-MM-DD}-{slug}.md written after every open question has
been resolved with the user. The interview happens before the document exists,
so the spec is written once, around real answers β not written around guesses
and reworked after the fact.
The spec is the single design artifact. Do not write separate "design docs" in other locations.
Announce at start: "Using the spec-writing skill β designing {feature}; I'll bring you the open questions before writing the spec."
When to write a spec
| Situation | Action |
|---|---|
| New module | Write spec |
| Feature touching 3+ files | Write spec |
| Data model change | Write spec |
| Cross-module behavior change | Write spec |
| Small bug fix or one-file refactor | Skip spec β use /root-cause + /fix |
Lifecycle and naming rules live in .ai/specs/AGENTS.md. Read it once before
your first spec.
Step 1: Scope the request
If the request is ambiguous, ask the user at most 3β4 focused questions covering: what (the capability), why (the problem), where (ERP, MES, or both), who (the users). If the request is already clear, skip to Step 2.
Step 2: Read Carbon context
Run all of these before designing anything:
ls .ai/specs/ .ai/specs/implemented/ | grep -i {keyword} # prior art β never duplicate a spec
cat .ai/lessons.md # known pitfalls
cat .ai/docs/module-conventions.md # module layout rules
cat apps/erp/app/modules/{module}/AGENTS.md # for every module touched
Then read the .ai/rules/ files matching the domain (use the Task Router table
in the root AGENTS.md to find them).
Step 3: Research competitors
Invoke /research {feature}. This is mandatory for ERP-domain features
(accounting, costing, tax, inventory valuation, RMA, planning, etc.) β do not
invent domain logic. Findings land in .ai/research/{slug}.md; cite that file
from the spec.
Step 4: Make the design decisions β and separate the questions
For each significant decision (data model shape, status lifecycle, workflow, integration point):
- State the question.
- Cite what the research found ("SAP and NetSuite bothβ¦").
- List 2β3 options with one-line trade-offs.
- Decide it yourself if the research + codebase settle it β record the choice and rationale for the spec's Design Decisions table.
- If you cannot settle it, it is an open question β genuine domain ambiguity, scope boundaries, data-model alternatives with real trade-offs, product-positioning calls, anything where the user's answer changes what you build. Do NOT pick a placeholder and move on; do NOT write "TBD".
Run every new or modified entity through this checklist; decided rows go in the Design Decisions table, unsettled ones join the question list:
| # | Heuristic | Question to answer |
|---|---|---|
| 1 | Multi-tenancy | Does every new table have companyId + composite PK ("id", "companyId") + id('prefix') default? |
| 2 | Service shape | Does every service function take client first, return {data, error}, never throw? |
| 3 | RLS coverage | Does every new table have SELECT/INSERT/UPDATE/DELETE policies per .ai/rules/conventions-database.md? |
| 4 | Permission scoping | Does requirePermissions in every route use the correct {module}_{action} scope? |
| 5 | Form pattern | Does every form use ValidatedForm + validator(zodSchema) + a route action? |
| 6 | Module layout | One {module}.service.ts, one {module}.models.ts, barrel index.ts? |
| 7 | Backward compatibility | Any FROZEN/STABLE surface touched (see BACKWARD_COMPATIBILITY.md)? What is the migration path? |
At least one open question is required before proceeding. Zero questions means you haven't thought hard enough β re-read the research and the heuristics table.
Step 5: Grill β resolve the questions with the user BEFORE writing
π HARD STOP: the spec file is not written while any question is unresolved.
Invoke /grill on the question list (protocol: .ai/skills/grill/SKILL.md β
the spec doesn't exist yet, so this is its artifact-less mode; resolutions
carry into the spec's Open Questions section when it is written in Step 6).
Interview one question at a time (group max 2β3 only for single-module,
no-schema designs). For each question:
- State the question and why it matters (what changes downstream).
- Give your recommended answer with a one-line rationale, plus the alternatives and their trade-offs.
- Cross-check the user's answer against the codebase before accepting it β if
the answer contradicts something real (an existing table, a lesson in
.ai/lessons.md, a prior spec), say so and re-ask. - Record the resolution:
- [x] {Question} β **Answer:** {decision and rationale}.
The user may batch ("accept all recommendations") β that is their call to make, not yours to assume. Never resolve a question yourself to unblock work; resolutions come only from a human answer, a research finding, or an explicit documented "out of scope for v1" decision.
Autonomous mode (automated loops β conductor, headless/outer-loop runs)
When this skill runs inside an automated loop with no human available, do
not invoke /grill and do not block waiting for answers. Instead:
- Resolve each question in this order: (1) codebase precedent, (2) research /
competitor consensus, (3) your recommended answer. Record it inline as
- [x] {Question} β **Autonomous:** {answer + rationale}so assumed decisions are distinguishable from human ones at a glance. - Surface the full list of autonomous resolutions in the spec changelog AND in the loop's "Assumed decisions" PR section β the human reviews them at the PR, not mid-loop.
- Ask-First territory is never resolved autonomously (root
AGENTS.md: production-critical schema, auth/RBAC/multi-tenancy, public contracts, scope reductions, new production dependencies). A question in that territory β the loop goes BLOCKED with the question stated crisply.
Step 6: Write the spec
Only now. Copy .ai/specs/template.md to .ai/specs/{YYYY-MM-DD}-{slug}.md
(today's date, kebab-case slug) and fill every section, with the Step-5
resolutions baked into the design. Rules:
- SQL sketches use
id('prefix'),companyId, composite PK, audit columns β nevergen_random_uuid(). - Acceptance criteria must be testable: "user creates a PO with 3 lines and sees correct totals in the list view", not "works correctly".
- No
{placeholders}left in the file; mark inapplicable sectionsN/Awith a reason. - The Open Questions section records the resolved Q&A (all boxes checked, each with its inline answer) β it is the audit trail of Step 5, not a to-do list.
Step 7: New questions discovered while writing
Writing the spec sometimes surfaces questions Step 4 missed. When that happens:
- Add them to the Open Questions section as unchecked items with "why it matters".
- Take them back to the user (same protocol as Step 5) before calling the spec final β the hard stop applies to these too. Do not say "we can figure these out during implementation."
Step 8: Finalize
After every question is resolved: add a changelog entry, set status per
.ai/specs/AGENTS.md. The spec is now ready for /plan (or /feature, which
calls it).
Done when
- Every open question was answered by the user BEFORE the spec was written (Step 5), with the resolution recorded inline in the spec
- Spec exists at
.ai/specs/{YYYY-MM-DD}-{slug}.md, every section real content, design reflecting the resolutions (no section contradicts an answer) - Research file exists and is linked from the spec
- Every applicable heuristic (1β7) has a row in Design Decisions β no TBDs
- Any questions surfaced during writing (Step 7) were also resolved before the spec was called final
Anti-patterns
- Writing the spec first and interviewing the user afterward (the old flow β it produces rework: the document gets written around guesses, then edited around answers)
- Writing a design doc anywhere other than
.ai/specs/ - Dumping all open questions in one message and accepting batch answers you assumed rather than the user chose
- Accepting an answer without checking it against the code
- Marking questions resolved without human input
- Skipping
/researchbecause "I know how ERPs work" - "TBD" in the Design Decisions table (that's an open question β Step 5 it)
- Vague acceptance criteria ("feature works as expected")
Red flags β thinking any of these means the gate is being defeated; STOP:
- "I'll draft the spec now and confirm the questions after" (that IS the old flow)
- "I'll mark this question resolved so we can keep moving"
- "zero open questions β the design is clear" (you haven't looked hard enough)
- "we can settle this during implementation"
- "the user probably wants X, I'll assume it" (that assumption IS the question)