speckit.specify: Write Requirements Without Naming the Tech Stack
A complete guide to using speckit.specify to write clean Golang feature specifications: user stories, business rules, and scope definition that work without ever naming the tech stack.
specify feature is the most frequently run command in the daily workflow. Every new feature starts here — and the key to success is one simple principle: write what users need, not how to build it.
In this article we cover the techniques that get the best possible spec.md out of speckit specify golang feature specification — a clean document any stakeholder can read.
06.1 The Philosophy
The clearest test of a good spec is who can read it, so start by picturing your audience. The list below names the three people a strong spec must serve.
1A good spec can be read by:
2 - A business analyst who doesn't know Go
3 - A frontend developer who doesn't know PostgreSQL
4 - A product manager who doesn't know what a goroutine is
5
6Good spec answers: who needs what, and what are the business rules?
7Bad spec answers: how to implement it using library X?The takeaway: if your spec is full of pgx.Pool, echo.Context, or kafka.Producer, it isn’t a spec — it’s a premature implementation note. Keep it about behavior and rules, and every one of those three readers stays with you.
06.2 Running specify feature
Every spec begins with the same interactive command, which interviews you about the feature. The command below launches that Q&A.
1specify feature product-searchThe interactive session covers description (2-3 sentences), users, must-do capabilities, must-not scenarios, business rules and constraints, and explicit out-of-scope — then writes .specify/features/product-search/spec.md. The result is a clean business-requirements document with zero tech-stack mentions.
06.3 Good Acceptance Criteria
The single best quality test for an acceptance criterion is whether you can name a test function for it. The mapping below shows ACs translated directly into test names.
1# Each AC should directly become one test function:
2
3AC1 → TestProductSearch_WithKeyword_ReturnsMatchingProducts
4AC2 → TestProductSearch_DeactivatedProduct_NotInResults
5AC7 → TestProductSearch_ShortKeyword_ReturnsValidationErrorThe rule that follows: if you cannot write a test-function name for an acceptance criterion, the criterion is too ambiguous and needs sharpening before the spec is approved.
06.4 Business Rules: Be Measurable
Business rules are only enforceable when they are measurable, so vague phrasing is a bug. The before/after pairs below show how to make rules concrete.
1❌ Ambiguous: "Search results should be relevant"
2✅ Measurable: "Results ranked by text similarity score (higher = first)"
3
4❌ Vague: "Don't allow bad keywords"
5✅ Concrete: "Minimum 2 characters. One-character searches rejected with error."The pattern: replace subjective adjectives (“relevant”, “bad”) with numbers and named behaviors. A measurable rule can become an assertion in a test; an ambiguous one becomes an argument in code review.
06.5 Out-of-Scope: As Important as In-Scope
A spec that never says what it won’t do invites scope creep, so an explicit exclusion list is mandatory. The section below shows how to track out-of-scope items with ticket references.
1## What This Feature Is NOT (Out of Scope)
2- ❌ Autocomplete/typeahead (tracked: SHOP-124)
3- ❌ Search analytics (tracked: SHOP-125)
4- ❌ Personalized results (tracked: SHOP-126)The benefit is twofold: it prevents scope creep during implementation, and it gives you the language to decline mid-sprint requests with “that’s a separate ticket, here’s its number.”
06.6 Spec for Internal APIs
Not every feature is user-facing, and internal service-to-service APIs need specs just as much — arguably more. The command and ACs below specify an internal stock-deduction API.
1specify feature stock-deduction-apiBecause a failure in an internal API can silently corrupt data, its acceptance criteria have to be unusually precise. Here is what a rigorous set looks like for atomic stock deduction.
1## AC for Internal Stock Deduction API
2
3- AC1: Deduction is atomic across all products in one request (all or nothing)
4- AC2: Returns the list of products that failed with a reason (insufficient stock)
5- AC3: Idempotent: same request_id twice = same result (no double deduction)
6- AC4: Stock cannot go below 0 under any circumstanceThe takeaway: internal APIs deserve the same behavioral rigor as customer-facing ones — atomicity, idempotency, and invariants like “stock never negative” are exactly the properties that, left unspecified, cause the worst production incidents.
06.7 Non-Functional Requirements Section
Functional ACs describe what the feature does; a separate NFR section captures how well it must do it. The section below records performance and security targets.
1## Non-Functional Requirements
2
3### Performance
4- Search endpoint: < 500ms p95 at 100 concurrent users
5- Index update: < 60 seconds from product creation
6
7### Security
8- Rate limit: 60 searches/minute per user
9- Never expose seller internal data in resultsAdd this section for any performance- or security-sensitive feature, because specify plan folds these targets into the technical plan — an unstated latency budget can never be designed for.
06.8 Spec Version Tracking
Specs evolve, and a lightweight version header keeps that evolution traceable. The block below shows the changelog convention plus how implementation code references it.
1# Spec Version: v1.3
2# Changelog:
3# v1.3: Added AC11 - search history display
4# v1.2: Clarified AC2 - deactivated product exclusion
5# v1.0: Initial draftReferencing the exact spec version in the code that implements it (// Implements: spec.md v1.3) creates two-way traceability — months later you can answer “which spec version does this code satisfy” without archaeology.
06.9 Spec as Team Contract
An approved spec is not just documentation — it’s a contract between the parties who depend on it. The list below names those contracts.
1Approved spec.md is a contract between:
2 - Engineering ↔ Product: "this is what we'll build"
3 - Backend ↔ Frontend: "this is the API that will exist"
4 - Team ↔ AI: "this is the context for code generation"The practical consequence: when someone asks “should we handle edge case X?”, the answer lives in the spec. If it isn’t there, it is out of scope — and that clarity is what keeps a feature from expanding indefinitely.
06.10 Feature Flags for Non-Interactive Mode
For automation or CI, you can drive specify feature entirely through flags instead of the interactive prompts. The command below supplies every answer up front.
1# Non-interactive mode for automation
2specify feature product-search \
3 --description="Customer product search with keyword and category filter" \
4 --users="Customer" \
5 --capabilities="Search by keyword, filter by category, paginate results" \
6 --rules="Min 2 chars, active products only, max 50 per page" \
7 --out-of-scope="Autocomplete, personalization, price filter"This mode is what lets you generate specs from Jira descriptions or inside a pipeline — the same six inputs, delivered as flags rather than typed answers.
06.11 Spec Quality Score
Spec Kit can grade a spec against objective quality dimensions before you send it for review. The command and report below show the scoring output.
1specify spec quality product-search
2
3# Output:
4# User Stories: ✅ 2/2 stories have clear role and benefit
5# Acceptance Criteria: ⚠️ 10/11 ACs are testable (AC5 is ambiguous)
6# Business Rules: ✅ 4/4 rules are measurable
7# Out of Scope: ✅ Explicit section with ticket references
8# NFR: ⚠️ No performance targets defined
9# Overall Score: 82/100Treat the warnings as a punch list: the report pinpoints the exact ambiguous AC and the missing NFR section, so you fix precise gaps instead of guessing what a reviewer might flag.
06.12 Retroactive Spec from Existing Code
When a feature already exists without a spec, Spec Kit can infer one from the code. The command below generates a spec from an existing handler package.
1# Analyze existing code and generate spec
2specify feature product-list --from-code=internal/product/handler/
3
4# Spec inferred from code, sections marked [INFERRED]This is invaluable for documenting legacy features, establishing a pre-refactoring baseline, or creating an audit trail — just review the [INFERRED] sections carefully, since the tool is reconstructing intent from implementation.
06.13 Multi-Feature Hierarchy
When a single ticket is too large for one spec, Spec Kit supports a parent/child hierarchy. The commands below split an oversized feature into manageable specs.
1specify feature product-management # parent
2specify feature product-management/create # child
3specify feature product-management/search # childThe rule of thumb: if a spec grows past one or two pages, break it into child specs. A parent overview plus focused children is easier to review and implement than one sprawling document.
06.14 Collaboration Workshop Format
Writing a spec is a team sport, and a fixed sequence keeps the workshop productive. The flow below assigns each role its moment.
11. PM writes user stories and ACs
22. Tech Lead reviews for technical feasibility
33. QA adds missed edge cases
44. All review the out-of-scope section
55. Tech Lead approves
66. Status → APPROVED → Engineering startsThe value of this sequence is that edge cases get caught before code exists — QA’s contribution at step 3 is where “obvious” requirements nobody wrote down finally get captured.
06.15 Iterating spec.md
A first-draft spec is rarely final, and Spec Kit gives you commands to refine it in place. The commands below regenerate, extend, and approve a spec.
1# Regenerate with different answers
2specify feature product-search --regenerate
3
4# Add a specific AC
5specify feature product-search --add-ac "AC11: Search results show product thumbnail"
6
7# Update status
8specify feature product-search --status=APPROVEDIteration is expected, not a failure — the fastest path is a “good enough” v1 that you sharpen with these commands and specify clarify, rather than agonizing toward a perfect first draft.
06.16 Tips & Gotchas
Years of writing specs distill into a handful of tips and traps. The list below captures the ones that most improve spec quality.
1💡 Tip 1: Start from "what does the user want", not "what can we build".
2💡 Tip 2: Out of scope is as important as in scope.
3💡 Tip 3: Use concrete numbers — "min 2 chars" beats "a few characters".
4💡 Tip 4: Each AC must be able to become a test — if it can't, it's too ambiguous.
5⚠️ Gotcha 1: "Obvious" requirements are often not written — write them anyway.
6⚠️ Gotcha 2: A spec that's too long doesn't get read — target 1-2 pages.
7⚠️ Gotcha 3: Don't write a spec without understanding the user journey.
8⚠️ Gotcha 4: Don't wait for a perfect spec — "good enough + clarify" wins.If you internalize just Gotcha 1, you’ll avoid the most common spec defect: skipping “obvious” rules like “only active products appear,” which the AI cannot honor if you never wrote them down.
06.17 Spec Review Checklist
Before a spec is approved, a structured checklist keeps reviewers consistent. The list below is the review gate.
1User Story Quality:
2✅ Specific role (not "user")?
3✅ Clear benefit (so that...)?
4✅ Understandable by a non-technical stakeholder?
5
6Acceptance Criteria:
7✅ Each AC becomes one test function?
8✅ No implementation details?
9✅ Error cases covered?
10✅ Happy path covered?
11
12Business Rules:
13✅ All rules measurable?
14✅ No ambiguity?
15✅ Consistent with other features?
16
17Out of Scope:
18✅ Explicit about what is NOT built?
19✅ Ticket references for out-of-scope items?Running this checklist every time is what keeps specs test-ready — a spec that passes all four sections converts almost mechanically into a plan and a test suite.
06.18 The “Spec Workshop” in 30 Minutes
For a complex feature, a timeboxed workshop turns a blank page into a review-ready spec fast. The agenda below fits the whole exercise into half an hour.
1Minute 0-5: PM presents the feature brief
2Minute 5-15: Run `specify feature` together (PM answering questions)
3Minute 15-20: Review the generated spec.md
4Minute 20-25: Tech Lead identifies edge cases
5Minute 25-30: Finalize out-of-scope and success criteria
6→ Spec ready for review in 30 minutesThe takeaway: with the interactive command driving the conversation, thirty focused minutes with the right people beats days of asynchronous document editing — and everyone leaves aligned on scope.
06.19 The Role of spec.md in CI
You can enforce “no feature without a spec” directly in continuous integration. The workflow step below fails the build when an in-progress ticket has no spec file.
1# .github/workflows/spec-check.yml
2- name: Check spec completeness
3 run: |
4 # All features in Jira/Linear must have a spec
5 for feature in $(list-in-progress-tickets); do
6 if [ ! -f ".specify/features/$feature/spec.md" ]; then
7 echo "❌ Missing spec for: $feature"
8 exit 1
9 fi
10 doneThis turns the spec-first discipline into an automated gate: work cannot progress through CI until its spec exists, which is the most reliable way to keep “spec before code” from eroding under deadline pressure.
06.20 Summary
specify feature is the entry point to the SDD cycle with Spec Kit. The key is writing what users need, not how to implement it.
Effective format: a specific user story + numbered acceptance criteria + concrete business rules + an explicit out-of-scope section.
Don’t: mention the tech stack, libraries, SQL, or any implementation detail.
Quality signal: if a PM can read and understand your spec, you’re on the right track.
Iteration is normal: a v1 spec is rarely perfect. Use specify clarify in the next article to fill the remaining gaps with structured questions.