Study guide: Part 7. Feature Specification

Lesson 2 of 5 in module «Part 7. Feature Specification»
You are viewing the lesson without signing in. Sign in to save progress and take tests.

Topic: Part 7. Feature Specification

Difficulty level: Medium

Estimated study time: 4-6 hours (theory 2 hours, practice 3-4 hours)

Prerequisites: Basic understanding of Git and working with branches

Familiarity with Markdown and document structure

Understanding of project roadmap concepts (Part 6 of the course)

Basic knowledge of TypeScript and web frameworks (Hono, Express, or equivalents)

Experience working with command line and npm

Learning objectives: Create a complete feature specification from three files (requirements.md, plan.md, validation.md) that prevents 'scope creep' when working with an AI agent

Formulate verifiable assertions in validation.md, replacing vague wishes with specific commands and expected results

Apply negative requirements ('What should not change') to protect existing functionality from unwanted agent modifications

Conduct a clarification step (/clarify) to identify ambiguities before code implementation begins

Use EARS and Given/When/Then formats to eliminate ambiguity in requirements and verification scenarios

Overview: Feature specification is a critical stage between the roadmap and writing code, which prevents turning a small phase into half a product. In the context of working with AI agents (Qwen Code), the specification serves as a 'contract' that limits the agent's freedom and provides specific acceptance criteria. The study guide is built around a real project 'Hello Hono': installing the Hono framework, launching a TypeScript server, serving a minimal HTML page, and type checking. Key principle: the textual specification guides the agent, but merging decisions remain with the human based on verifiable facts.

Key concepts: Feature boundaries (scope boundaries): Clear definition of what is and is not included in the task. Includes two aspects: 'Out of scope' (what we don't add) and 'What should not change' (what already works and must continue working). Without these constraints, the agent may 'improve' what wasn't broken, or add functionality not planned for the phase.

Negative requirements: Explicit prohibitions on changes: which URLs remain the same, which fields are not renamed, which dependencies are not updated 'along the way', which configuration files remain untouched. This is protection against regressions that tests won't catch, because there is no test for the old behavior yet.

Verifiable facts: Criteria in validation.md that have a specific verification command and expected result. Contrasted with vague formulations like 'everything should work'. Each fact includes: command, expectation, responsible party (manual/automatic verification), status.

Clarification step (/clarify): A separate stage between intent and plan, where the agent asks targeted questions about places with alternative interpretations. Signs of necessity: the agent itself mentions dual understanding; externally agreed points require mutually exclusive decisions; the decision depends on an external service; your answers contradict each other. 6+ questions is a signal that the phase is too large.

EARS format: Лёгкий Approach to Requirements Syntax — a micro-format for functional requirements: 'WHEN <condition/event> THE SYSTEM SHALL <expected behavior>'. Eliminates ambiguity about who and under what conditions must do something.

Given/When/Then format: Structure for acceptance scenarios in validation.md: 'Given <precondition> When <action> Then <expected result>'. Turns prose into a concrete testable scenario.

Specs/ structure: Naming convention: specs/YYYY-MM-DD-feature-name/ with three files. The date makes the work order clear, kebab-case links the folder to the Git branch. Three files: requirements.md (intent and boundaries), plan.md (implementation order), validation.md (how to accept the result).

Specification readiness (readiness checklist): Seven items that must be completed before moving to code. Key one: 'The same person who wrote the specification can name the criterion "this phase is finished"'. If the person cannot answer — the agent certainly won't be able to.

Practice exercises: Name: Exercise 1: Converting Vague Requirements to EARS

Problem: Given three informal requirements for the 'Hello Hono' feature:

  1. 'Server should work fast'
  2. 'User sees the main page'
  3. 'TypeScript should not complain'

Convert each to EARS or Given/When/Then format, eliminating all ambiguities. Determine what additional questions need to be asked of the customer for clarification.

Solution: Step 1: Analysis of problems in original formulations.

  • 'Fast' — immeasurable; needs a concrete threshold (response time < 100 ms?)
  • 'User' — not defined; which HTTP client?
  • 'Not complain' — subjective; needs a specific command and expected exit code

Step 2: Conversion to EARS/Given-When-Then.

  1. EARS: 'WHEN a GET / request is executed, THE SYSTEM SHALL return a response in less than 100 ms when running locally on port 3000.'

Clarifying question: 'Which measurement tool to use? (curl -w "%{time_total}"? k6? Built-in logs?)'

  1. Given/When/Then: 'Given server is running on port 3000. When curl -s http://localhost:3000 is executed. Then HTTP status equals 200, Content-Type contains text/html, body contains <h1>AgentClinic</h1>.'

Clarifying question: 'Should the page contain only h1 or other elements too? What exactly is the slogan text?'

  1. EARS: 'WHEN the command npm run typecheck is executed, THE SYSTEM SHALL exit with code 0 without errors or warnings.'

Clarifying question: 'Are warnings acceptable or is strict zero required? Which TypeScript version?'

Step 3: General principle: every metric must have a measurement tool, every condition — a reproduction method, every result — an acceptance threshold.

Complexity: beginner

Name: Exercise 2: Creating a Complete Specification for the 'API Health Check' Feature

Problem: Your roadmap contains a phase: 'Add GET /health endpoint for server health monitoring'. Create a complete specification of three files for this feature. Conditions:

  • Project already uses Hono + TypeScript
  • There is already a GET / route returning HTML
  • Cannot add new dependencies outside tech-stack.md
  • Need health verification via curl
  • Feature should be intentionally small

Write requirements.md, plan.md, and validation.md. Then conduct a self-check against the readiness checklist.

Solution: Step 1: Creating requirements.md

# Requirements — API Health Check

## Boundaries
- Add GET /health route returning JSON with server status.
- JSON contains status field with value "ok" and timestamp field with ISO string of current time.

## Out of scope
- No connection to real external services (DB, Redis, etc.).
- No authentication on the endpoint.
- No response formats other than JSON for this route.

## What should not change
- GET / route continues to return HTML with <h1>AgentClinic</h1>.
- Strict TypeScript mode remains enabled.
- package.json does not receive new dependencies.
- Server port remains 3000.

## Decisions
- Use built-in Date for timestamp, without external libraries.
- Return status 200 for 'ok', without complex state logic.

## Context
Phase is intentionally minimal. Health check is needed for future monitoring, not for diagnostics.

Step 2: Creating plan.md

# Plan — API Health Check

## Group 1 — route
1. Add GET /health handler to existing Hono application.
2. Return object { status: "ok", timestamp: <ISO string> }.
3. Set Content-Type: application/json header.

## Group 2 — typing
4. Define HealthResponse interface in src/types.ts or inline.
5. Confirm that TypeScript compiles without any.

## Group 3 — verification
6. Run npm run typecheck.
7. Run npm run dev.
8. Execute curl -s http://localhost:3000/health | jq .
9. Confirm that curl http://localhost:3000/ still returns HTML.

Step 3: Creating validation.md

# Verification — API Health Check

## Fact set

### F1 — TypeScript compiles
- Command: npm run typecheck
- Expectation: exit code 0
- Responsible: automatic verification

### F2 — health endpoint is accessible
- Command: curl -s http://localhost:3000/health
- Expectation: HTTP 200, Content-Type: application/json, body parses as JSON
- Responsible: manual or automatic verification

### F3 — response format is correct
- Command: curl -s http://localhost:3000/health | jq -e '.status == "ok" and .timestamp != null'
- Expectation: jq returns true (exit code 0)
- Responsible: manual verification

### F4 — existing route is not broken
- Command: curl -s http://localhost:3000/ | grep -o '<h1>AgentClinic</h1>'
- Expectation: substring found, grep exit code equals 0
- Responsible: automatic verification

### F5 — boundaries have not expanded
- Check: git diff --name-only
- Expectation: only src/* changed, no new dependencies in package.json
- Responsible: manual verification

Step 4: Self-check against readiness checklist

  • [x] Intent is clear without chat history: 'add minimal health check'
  • [x] Boundaries are concrete: JSON with two fields, no external services
  • [x] 'What should not change' is filled: protected route /, port, dependencies
  • [x] All decisions are recorded: built-in Date, status 200
  • [x] Plan is broken into groups with verifiable results
  • [x] Every fact has a command: typecheck, curl, jq, grep
  • [x] I can name the readiness criterion: 'all F1-F5 pass'

Result: specification is ready for implementation.

Complexity: intermediate

Name: Exercise 3: Identifying Ambiguities (Clarification Step /clarify)

Problem: You received the following draft specification from the agent for the 'Hello Hono' feature. Find all ambiguities that will lead to different implementations by different agents or people:

# Requirements — Hello Hono (draft)

## Boundaries
- Install Hono and set up server.
- Make the main page beautiful.

## Out of scope
- Don't add extra stuff.

## What should not change
- Everything as it was.

## Decisions
- Use good practices.

## Context
- Fast and high quality.

Formulate specific questions for the /clarify step. Determine which ambiguities are critical (block implementation) and which are non-critical.

Solution: Step 1: Systematic analysis of ambiguities by categories.

Category 'Install and set up':

  • 'Hono' — which specific version? With ^/~ or fixed?
  • 'Set up server' — which port? which runner (tsx, ts-node, node --loader)?
  • 'Install' — what other dependencies? only hono or also tsx? dev/prod?

Category 'Main page':

  • 'Beautiful' — impossible to verify; which specific elements? (h1, slogan, styles?)
  • 'Main page' — which URL? GET / or GET /home?
  • 'Page' — HTML, JSON, or Hono JSX? server or client rendering?

Category 'Out of scope':

  • 'Extra stuff' — not defined; what counts as 'needed' vs 'extra'?
  • No concrete list of prohibited items: DB? authentication? tests? CI?

Category 'What should not change':

  • 'Everything as it was' — for a first phase there is no 'was', but even if there is — what specifically?
  • No protection for tsconfig.json, package.json, .gitignore, existing scripts

Category 'Decisions':

  • 'Good practices' — whose? which specifically? strict TypeScript? linter?
  • No record of preserving/changing strict mode

Category 'Context':

  • 'Fast' — what time frame? or intentionally small phase?
  • 'High quality' — by what criteria?

Step 2: Prioritization of questions for /clarify.

Critical (block implementation — 6+ questions, requires separate step):

  1. What is the exact Hono version and how to install it (with ^/~ or fixed)?
  2. Which port and which runner for development (tsx, ts-node)?
  3. Does GET / return HTML via Hono JSX or pure string? Which specific elements in the response?
  4. What exactly is out of scope: DB? authentication? test framework? CI? deployment?
  5. Which files/settings should not change during installation (tsconfig strict, .gitignore)?

Non-critical (can be left to discretion, but better to clarify):

  1. Is a specific slogan needed or any that fits the mission?
  2. Should the phase be 'intentionally small' or is there expectation of a full page?

Step 3: Decision on necessity of separate clarification. Since 7+ critical questions were found, this is a signal that either the phase is too large, or the constitution (mission.md/tech-stack.md) leaves too many open decisions. Recommendation: stop, update tech-stack.md (specify versions, runner, port), then return to specification.

Step 4: Formulating the request for the agent.

Before writing requirements.md, plan.md, and validation.md, list all places where you still have alternatives. Ask me exactly one question for each: what to choose and why. Don't suggest your answer before my choice. Don't guess.

Expected result: the agent should identify the same 7+ ambiguities. If the agent finds fewer than 3 — this is itself a problem: the agent is not critical enough about ambiguities.

Complexity: advanced

Name: Exercise 4: Specification Readiness Verification

Problem: Given a specification for the feature 'Add search by article titles'. Conduct an audit against the readiness checklist, find violations, and suggest fixes.

# Requirements — Title Search

## Boundaries
- User can search for articles.
- Results are relevant.

## Out of scope
- We don't do full-text search.

## What should not change
- (empty)

## Decisions
- Will be fast.

## Context
- Important feature for users.

plan.md contains 15 steps, including 'Set up Elasticsearch', 'Add Redis caching', 'Make admin panel for index management'.

validation.md contains: 'Search works', 'Results look good', 'Users are happy'.

Solution: Step 1: Check against readiness checklist with violations.

[ ] Intent and audience are clear without chat history. VIOLATION: 'User can search for articles' — which user? registered or any? What search interface? FIX: 'WHEN an anonymous user enters a string in the search field on the main page, THE SYSTEM SHALL return a list of articles whose titles contain that string (case-insensitive, maximum 20 results).'

[ ] 'What is included' and 'what is out of scope' are formulated concretely. VIOLATION: 'Results are relevant' — immeasurable; 'We don't do full-text' — but plan.md has Elasticsearch (that's a full-text engine!). FIX: Boundaries — 'Search only by title field in existing articles table, via SQL LIKE with index. Maximum 20 results, sorted by publication date.' Out of scope — 'No separate search engine (Elasticsearch, Meilisearch). No search by article content. No autocomplete. No filters by date/author.'

[ ] 'What should not change' block is filled. VIOLATION: Empty, although there is an articles table with fields id, title, content, published_at. FIX: 'Existing articles table does not get new columns. Title field is not renamed. API response format for GET /articles/:id does not change.'

[ ] All made decisions are recorded; open ones are marked. VIOLATION: 'Will be fast' — not a decision, but a wish. No implementation decisions, but plan.md has complex technologies. FIX: 'Decision: use SQL LIKE with B-tree index on title. Constraint: up to 1000 articles, then migration to dedicated search. Expected response time < 200 ms for 95th percentile.'

[ ] Plan is broken into groups with verifiable results. VIOLATION: 15 steps, no grouping, steps from different phases mixed (Elasticsearch, Redis, admin panel — these are 3 separate features). FIX: Break into phases. Current phase — 'Basic title search': Group 1 (SQL query), Group 2 (API endpoint), Group 3 (performance tests). Elasticsearch and Redis — into future roadmap phases.

[ ] In validation.md every fact has a command or manual scenario. VIOLATION: 'Search works', 'looks good', 'users are happy' — none can be verified by command. FIX:

  • F1: 'curl "http://localhost:3000/api/search?q=test" | jq -e ".results | length > 0"' — expectation: code 0
  • F2: 'k6 run search-perf.js' — expectation: p95 < 200 ms
  • F3: 'curl with non-existent query' — expectation: empty results array, code 200

[ ] One person can name the criterion 'phase is finished'. VIOLATION: The specification author cannot say when 'users are happy'. FIX: 'Phase is finished when F1-F3 pass automatically, and manual verification confirms that search for 'test' finds an article with title 'Testing Guide'.'

Step 2: Overall verdict. Specification is NOT ready for implementation. Required: shrink the phase, move Elasticsearch/Redis/admin panel to future phases, rewrite requirements in EARS, fill negative requirements, rewrite validation.md with specific commands.

Complexity: intermediate

Case studies: Name: Case: How Specification Saved AgentClinic Startup from 'Eternal Beta Feature'

Scenario: A team of 2 developers was creating an MVP for a medical assistant on Hono + TypeScript. The roadmap contained a phase 'Hello Hono' — basic server with one page. The developer assigned implementation to an AI agent (Qwen Code) without prior specification, merely saying 'make a beautiful main page on Hono'.

Challenge: The agent, having no concrete boundaries, implemented in one 'phase': Hono installation, Tailwind CSS setup, creation of 5 routes (/, /about, /contact, /features, /pricing), integration with a feedback form, preparation for deployment on Vercel, and even a draft of authentication via GitHub OAuth. Result: 47 changed files, 12 new dependencies, broken existing typecheck script due to TypeScript version conflict. A phase planned for 2 hours stretched to 3 weeks of fixes. The team lost focus, technical debt appeared before the real product began.

Solution: After the failure, the team implemented mandatory three-file specification. To fix the situation: 1) Created branch phase-1-hello-hono-v2; 2) Wrote requirements.md with strict boundaries ('one GET / route, HTML with h1 and slogan, no DB, no authentication, no deployment'); 3) Added 'What should not change' block with protection for tsconfig.json and existing scripts; 4) Recorded specific commands in validation.md: curl for HTML verification, npm run typecheck for TypeScript, git diff for boundary control; 5) Conducted /clarify step, where the agent identified 4 ambiguities (Hono version, tsx vs node runner, HTML response format, inline styles permissibility) — all closed before code.

Result: Second attempt of the phase took 3 hours instead of 3 weeks. 4 files changed, 2 new dependencies (hono and tsx, as in tech-stack.md). Typecheck script continued working. The team could immediately move to phase 2 (DB connection), having a stable base. Key metric became 'time from specification to phase acceptance' — reduced from 504 hours to 3 hours (168-fold improvement).

Lessons learned: Lack of specification is not 'time savings' but a lottery with exponentially growing risks; the agent interprets 'small feature' through the lens of all 'best practices' it knows

'What should not change' block is critically important for protection against 'improvements': the agent 'fixed' tsconfig by disabling strict mode to 'resolve' version conflict — without an explicit prohibition this cannot be stopped

/clarify step with 4 questions turned out to be optimal range (0-2 — insufficient criticality, 6+ — phase too large); 4 questions allowed closing all ambiguities in one round

validation.md as 'set of verifiable facts' gave an objective completion criterion: when curl returns <h1>AgentClinic</h1> and typecheck passes — phase is done, disputes are impossible

Related concepts: Feature Boundaries (Scope Boundaries)

Negative Requirements

Verifiable Facts

Clarification Step (/clarify)

Specification Readiness (Readiness Checklist)

Name: Case: Failure Due to Missing /clarify in Corporate Migration

Scenario: A large company (200+ developers) migrated an internal tool from Express to Hono. Phase 'Hello Hono' at scale: install Hono, ensure compatibility with existing middleware. Senior developer wrote specification without clarification step, relying on 10 years of experience.

Challenge: The specification had an implicit assumption: 'middleware compatibility' meant 'all 47 existing middleware work without changes'. The agent understood differently: 'rewrite key middleware to Hono-compatible analogs'. Result: the agent rewrote 12 middleware, including a custom logger used by 15 other services. Logger breakage was only detected in production when metrics stopped flowing to Datadog. Rollback took 6 hours, incident affected 2000+ users.

Solution: After the incident, the team made /clarify mandatory for all phases touching shared code. To fix: 1) Rollback to Express; 2) New specification with explicit separation: 'middleware used by >1 service are NOT rewritten, but wrapped in adapter'; 3) Separate phase 'Middleware Audit' before any migration; 4) validation.md included verification: 'curl on /health of all dependent services returns 200 with log in Datadog within < 5 minutes'.

Result: Second attempt passed without incidents. Migration time increased from planned 2 days to 5 days (due to additional audit phase), but zero downtime and zero incidents. Management acknowledged: 'Slower but predictable' is better than 'fast but with an accident'. The /clarify process became mandatory in specification CI.

Lessons learned: Experience does not replace /clarify: the expert knows that 'compatibility' is ambiguous, but forgot to explicitly record it; the agent has no context that 'shared code = do not touch'

validation.md must include integration checks, not just unit checks: 'typecheck passes' does not guarantee that Datadog receives logs

The '6+ questions on /clarify' sign works for experts too: if an expert cannot quickly answer the agent's questions — it means their own understanding has gaps

Negative requirements are needed not only for code but also for process: 'middleware used by >1 service' — this is a meta-constraint that the agent cannot derive from code

Related concepts: Clarification Step (/clarify)

Negative Requirements

Verifiable Facts

Specification Readiness (Readiness Checklist)

Study tips: Practice on 'toy' features before a real project: take a familiar tool (e.g., adding dark theme to a personal blog) and write a complete three-file specification. Compare with the readiness checklist — you'll find 5-10 violations even if you think 'everything is clear'

Use the 'fresh eyes' technique: after writing the specification, give it to a colleague or even a neural network with the prompt 'find ambiguities'. A fresh perspective finds what the author considered 'obvious'

For visual learners: create a physical or digital board with three columns (In scope / Out of scope / Does not change). Move stickers between columns — this visualizes boundaries better than text

For kinesthetic learners: conduct a 'role play' — you are the developer, your partner (or second AI instance) is the agent that 'doesn't understand context'. The partner must ask questions about every sentence of the specification. Record the questions — this is your /clarify

Form a habit: before git commit of specification, check validation.md with the question 'can someone else, who hasn't read the chat, understand when the phase is done?' If you need to explain verbally — rewrite

Create a personal template for specs/: copy examples from this guide, adapt for your tech-stack, use as boilerplate. Saves 30 minutes per feature and reduces risk of missing a block

Practice EARS and Given/When/Then on everyday tasks: 'WHEN I open the refrigerator, THE SYSTEM SHALL show milk' — funny, but trains the pattern. In a week the formulations will become automatic

For auditory learners: record yourself on video explaining the specification 'out loud'. When listening, you'll notice places where you stumble — these are hidden ambiguities

Additional resources: Github spec kit (original methodology): https://github.com/github/speckit — primary source of /clarify concept and specification structure, adapted in this course for working with AI agents

Ears requirements syntax (nigel rae): https://www.betteruserstories.com/ears/ — official guide to EARS micro-format with examples for different domains (aviation, medicine, web)

Given-when-then (cucumber/gherkin): https://cucumber.io/docs/gherkin/reference/ — reference for Given/When/Then format used in BDD; helps write validation.md as executable specifications

Hono framework documentation: https://hono.dev/ — official documentation of the framework used in the study project; necessary for understanding 'Hello Hono' context

Course 'Project Rules' (part 6 of this course): Internal course resource — roadmap, mission.md and tech-stack.md, which are inputs for feature specification

Article 'writing great specifications' (kamil nicieja): https://www.manning.com/books/writing-great-specifications — book on Specification by Example; chapter 3 ('Living Documentation') is directly applicable to validation.md

Interactive requirements formulation trainer: https://www.reqtest.com/requirements-management-blog/how-to-write-good-requirements/ — set of exercises on converting bad requirements to good ones (in English, but concepts are universal)

Summary: Feature specification is a 'contract' between human and AI agent, preventing a small phase from turning into half a product. Key principles: 1) Three files (requirements.md — intent, plan.md — order, validation.md — verifiable facts); 2) Two lines of boundary defense ('Out of scope' and 'What should not change'); 3) Formalization via EARS and Given/When/Then where prose is ambiguous; 4) Mandatory /clarify step to identify alternative interpretations before code; 5) Readiness checklist where the criterion is 'I can name when the phase is done'. The 'Hello Hono' study project demonstrates practical application: from Git branch to specification commit without a single line of code. Remember: the textual specification guides the agent, but merging decisions remain with the human based on facts, not wishes.

My notes
0 / 10000

Notes are saved in this browser. They will not appear on another device.

Course menu

Course

Specification-Driven Development with Qwen Code CLI
Progress 0 / 135