From codacy-specs
This skill should be used when the user wants to 'audit a spec', 'improve a spec', 'review a ticket', 'improve this Jira issue', 'rewrite this story', 'check if this spec is good', 'make this ticket clearer', 'improve this Linear issue', or mentions that a spec needs better acceptance criteria, error handling, or clarity for AI agents. It should ALSO be used as a guardrail before starting implementation work on any ticket, story, or spec — for example when the user says 'start working on PROJ-123', 'implement this ticket', 'pick up the next item', or when an agent is about to begin coding from a specification. In this guardrail context, use Quick Check Mode.
How this skill is triggered — by the user, by Claude, or both
Slash command
/codacy-specs:spec-improveThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Audit any specification for AI-agent readiness and optionally rewrite it to be clear, testable, and unambiguous. Works with Jira issues, Linear issues, and local spec files.
Audit any specification for AI-agent readiness and optionally rewrite it to be clear, testable, and unambiguous. Works with Jira issues, Linear issues, and local spec files.
An AI-agent-ready spec leaves no room for guessing: it states what to build, defines inputs and outputs, specifies error handling, enumerates edge cases, and provides acceptance criteria an agent can verify autonomously.
Determine which mode to use before doing anything else.
Full Audit Mode — use when the user explicitly asks to audit, improve, review, or rewrite a spec. Runs all 6 phases (fetch → type detect → audit → clarify → preview → write back).
Quick Check Mode — use when the trigger is about to start work: "implement this", "start on PROJ-123", "pick up the next ticket", or an agent transitioning from planning to coding. Runs a lightweight check and presents a decision point. See the Quick Check Mode section below.
Use this mode when the skill is triggered as a guardrail before starting implementation — not as an explicit audit request.
⚡ Pre-work spec check: <ID or filename>
Grade: <A/B/C/D/F> (<N>/100) — <READY / CONDITIONALLY READY / NOT READY>
<One sentence explaining the readiness verdict.>
Top gaps:
• [Gap 1 — e.g. "missing acceptance criteria"]
• [Gap 2 — e.g. "no error handling defined"]
• [Gap 3 — e.g. "request schema absent"] ← omit if fewer than 3 gaps
• parent inconsistency: <brief description> ← include if a parent↔child contradiction was found
What would you like to do?
[1] Review and improve — I'll ask clarifying questions and rewrite the spec before we proceed
[2] Continue anyway — skip the review and start implementation
Gaps that are explicitly covered by the parent ticket are not listed in "Top gaps".
If the grade is A or B, skip the options entirely and output:
⚡ Pre-work spec check: <ID or filename>
Grade: <A/B> (<N>/100) — READY
This spec is clear enough to implement. Proceeding.
Identify where the spec lives before doing anything else.
Jira issue: The user mentions a key matching [A-Z]+-[0-9]+ (e.g. PROJ-123, ENG-42, or a full Jira URL). Fetch with the Atlassian MCP tool atlassian:getJiraIssue.
Linear issue: The user mentions a Linear issue ID (e.g. ENG-123, ABC-456, or a full Linear URL). Fetch with linear:<read_tool_name> — verify the exact tool name from your Linear MCP server configuration.
GitHub issue: The user mentions a GitHub issue URL (github.com/owner/repo/issues/123) or a #123 reference while a GitHub repo is in context. Extract owner, repo, and issue_number. Fetch with the GitHub MCP tool github:get_issue.
Local file: The user provides a file path or says "this spec" while a file path is in context. Read with the Read tool.
Inline spec: The user pastes spec text directly into the message. Use the pasted content as-is.
If source is ambiguous, ask: "Is this a Jira issue, Linear issue, GitHub issue, or a local file? Please share the issue key, URL, or file path."
atlassian:getJiraIssue(issueKey: "PROJ-123")
Extract: summary (title), description (body), issuetype (Story/Bug/Task/Epic).
If the tool is unavailable or returns an error, inform the user: "Atlassian MCP is not connected. Please paste the spec content directly or check your MCP configuration."
Parent fetch: After the main fetch, inspect the response for a parent field. If parent.key is present and the current issue is not itself an Epic, fetch atlassian:getJiraIssue(issueKey: parent.key). Extract the parent's title and description. If the fetch fails or the current issue has no parent, continue without parent context (non-blocking).
Use linear:<read_tool_name> to fetch the issue by ID or URL. Verify the exact tool name from your Linear MCP server configuration.
Extract: title, description, issue type/label.
If unavailable, fall back gracefully: "Linear MCP is not connected. Please paste the spec content directly."
Parent fetch: After the main fetch, inspect the response for a parent field. If present, fetch the parent using linear:<read_tool_name> with the parent's ID. Extract title and description. If the fetch fails, continue without parent context (non-blocking).
github:get_issue(owner: "org", repo: "repo-name", issue_number: 123)
Extract: title, body (description), labels (for type detection).
If the user provided a full URL, parse owner, repo, and issue_number from it. If only #123 was given, infer owner and repo from the current git remote (git remote get-url origin) or ask the user to confirm.
If the tool is unavailable: "GitHub MCP is not connected. Please paste the spec content directly or check your MCP configuration."
Parent fetch: GitHub issues have no native parent field in the standard API. Skip silently.
Read(file_path: "<path>")
If the file does not exist, ask the user to confirm the path.
Parent fetch: No parent concept for local files. Skip.
Parent fetch: No parent concept for inline specs. Skip.
This phase summarises what was established in the platform-specific parent fetch steps above and defines "parent context" for all subsequent phases.
Parent context is a record { id, title, description } sourced from the parent ticket (Epic, Feature, or parent issue).
Classify the spec into one of these types based on title, labels, and content keywords:
| Type | Signals |
|---|---|
| API endpoint | "endpoint", "REST", "HTTP", "GET/POST/PUT/DELETE", "request", "response", "schema" |
| UI component | "component", "page", "screen", "modal", "form", "button", "UI", "UX", "design" |
| Backend feature | "service", "worker", "job", "queue", "database", "migration", "business logic" |
| Bug fix | "bug", "fix", "error", "crash", "broken", "regression", issue type = Bug |
| Data migration | "migrate", "migration", "import", "export", "ETL", "transform" |
| Generic / other | Anything that doesn't match the above |
State the detected type clearly: "I've classified this as an API endpoint spec."
Consult references/scoring-rubrics.md for the full rubric for each type.
Run these two steps before applying any rubric scores. They prevent false positives and reduce noise.
1. Project context — Search the working directory for Claude instruction files using Glob:
CLAUDE.md, **/CLAUDE.mdAGENTS.md, **/AGENTS.md.claude/**/*.mddocs/**/*guidelines*, docs/**/*conventions*, docs/**/*standards*Read any files found and extract two things:
✅ Pagination behavior 8/10
↳ covered by project conventions (CLAUDE.md)
If no instruction files are found, proceed without project context.
2. REST defaults (API specs only) — Do not deduct points for omitting universally-implied REST defaults:
application/json for GET, PUT, PATCH success responsesapplication/json for POST responses that create a resourceOnly flag HTTP status codes and Content-Type when: the correct code is ambiguous (e.g. 200 vs 201 for a POST), a non-JSON response type is possible, or it is an error response. Error response codes and bodies should always be specified regardless of whether they are "standard".
3. Parent context — If parent context is non-empty:
a. Inherited coverage: For each audit dimension where the child has a gap (score < 7), check whether the parent's description explicitly addresses it. If it does, raise that dimension's score to 7–8/10 and annotate:
✅ Error handling 8/10
↳ covered by parent PROJ-100 — error strategy defined in epic
Use score 7 when the parent covers the dimension generally; 8 when the parent is specific. Never award 9–10 from parent coverage alone — the child should eventually own its content.
b. Inconsistency detection: Flag explicit contradictions between parent and child. Check for:
Score the spec against the quality rubric. Apply the universal dimensions to every spec. Then apply the type-specific dimensions for the detected type.
Consult references/scoring-rubrics.md for scoring criteria and weights.
Output the report in this exact format:
───────────────────────────────────────────────────────────────
Spec Quality Report: <ID or filename>
Type: <API endpoint / UI component / Bug fix / ...>
Score: <N>/100 (Grade: <A/B/C/D/F>)
───────────────────────────────────────────────────────────────
UNIVERSAL DIMENSIONS
✅ Problem statement 8/10
✅ Scope 7/10
⚠️ Acceptance criteria 3/10
↳ present but not independently testable
❌ Error handling 0/10
↳ missing
❌ Edge cases 0/10
↳ missing
✅ Testability 6/10
TYPE-SPECIFIC DIMENSIONS (<type>)
✅ HTTP method + path 10/10
⚠️ Request schema 3/10
↳ params listed but not typed or constrained
⚠️ Response schema 6/10
↳ example given, enum values undefined
❌ Auth requirements 0/10
↳ missing
⚠️ Error response codes 2/10
↳ status codes listed, response bodies absent
───────────────────────────────────────────────────────────────
PARENT CONTEXT: PROJ-100 (Payment Gateway Epic)
ℹ️ Covered by parent: error handling, auth requirements
⚠️ Inconsistency: child targets Node 18, parent specifies Node 20
───────────────────────────────────────────────────────────────
Agent Readiness: NOT READY
An AI agent working from this spec will make 4+ wrong
assumptions and produce unverifiable code.
───────────────────────────────────────────────────────────────
Formatting rules — follow exactly:
────) and consistent 2-space indentation on every content line.✅ , ❌ , ⚠️ — same for all, no exceptions.↳ <short explanation> — never inline after the score.ℹ️ line listing all covered dimensions (omit if none). Include one ⚠️ line per inconsistency (omit if none).Grade thresholds: A = 85–100, B = 70–84, C = 50–69, D = 30–49, F = 0–29.
Agent Readiness:
After the report, ask: "Would you like me to rewrite this spec to address these gaps? (yes/no)"
If the user says no, stop here. Offer to answer questions about the gaps instead.
Before rewriting, collect information for each missing critical section (score 0/10). Ask one question at a time. Do not proceed to the next question until the user answers.
Critical sections (always ask if missing):
Important sections (ask if score < 4):
Question format:
I noticed this spec has no [section name].
[One focused question about what's needed.]
(Type your answer, or say "skip" to mark it as [TO BE DEFINED].)
If the user says "skip", "don't know", or "move on": record [TO BE DEFINED] for that section and continue.
Do not ask about sections that already have good coverage (score ≥ 7).
Rewrite the full spec incorporating:
references/spec-templates.md[TO BE DEFINED] placeholders for skipped sections[INCONSISTENCY — reconcile with <parent-ID>: <description>]Present the rewritten spec as a clean, formatted document — not a diff. Specs are prose, not code.
Here's the rewritten spec. Review it carefully before I apply it.
---
[Full rewritten spec here]
---
Confirm to apply this to <Jira PROJ-123 / Linear ENG-42 / GitHub #123 / spec.md>, or say "edit" to request changes.
If the user requests changes, apply them and show the updated preview again. Repeat until confirmed.
Never write back without explicit confirmation.
Apply the confirmed spec to its source.
atlassian:updateJiraIssue(issueKey: "PROJ-123", description: "<rewritten spec>")
Pass description as a plain markdown string — not an ADF object. The MCP tool converts markdown to ADF internally.
Confirm success: "PROJ-123 has been updated in Jira."
Use linear:<update_tool_name> with the issue ID and new description. Verify the exact tool name from your Linear MCP server configuration.
Confirm success: "The Linear issue has been updated."
github:update_issue(owner: "org", repo: "repo-name", issue_number: 123, body: "<rewritten spec>")
Pass body as a plain markdown string. GitHub renders markdown natively — no format conversion needed.
Confirm success: "Issue #123 has been updated in GitHub."
Edit(file_path: "<path>", old_string: "<entire original content>", new_string: "<rewritten spec>")
Confirm: "spec.md has been updated."
Output the final spec for the user to copy. Offer to save it to a file: "Would you like me to save this to a file? If so, provide a filename."
Consult these reference files throughout the workflow:
references/scoring-rubrics.md — Full scoring criteria for all spec types and dimensions. Required reading before Phase 3.references/spec-templates.md — Section-by-section templates for rewriting. Use in Phase 5.references/spec-examples.md — Before/after transformation examples. Use for calibration and when unsure how to rewrite a section.If the user asks for "Gherkin acceptance criteria" or "Given/When/Then format", write acceptance criteria using the Gherkin syntax:
Given [precondition that must be true before the action]
When [the specific action or event]
Then [the observable expected outcome]
And [additional assertion, if needed]
Apply this format to all acceptance criteria in the rewritten spec, including error cases:
Scenario: Invalid input
Given a user is authenticated
When they submit the form with an empty required field
Then the API returns HTTP 422
And the response body contains {"error": "VALIDATION_ERROR", "fields": ["fieldName"]}
Gherkin mode does not change the scoring rubric — it only changes the format of the acceptance criteria section in the output.
If the user says "just audit" or "don't rewrite", run Phases 1–3 only. Output the quality report and stop. Do not ask about rewriting.
On acceptance criteria: Every criterion should be independently verifiable by a test. The pattern "Given [state], when [action], then [outcome]" is always a good structure even without full Gherkin mode.
On error handling: Push for specificity. "Returns an error" is not enough. Ask: what HTTP status? What error code in the body? Is it retryable? Does it log? Does it alert?
On scope: If the original spec does not define what is out of scope, scan the content for anything ambiguous and add an explicit out-of-scope bullet. Undefined scope is one of the most common causes of scope creep in AI-generated code.
On edge cases: A reliable heuristic is to ask: what happens when the primary entity is missing, empty, at maximum size, or deleted? These four questions surface the most common uncovered edge cases.
On language: Replace all instances of "should", "must", "may", "could", and "might" with unambiguous declarative language: "returns", "accepts", "rejects", "stores". Hedged language becomes ambiguous instructions for an agent.
On fabrication: When in doubt, use [TO BE DEFINED]. A spec with honest placeholders is safer than a spec with plausible-sounding invented details. An AI agent will try to implement [TO BE DEFINED] by asking; it will silently implement a fabricated spec incorrectly.
[TO BE DEFINED] and move on.CLAUDE.md under a Terminology or Conventions section and it won't be flagged in future audits." Do not auto-edit CLAUDE.md — it is a curated document the team owns. The benefit of putting it there is that all Claude interactions will respect it, not just spec audits.npx claudepluginhub codacy/codacy-specs --plugin codacy-specsTransforms ideas into structured specifications (requirements, design, tasks) before implementation. Use when building features, fixing bugs, refactoring, or designing systems.
Conducts multi-round interviews to refine rough SPEC.md into complete, implementation-ready specifications with tasks. Use for new features, requirements refinement, or ideas to actionable specs.
Manages sudocode specs and issues: view (show_spec, list_issues), create/modify (upsert_spec, upsert_issue), plan features, build dependency graphs, add feedback. Supports markdown editing and Obsidian-style links.