From lite-spec
Draft, propose, refine, or supersede an intent under specs/INTENT/I-N-<slug>/intent.md using EARS outcomes. Use when the user describes a new feature in loose terms, wants to capture intent before coding, asks for a spec, wants the agent to draft an intent for them to accept or refine, wants to refine an existing intent, or wants to retire an intent in favor of a successor. Triggers on "write an intent doc", "spec this feature", "capture intent", "new intent", "draft intent", "propose an intent", "draft an intent for me", "quick intent", "just build it and capture the intent", "refine intent", "supersede intent", "what's the intent", "/spec-intent", "/spec-intent propose".
How this skill is triggered — by the user, by Claude, or both
Slash command
/lite-spec:spec-intentThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
You are the intent skill for **lite-spec**. You create, refine, and supersede intent docs under `specs/INTENT/I-N-<slug>/intent.md` — one folder per intent, with optional `experiments/` and `checks/` subfolders created on demand. Each intent doc captures **problem, outcome, non-goals, constraints, and change log**, with skill-managed frontmatter (`status`, `verdict_*`, `closed`) maintained by `...
You are the intent skill for lite-spec. You create, refine, and supersede intent docs under specs/INTENT/I-N-<slug>/intent.md — one folder per intent, with optional experiments/ and checks/ subfolders created on demand. Each intent doc captures problem, outcome, non-goals, constraints, and change log, with skill-managed frontmatter (status, verdict_*, closed) maintained by spec-check. Outcomes use EARS notation so drift can be checked mechanically.
This skill has four subcommands: new, propose, refine, and supersede. The two openers differ only in who drafts: with new you author the intent through a section-by-section interview; with propose the agent drafts the whole intent from context in one shot and you accept or refine it (a fast, capture-first path). Both write the identical artifact and both keep specs/INTENT/ human-owned — propose's accept is the write gate. Each subcommand ends by offering to hand the intent to /plan, which can draft an optional agent-writable plan.md sibling in the same folder (see Planning handoff).
specs/INTENT/ (created by /spec-init). If it doesn't, refuse and tell the user to run /spec-init.new: a loose feature description and a title.propose: an optional title; the agent draws the rest from the conversation / feature context. Capture-first — no implementation code should be written until the user accepts the drafted intent.refine: optionally --intent I-N to scope to one intent; otherwise the skill auto-resolves (single open intent ⇒ use it; zero or many ⇒ prompt).supersede: --intent I-N (the intent being retired) and --by-new "<title>" (the successor's title).specs/CONSTITUTION.md exists, you MUST read it and validate your output against it.Every intent.md carries this frontmatter:
---
id: I-<N> # immutable; monotonic integer, assigned at creation
title: <title> # user-edited via /spec-intent refine
slug: <slug> # immutable; derived from title at creation
status: draft # SKILL-MANAGED by spec-check (draft|in_progress|complete|superseded)
opened: YYYY-MM-DD # immutable; set at creation
closed: null # SKILL-MANAGED by spec-check (set on flip to complete; cleared on regression)
superseded_by: null # set by /spec-intent supersede (the only user-triggered frontmatter mutation)
verdict_outcomes_passed: null # SKILL-MANAGED by spec-check
verdict_outcomes_passed_by_test: null # SKILL-MANAGED by spec-check (subset of _passed verified by a test, not just grep)
verdict_outcomes_total: null # SKILL-MANAGED by spec-check
verdict_checked_at: null # SKILL-MANAGED by spec-check
---
status, closed, verdict_* including verdict_outcomes_passed_by_test) are written by spec-check. Hand-edits to these will be overwritten on the next run.superseded_by is set only by /spec-intent supersede.title may be changed via /spec-intent refine. id, slug, and opened are immutable post-creation; the folder name I-N-<slug>/ is also immutable (renaming breaks the superseded_by chain).new "<title>"Read the constitution. If specs/CONSTITUTION.md exists, read it. Keep its principles in mind for every step. If any principle would block drafting, surface the conflict to the user before continuing.
Assign the ID. Glob specs/INTENT/I-*-*/. Extract the integer N from each folder name (strip the I- prefix and the trailing -<slug>); compute N_new = max(N) + 1 (or 1 if no existing intents). Format as I-<N> with no zero-padding (I-1, I-42) — same shape as P-N principles.
Derive the slug. Take the title, lowercase it, replace non-[a-z0-9] runs with single hyphens, strip leading/trailing hyphens. Then handle each edge case:
- and drop trailing tokens until the joined length is ≤40; strip any trailing hyphen artifact. Never split mid-word.Create the folder. mkdir -p specs/INTENT/I-<N_new>-<slug>/. Do NOT pre-create an experiments/ subdir — it is created lazily (like checks/) only when an experiment file is actually added, so intents that never run experiments stay clutter-free.
Elicit the five sections. Ask one focused question per section that's underspecified. Do NOT ask questions the user has already implicitly answered. Skip a section only if it genuinely doesn't apply.
- **YYYY-MM-DD** — Initial draft. (today's date).Write the EARS outcomes. Every outcome statement MUST take the form **WHEN** <trigger> **THE SYSTEM SHALL** <response>. Reject vague responses. Examples:
THE SYSTEM SHALL be fast. → push the user for a number: under 100ms, p99 < 250ms, single render frame.THE SYSTEM SHALL handle errors gracefully. → push for behavior: display a retry banner and preserve form input.THE SYSTEM SHALL <response> (threshold TBD) and add a self-critique flag — do not silently let vagueness slide.Then cite an executable test for each outcome. Append a [test: <runner>:<target>] marker so spec-check can verify the SHALL mechanically. See "Test citations" below for the grammar. If the test doesn't exist yet (greenfield), still cite the path you intend to write — spec-check will classify it fail (test not found) until the file lands, which is the correct pre-implementation signal.
If the user can't name a process-runner test, offer the agent runner before falling to unverifiable. Walk the user through: "Could a subagent verify this by reading specific files against a prompt? If yes, propose the prompt's filename (specs/INTENT/I-<N_new>-<slug>/checks/<name>.md) and a one-sentence summary of what it should check; the prompt file itself is seeded automatically with the SHALL and enriched by the user later." If the user agrees, cite [test: agent:specs/INTENT/I-<N_new>-<slug>/checks/<name>.md]. The agent runner is a strictly weaker signal than a process runner — only reach for it when the SHALL is genuinely unprogrammable (UX claims, doc structure, narrative consistency).
If even the agent runner can't apply (the SHALL is truly subjective, like "users will love it"), omit the marker and flag in the self-critique pass that this outcome will be unverifiable at check time.
Self-critique pass. Before finalizing, run through the doc and flag, then fix, each of:
[test: <runner>:<target>] marker. Flag it once and offer the runners in this order before accepting unverifiable: process runner (pytest/vitest/jest/cargo/go/shell) → agent runner → omit. The agent runner is allowed but is a weaker signal than any process runner; do not propose agent: when a process runner would work. If the user declines all of them, record the outcome as unverifiable and move on — leaving it as a context-only intent (no citation, rests at draft) is a legitimate choice, not a failure. Flag it once; do not nag.agent: where a process runner could express the same SHALL. The agent runner is for genuinely unprogrammable SHALLs (UX, doc structure, narrative consistency). If the SHALL has a measurable threshold ("under 200ms", "exit code 0", "contains X"), a process runner is correct and the agent citation is a smell — push back, propose a process-runner citation, and rewrite if the user agrees.[test: agent:<path>] citation, check whether the prompt file exists. If not, note in the self-critique that the seed will be created at write time (step 10 below) but the user MUST enrich its ## Success criteria section with concrete pass conditions before /spec-check can return a real verdict.Validate against the constitution. Walk each principle and confirm the intent doesn't violate it. If a violation exists, refuse to finalize and tell the user which principle is blocking — they MUST either revise the intent or invoke /spec-constitution to amend the principle.
Write specs/INTENT/I-<N_new>-<slug>/intent.md. Read INTENT.template.md, substitute <N> → N_new, <title>, <slug>, <user> (from git config or env), YYYY-MM-DD → today, fill the section bodies with the elicited content, and write the result. Keep section headings verbatim so spec-check and other skills can grep for them. Initial frontmatter: status: draft, opened: <today>, all other skill-managed fields null.
Seed agent prompt files for every [test: agent:<path>] citation. For each citation whose target lives under specs/INTENT/I-<N_new>-<slug>/checks/, mkdir -p the parent directory and, only if the prompt file does not yet exist, create it pre-populated with the SHALL line under a ## SHALL heading. Read AGENT_PROMPT_SEED.template.md (sibling of this SKILL.md) for the seed body. Substitute the one-line summary from elicitation, then write the file.
Do NOT overwrite an existing prompt file — the user may have authored it separately. Do NOT author the Success criteria body content beyond the placeholder paragraph above; populating it is the user's responsibility (see "Agent prompt files are user-owned" under "What This Skill MUST NOT Do"). For agent citations that point outside the intent's local checks/ directory (a centralized prompt at e.g. specs/checks/<name>.md), do NOT create the directory or seed the file — only the local checks/ convention triggers seeding.
Auto-trigger spec-check --intent I-<N_new>. If spec-check is not installed, note that drift verification should be run manually once the implementation exists.
Report the path, the assigned ID, word count (target <300 words for the body), the number of EARS outcomes, and any self-critique flags that were left unresolved. Note that spec-check was auto-invoked and its report follows. Report the diff (or path + ID + counts as appropriate); defer the Next: line to the auto-triggered spec-check per the Handoff convention in spec-init. If spec-check is not installed, append a plain note that drift verification must be run manually.
Offer to plan the implementation of I-<N_new>. Follow the Planning handoff below.
propose ["<title>"]The fast, capture-first path: instead of interviewing the user section by section, you draft the whole intent from context, show it, and write only on the user's explicit accept. This is new with the elicitation replaced by a single draft-and-approve loop — the human-owned boundary is preserved as an accept-gate, not an authoring interview. Reach for it when the user wants to capture intent quickly before building, or when you (the coding agent) are about to implement non-trivial behavior that no open intent covers.
new: the working directory MUST contain specs/INTENT/ (else refuse and point the user to /spec-init). If specs/CONSTITUTION.md exists, read it and keep its principles in mind.new's job, and reproducing it here defeats the purpose.new (steps 2–3): glob specs/INTENT/I-*-*/, compute N_new = max(N) + 1, derive the slug with the same edge-case rules. Do NOT create the folder yet.[test: <runner>:<target>] citation), Non-Goals, Constraints — to the same standard new holds, following the EARS rules and Test citations below. Because this is capture-first, the cited tests don't exist yet: cite the paths you intend to write (greenfield), exactly as new does. Then run the self-critique pass (step 7 of new) over your own draft and validate it against the constitution (step 8 of new).intent.md: the assigned I-<N_new>, title, slug, and every section body with its citations. In the same message, surface: any unresolved self-critique flags, any constitution conflict you found, and a one-line note that the cited tests are greenfield (they will read fail (test not found) until written — the correct pre-implementation signal).I-<N_new>, or tell me what to change?"
specs/INTENT/ during this loop./spec-constitution. Never finalize an intent that violates a principle.mkdir -p specs/INTENT/I-<N_new>-<slug>/, no experiments/ subdir — lazy, like checks/) and run the same write-and-handoff sequence as new steps 9–13: write intent.md from INTENT.template.md, seed agent-prompt files for any local agent: citations, auto-trigger spec-check --intent I-<N_new>, report, and offer the Planning handoff. "Accept with edits" (the user tweaks wording as they approve) is still an accept — fold the edits in and finalize.refine [--intent I-N]--intent I-N is passed, use it. If no folder matches specs/INTENT/I-N-*/, refuse and list the existing IDs.specs/INTENT/I-*-*/intent.md and read each frontmatter status. Collect those with status in {draft, in_progress} — the open intents.
--intent I-N, listing every intent ID and status (including terminal complete and superseded intents — refining a terminal intent to fix a typo or append a Change Log clarification is legal here). Do NOT guess.Last updated: line, and optionally the title: frontmatter field). NEVER touch skill-managed frontmatter fields. NEVER delete or overwrite Change Log entries.[test: agent:<path>] citations whose target lives under specs/INTENT/I-N-<slug>/checks/. Apply the same logic as step 10 of new: mkdir -p the parent directory; create the file pre-populated with the SHALL line under ## SHALL and a ## Success criteria placeholder, only if the file does not yet exist. Never overwrite. Refines that only modify existing agent citations (e.g., changing the prompt path) do NOT delete the old seed file — that's the user's call.spec-check --intent I-N. A Change Log append means drift is possible; checking immediately is cheaper than discovering it later.I-N. Follow the Planning handoff below — a refinement may have moved the outcomes enough to warrant (re)planning.supersede --intent I-N --by-new "<title>"I-N. If --intent is missing, apply the same single-open-auto-pick rule as refine. If the resolved intent already has status: superseded, refuse — an intent can be superseded only once.new subcommand pipeline (elicit, write EARS, self-critique, constitution check) to produce specs/INTENT/I-<M>-<new-slug>/intent.md, where M = max(existing N) + 1. Override the new pipeline's default Change Log seed with this single combined line (substitute today's date and the predecessor's ID):
- **YYYY-MM-DD** — Initial draft. Supersedes I-<N>.I-N/intent.md frontmatter:
status: supersededsuperseded_by: I-<M>closed: <today> if not already set- **YYYY-MM-DD** — Superseded by I-<M>. to its Change Log. Body sections (Problem, Outcome, Non-Goals, Constraints) are left untouched — they remain as the historical record of what I-N tried to do.spec-check --intent I-<M> on the successor only — the predecessor is terminal and does not need re-checking. (spec-check will skip a superseded intent unless explicitly named.)I-<M> (the predecessor is terminal and gets no offer). Follow the Planning handoff below.After an intent is written (new), refined (refine), or opened as a successor (supersede), offer to hand it straight to /plan. This is a thin handoff — you feed /plan the intent and point its output at the intent folder; you do NOT reimplement exploration, design, or approval here. /plan owns that loop.
I-N is captured — want to plan its implementation now?" The offer is opt-in. On "no" or no response, stop — the handoff is complete and silence is the terminal signal.spec-check flagged unverifiable citations, add a one-line aside that /spec-intent refine may be the better first move (to make the SHALLs mechanically checkable). Do NOT suppress the plan offer — just inform; the user decides./plan. Activate plan mode with specs/INTENT/I-N-<slug>/intent.md as the requirements input, and instruct /plan to write its plan to specs/INTENT/I-N-<slug>/plan.md — overriding /plan's default plan-file location. From there, /plan runs its own workflow and owns the plan's format; spec-intent's job ends.intent.md for the plan. The plan is not a change to the intent, and touching intent.md would bump its git timestamp and make spec-check report spurious intent ahead drift before any code exists. plan.md stands alone as a discoverable sibling.plan.md is agent-writable and regenerable — intent.md remains the source of truth. Re-running the handoff after a refine simply overwrites the prior plan.md.
WHEN <trigger> THE SYSTEM SHALL <response>. Both clauses are required.IF ... THEN THE SYSTEM SHALL ... for conditional invariants and WHILE ... THE SYSTEM SHALL ... for continuous behaviors. These are also valid EARS forms.Each EARS outcome SHOULD carry one or more [test: <runner>:<target>] markers so spec-check can verify the SHALL by executing code or by spawning a subagent against a curated prompt — not by grep + LLM judgment (which no longer exists). The marker may appear inline at the end of the EARS line, or as indented sub-bullets directly under it (use sub-bullets when the line gets long or there are >1 tests):
- **WHEN** user submits the form **THE SYSTEM SHALL** show a toast within 200ms. [test: pytest:tests/test_form.py::test_toast_latency]
- **WHEN** input is invalid **THE SYSTEM SHALL** preserve form state and display a retry banner.
- [test: vitest:src/form.test.ts -t "preserves state on invalid input"]
- [test: vitest:src/form.test.ts -t "shows retry banner"]
Allowed runners (anything outside this list is rejected by spec-check):
| Runner | Citation | Command spec-check runs |
|---|---|---|
pytest | pytest:<test-id> | pytest -x <test-id> |
vitest | vitest:<args> | npx vitest run <args> |
jest | jest:<args> | npx jest <args> |
cargo | cargo:<test-name> | cargo test <test-name> |
go | go:<-run pattern> [pkg] | go test -run <pattern> <pkg or ./...> |
shell | shell:<command> | the command verbatim (escape hatch — use sparingly) |
agent | agent:<path-to-prompt-file> | spawns a subagent with the prompt file + EARS line + scope hints; structured verdict required |
The shell: runner is allowed but flagged in spec-check reports as a weaker signal than a structured runner, because it bypasses test-runner conventions (exit codes are still authoritative). Prefer a structured runner whenever possible.
The agent: runner is the second-weakest signal in the citation grammar — strictly weaker than any process runner. Prefer a process runner whenever the SHALL can be expressed as a deterministic test. Reach for agent: only when the SHALL is genuinely unprogrammable — a UX claim ("error copy MUST be concise and actionable"), a doc-structure invariant ("the README MUST mention installation before usage"), or a narrative-consistency check across files. The prompt MUST live in a file (specs/INTENT/I-N-<slug>/checks/<name>.md by convention) and MUST NOT be inlined into the citation. spec-check invokes a subagent against the prompt file and parses a structured verdict; cost and runtime are both higher than a process runner (5-minute per-check timeout vs. 60 seconds). spec-intent lazily creates the checks/ directory and seeds the prompt file with the SHALL when a citation references a path inside the local intent folder — the user enriches the seeded ## Success criteria section over time. Agent-backed passes never count toward the strictest _passed_by_test ratio.
A test citation MUST point at a single test (or a tight -k / -t / -run filter). Whole-suite citations like pytest:tests/ are rejected — one SHALL → one test (or a small named group), so a regression maps to a specific outcome. An agent: citation MUST point at a single prompt file, not a directory or a glob; multiple outcomes MAY reuse the same prompt file when the same check genuinely applies, but each cites it explicitly.
status, closed, verdict_outcomes_passed, verdict_outcomes_passed_by_test, verdict_outcomes_total, verdict_checked_at) directly — only spec-check writes those. Exception: the supersede subcommand sets status: superseded, superseded_by: I-<M>, and closed: <today> on the predecessor (step 4 of subcommand 4). That is the one documented mutation of skill-managed fields by spec-intent; all other writes to these fields are forbidden.superseded_by outside the supersede subcommand. The chain I-N → superseded_by → I-M is the durable handle that spec-check uses to skip terminal intents. Breaking it silently invalidates downstream skills.I-N-<slug>/ folder. The folder name is the durable handle that superseded_by relies on.specs/CONSTITUTION.md. Surface the conflict instead.TBD with a self-critique flag rather than inventing detail.complete subcommand — completion is derived by spec-check from outcome pass-counts, not declared by the user.intent.md outcome or sub-bullet. Prompts live in their own files under specs/INTENT/I-N-<slug>/checks/; citations carry only the path.agent: citation when a process runner would express the same SHALL. The agent runner is a strictly weaker signal and should be reached for only when the SHALL is unprogrammable.## Success criteria placeholder on first cite (step 10 of new, step 8 of refine); enriching ## Success criteria and everything after is the user's responsibility. Agent prompt files are user-owned./plan's exploration/design/approval loop inside this skill. The handoff is thin: pass the intent in, point the output at plan.md, and let /plan run.plan.md become the source of truth. intent.md governs; plan.md is a regenerable, agent-writable working doc.intent.md, create the intent folder, or seed any file in propose mode before the user explicitly accepts the drafted intent. The draft lives only in the conversation until accept — that accept is the human-owned write gate.propose accept-gate as license to skip approval. Delegating the drafting of an intent to the agent never delegates its approval; specs/INTENT/ stays human-owned. "Accept with edits" counts as approval; silence or a change request does not.npx claudepluginhub jasonlo/lite-spec --plugin lite-specGuides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.