Imported from fhqvst/agents (
specular/skills/specify/SKILL.md). Install upstream withnpx skills add fhqvst/agents --skill specify. Copyright stays with the author.
Specify
Produce a Linear issue with two layers:
- Top (human-facing, terse): Problem, optional Background, Proposal, Constraints, Implementation, References. Reviewers should be able to evaluate the direction in under a minute.
- Bottom (agent-facing, additive): a single Linear
+++ PLAN.mdcollapsible holding what the human-top doesn't cover. Downstream skills (/specular:plan,/specular:implement) read the entire issue body - the human-top plusPLAN.mdtogether are the full brief.PLAN.mdshould not restate Problem, Proposal, or Out-of-scope. The one exception is Implementation: the human-top has a high-level pseudocode glance, andPLAN.mdgoes deeper.
0. Confirm Linear context
SPECULAR.md lists the Linear projects this repo files into (one ### <project> subsection each, with optional Paths and Assignee). To find it, walk upward from the current working directory, checking each parent until you hit SPECULAR.md or reach $HOME / the filesystem root. If none is found, or the file is missing a ## Linear section, tell the user to run /specular:setup first and stop.
1. Grill
Interview the user relentlessly about every aspect of this plan until you reach a shared understanding. Walk down each branch of the design tree, resolving dependencies between decisions one-by-one. For each question, provide your recommended answer.
Ask the questions one at a time, waiting for feedback on each before continuing. If a question can be answered by exploring the codebase, explore the codebase instead.
Anchor in the current UI (nice-to-have, requires Playwright MCP)
This step is opt-in based on tool availability. If a Playwright MCP isn't installed in this session (no mcp__plugin_playwright_playwright__browser_* tools available), skip silently and grill from the codebase alone. Don't ask the user to install anything.
If Playwright is available, decide whether this change ships any user-visible surface. Cues: the seed prompt mentions a URL, or words like page, screen, view, button, drawer, modal, sheet, panel, flow, sidebar, header, layout; the codebase area is clearly frontend; the user explicitly asks ("please look at the page first").
If yes:
- Ask the user for the URL if it isn't in the seed prompt.
- Navigate with
browser_navigateand capture the relevant view(s) withbrowser_take_screenshot. Resize the viewport to a representative desktop size (1440x900) first. - Read the screenshot. Identify the layout primitives (rail, header, sidebar, table, etc.) before asking your first grilling question.
This grounds both you and the user in the same picture before grilling. The screenshots are ephemeral - they don't go in the spec.
Skip this entirely for non-UI changes (DB migrations, infra, internal libraries, etc.) - the inference cue is the absence of UI vocabulary in the seed prompt.
Grilling techniques
- Explore the codebase first. Get oriented before grilling. Read READMEs in the relevant module.
- Sharpen fuzzy language. Propose precise canonical terms. "You're saying 'account' - do you mean the Customer or the User? Those are different things."
- Discuss concrete scenarios. Stress-test relationships with specific scenarios that probe edge cases.
- Cross-reference with code. "Your code cancels entire Orders, but you just said partial cancellation is possible - which is right?"
When the grilling is done, fall through to section 2.
2. Explore the codebase
You already explored the relevant area during grilling - revisit only files you specifically need to cite or to clarify a precise interface.
3. Sketch the modules
List the major modules to build or modify. Look for deep modules: small stable interfaces hiding substantial functionality, testable in isolation.
Show the user the proposed module breakdown and ask:
- Do these modules match your expectations?
- Which ones should have tests?
Iterate until they approve. Keep this lightweight.
4. Write PLAN.md (the agent-facing addendum)
PLAN.md holds what the human-top doesn't cover. Downstream skills read the entire issue body, so don't restate the Problem, Proposal, or Out-of-scope here - they'll get those from the top. The one place restatement is welcome is Implementation: the human-top has a brief pseudocode glance, and PLAN.md goes deeper.
Write PLAN.md first - the human-top in section 6 is derived from it.
Use this template (omit any section that has nothing useful to add):
User Stories
A long, numbered list of user stories in the format:
- As an , I want a , so that
Cover all aspects of the feature - this list should be extensive.
Implementation Decisions
Deeper-than-the-human-top detail on how to build this. The human-top already has the headline pseudocode; this section is for everything that didn't fit there:
- Modules to build or modify (from section 3) and why each exists
- Full interfaces those modules expose (beyond the human-top's "// New" / "// Changed" glance)
- Architectural decisions and the tradeoffs behind them
- Schema changes
- API contracts
- Specific interactions between components
Do NOT include file paths or code snippets - they go stale fast. Pseudocode TypeScript signatures are fine for clarifying interfaces.
Testing Decisions
- What makes a good test here (test external behavior, not implementation details)
- Which modules will be tested (from section 3)
- Prior art - similar tests already in the codebase to mirror
Further Notes
Anything else worth capturing - non-obvious constraints, open questions, references to relevant files.
Hold this content in memory - it goes into the +++ PLAN.md collapsible in section 7.
5. Build a low-fi UX prototype (nice-to-have, requires Figma MCP)
This step is opt-in based on tool availability. If a Figma MCP isn't installed in this session (no mcp__plugin_figma_figma__* tools available), skip silently and proceed to section 6. Don't ask the user to install anything. The spec is fine without a prototype - this is purely additive when Figma is around.
If Figma is available and the change ships any user-visible surface (use the same UI-detection cues as section 1), build a clickable wireframe so reviewers can react to the proposed UX in seconds instead of reading prose.
The wireframe is intentionally low-fi - gray rectangles only, mirroring the real app's shell so the proposed change lands in context. Skip pixel polish; this is a spec-time artifact, not a design deliverable.
- Create a file.
mcp__plugin_figma_figma__create_new_filewith a descriptive name (e.g. " wireframe - "). Get the user'splanKeyfromwhoamiif you don't have it. - Build at least two frames with
use_figma:- One Closed / current-state frame: the existing shell (rail, header, sidebar, table, etc.) as you saw it in section 1's screenshots.
- One Open / proposed-state frame: the same shell with the change in place (drawer slid in, modal open, new section visible, etc.).
- For multi-step flows, add intermediate frames as needed.
- Wire prototype reactions.
ON_CLICK→SMART_ANIMATEbetween frames so the prototype is actually clickable. Setfigma.currentPage.flowStartingPointsto the starting frame. - Verify visually.
get_screenshoton each frame. Fix layout issues before moving on.
Load the figma:figma-use skill before any use_figma call - it's a mandatory prerequisite.
The Figma file URL gets attached to the Linear issue as a link in section 8. The wireframe is referenced from the human-facing top's ## UX section (see section 6).
Skip this entirely for non-UI changes.
6. Derive the human-facing top
Now write the terse top of the body, deriving from PLAN.md. Use this exact structure:
## Problem
[1-3 sentences. What's broken, missing, or painful. Make it concrete -
if there's a user-facing or developer-facing symptom, name it.]
## Background (optional)
[Only include this when the area would be unfamiliar to most reviewers.
A few sentences to orient someone who hasn't touched this part of the
codebase. Skip entirely if the area is well-known.]
## Proposal
[What we're doing and why. Written as a clear direction, not a menu of
options. Should read naturally - not like a template was filled in.
Then, if there are sensible alternatives reviewers might suggest,
preempt them: "Not doing X because Y." Only include alternatives a
reasonable engineer would actually propose. If the approach is
obvious, skip this part entirely.]
## Constraints
**In:**
- [Concrete things that change. Each bullet = one specific thing.]
**Out:**
- [Things we're explicitly not touching. Important because agents
love to "improve" adjacent code.]
## Implementation
[Start with a single sentence describing the core implementation-level
change - the key thing that shifts in the code, not a restatement of
the proposal.
Then a pseudocode summary of interfaces being added or changed, inside
a fenced ts code block. Group into "// New" and "// Changed" sections.
Use short TypeScript-style signatures - just name, params, and return
type. Spread existing params with `...existing`.
Add a short inline `//` comment ONLY when the purpose isn't obvious
from the name and signature alone.
If some areas are too uncertain to spec, use bold sub-headers
(**Interfaces:** and **Open areas:**) to separate them.]
## UX (only if section 5 ran)
[Link to the Figma prototype with one sentence describing what it shows.
Format: `[Figma prototype](<url>) - <one sentence>`. The URL is also attached
to the Linear issue as a link in section 8, so this is a convenience for
in-body readers.]
## References
- [path/to/file](https://github.com/org/repo/blob/main/path/to/file)
- [path/to/other](https://github.com/org/repo/blob/main/path/to/other)
The References section links to 2-5 key files. Determine the org and repo from the git remote URL. Use the file path as the link text.
Writing principles for the human-facing top
- 30-second rule: an engineer should be able to read Problem, Background, and Proposal in under 30 seconds.
- Implementation detail lives in its own section: no code, interfaces, paths, or type signatures in Problem, Background, or Proposal.
- No acceptance criteria: don't write "should X when Y" checklists. The agent derives these from
PLAN.md. - Concrete over abstract: "stack traces point to our wrapper instead of the real throw site" beats "error reporting is suboptimal."
- Lead with the pain, not the cause: the first sentence of Problem should be the symptom.
- Honest alternatives: only mention approaches you genuinely considered and rejected for real reasons.
- Constraints should be short and scannable: one line per bullet.
- One sentence per paragraph in Problem, Background, and Proposal. Separate with double newlines so they render as distinct paragraphs in Linear.
7. Compose the issue body
Final body structure:
<the human-facing top from section 6>
+++ PLAN.md
<the PLAN.md content from section 4>
+++
Linear collapsible syntax: +++ <summary> on its own line, blank line, content, blank line, closing +++ on its own line. Don't use HTML <details> - Linear renders that as raw text.
8. Present and create
Show the composed body to the user. Ask if they want to adjust anything.
Once approved, create the issue with mcp__plugin_linear_linear__save_issue:
- Title: a concise summary derived from the Problem section
- Project / assignee: pick the project whose
Pathsglobs match the RFC's scope (Implementation pseudocode, References, area being touched). If no globs match, fall back to the project with noPathsbullet (the catch-all). If multiple projects match, ask the user which one. The chosen project'sAssignee, if any, is the default; otherwise leave it unset. Team is derived from the project. IDs are baked intoSPECULAR.mdheadings - parse them out rather than re-resolving vialist_projects. Edge case: if## Linearhas flatTeam:/Assignee:bullets and no###project subsections, file under that team with no project, using the listed assignee (if any). - Description: the composed body
links: if section 5 ran, attach the Figma prototype URL as[{url, title: "Figma prototype - <feature>"}]. Linear renders this as a preview card in the issue sidebar.
Report the issue URL.