| name | auto-spec |
| version | 0.1.0 |
| description | Turn a raw feature request into a grounded, TESTABLE spec — autonomously. It recons the real repo and
domain to ground every claim, drafts a spec (objectives, user-visible behavior, acceptance criteria,
explicit non-goals, constraints, interfaces, risks), then runs a completeness-critic loop that
adversarially hunts for gaps, ambiguity, and untestable criteria and fixes them until the spec is
stable. Every acceptance criterion it emits is measurable (you could write a test for it); every
requirement is grounded in the repo or flagged as an assumption — no invented requirements, no phantom
paths. It writes `.ulpi/spec/<name>.md` and is the DEFINE phase that feeds auto-plan. Composes
fan-out-work (recon), adversarial-verify (the critic), converge-loop (until-stable), and
checkpoint-resume.
|
| allowed-tools | ["Bash","Read","Write","Edit","Grep","Glob","Agent","AskUserQuestion","Workflow"] |
| disable-model-invocation | true |
| user-invocable | true |
| effort | high |
| argument-hint | <what to build — the feature/product/change request> |
| arguments | ["request"] |
| when_to_use | Use at the start of any new feature, product, or significant change, when you need a written spec before
planning or code — especially when the request is broad and needs grounding + tightening. Do NOT use to
plan HOW to build (that's auto-plan) or to write code; and do NOT invent a spec for a request so vague
it needs a product decision first — ask the few blocking questions, then spec.
|
A spec is a contract; a vague or invented one poisons everything downstream. Non-negotiable:
1. GROUND EVERY REQUIREMENT. Each requirement is tied to the actual repo/domain or explicitly marked an
ASSUMPTION. Never invent requirements, file paths, endpoints, or constraints to fill a gap — a phantom
in the spec becomes a phantom in the plan and the code.
2. EVERY ACCEPTANCE CRITERION MUST BE TESTABLE. If you can't state how it would be verified (a test, a
measurable threshold, an observable behavior), it isn't an acceptance criterion — sharpen it or cut it.
3. SCOPE HAS EXPLICIT NON-GOALS. A spec that only says what's in-scope invites scope creep. State what is
deliberately OUT.
4. SURFACE, DON'T GUESS. Genuine ambiguity that changes what gets built is a STOP-and-ask (bounded
questions), not a silent assumption dressed as a requirement.
5. FAIL CLOSED ON COMPLETENESS. The critic loop exits only when no material gap/ambiguity/untestable
criterion remains OR it stalls — and a stalled critic reports the open gaps, never a "looks complete"
it didn't earn.
Auto Spec
Overview
Produce the spec a strong engineer would write before touching code: grounded in what actually exists,
precise about behavior, testable in its criteria, honest about scope and risk — arrived at autonomously
through recon + draft + an adversarial completeness loop. The output is a spec downstream phases can plan
and test against without re-interviewing the user.
Phase 0: Intake — capture the request, detect blocking ambiguity
- Capture
$request verbatim as the source of scope. The request IS the scope; don't silently narrow or
widen it.
- Judge whether it's answerable from the repo + reasonable inference, or whether a genuine product
decision blocks it (a fork where building the wrong branch is expensive). Only for the latter, ask a
FEW targeted questions (
AskUserQuestion) — never a long interview, never scope questions you could
answer by reading the repo.
- Open a
checkpoint-resume run.
Success criteria: the request is captured; at most a few genuinely-blocking questions asked; recon
can proceed.
Phase 1: Recon — ground the spec in reality
Before drafting, learn what exists (fan out with fan-out-work for a large repo):
- the relevant existing code, modules, data models, and interfaces the change touches;
- prior art / patterns in the repo to stay consistent with;
- constraints that are real: the stack, existing contracts, invariants in
CLAUDE.md/docs, data shapes,
auth/security boundaries;
- the domain facts the request assumes;
- prior-run lessons already in your loaded context —
auto-learn routes them into CLAUDE.md,
.claude/rules, and auto memory (which Claude Code loads automatically), so constraints and failure
patterns already paid for are in front of you: fold them into the spec's constraints/risks, don't
rediscover them.
Record what's grounded vs. what's an assumption — the draft will mark assumptions explicitly.
Success criteria: a grounded picture of the current state and constraints the spec must respect.
Phase 2: Draft the spec
Write .ulpi/spec/<name>.md covering (omit a section only when truly N/A, and say so):
- Objective — the problem and the outcome, in one or two sentences.
- Users & context — who this is for and when it's used.
- Behavior / user stories — what the system does, from the user's view; the happy path AND the error
and edge paths.
- Acceptance criteria — a checklist, each item TESTABLE (a condition you could assert). These become
the plan's per-task criteria and the tests' targets.
- Scope & non-goals — explicitly in and explicitly OUT.
- Constraints & interfaces — stack, contracts, data shapes, public interfaces affected, backward-compat.
- Assumptions & open questions — everything not grounded, named as such.
- Risks — security, data, irreversibility, performance — with the mitigation direction.
Success criteria: a complete first draft; every acceptance criterion is phrased testably; assumptions
are marked, not hidden as facts.
Phase 3: The completeness-critic loop (converge until stable)
Run converge-loop in until-dry mode with an adversarial critic as the finder — this is what makes the
spec strong:
- each round,
adversarial-verify-style critics attack the draft: missing behavior/edge/error case? an
acceptance criterion that isn't testable? an ungrounded requirement? contradictory or ambiguous
wording? a non-goal that should be stated? an unstated assumption?
- apply the smallest fix per finding (tighten a criterion, add the missing case, mark the assumption, cut
the invented requirement);
- re-critique; exit when a round finds no material gap (dry) OR it stalls. A stalled loop reports the
remaining open gaps — it does not claim completeness.
Use AskUserQuestion only if a surfaced gap is a real product decision; otherwise the critic resolves it
against the repo.
Success criteria: no material gap/ambiguity/untestable criterion remains, or the open ones are
explicitly listed as open questions.
Phase 4: Finalize
Write the stabilized spec to .ulpi/spec/<name>.md, close the checkpoint, and report where it lives + the
open questions (if any). This spec is the input to auto-plan.
Success criteria: the spec file is written and self-consistent; open questions (if any) are flagged
for the user.
Common Rationalizations
| Rationalization | Reality |
|---|
| "The request is clear enough, skip the spec." | Clear-to-you scatters into ten interpretations at build time. The spec is the shared contract that prevents that. |
| "I'll just assume the obvious behavior." | An unmarked assumption is an invented requirement. Mark it as an assumption or ask — don't smuggle it in as fact. |
| "'Works well' is a fine acceptance criterion." | Untestable criteria can't gate anything. If you can't write a test for it, it's a wish, not a criterion. |
| "I don't need non-goals, the scope is obvious." | Unstated non-goals are the entry point for scope creep. Name what's out. |
| "The critic found nothing new, one round is enough." | One round rarely exhausts the gaps. Loop until a round is genuinely dry, then stop. |
| "I'll reference a config/endpoint that probably exists." | A phantom path in the spec becomes a phantom in the code. Ground it or mark it unknown. |
Red Flags
- Requirements, paths, or endpoints in the spec that don't exist in the repo and aren't marked assumptions.
- Acceptance criteria you couldn't write a test for.
- A spec with in-scope items but no non-goals.
- The critic loop ran exactly once.
- Long clarification interviews for things readable in the repo.
- A "complete" verdict with unresolved contradictions still in the text.
Guardrails
- Never invent requirements/paths/constraints; ground them or mark them assumptions.
- Never emit an untestable acceptance criterion.
- Never omit explicit non-goals.
- Never resolve a real product decision silently — ask (briefly) or flag it open.
- Never report the spec complete while the critic still finds material gaps.
When To Load References
fan-out-work (skill) — parallel recon across a large codebase in Phase 1.
adversarial-verify (skill) — the completeness critics in Phase 3.
converge-loop (skill) — the until-stable critic loop (termination + anti-thrash).
checkpoint-resume (skill) — durable spec-run state.
Output Contract
Report:
- the spec file path (
.ulpi/spec/<name>.md) and a one-line objective
- acceptance criteria count (all testable) and the explicit non-goals
- assumptions made + open questions surfaced for the user
- critic-loop outcome (rounds to stable, or the honest remaining gaps)