Introduction: The Role of Complete Specifications

Welcome back! In Unit 2's lesson, you established your project-level constitution with CLAUDE.md. That defines how your entire project works.

This lesson teaches feature-level specifications — detailed blueprints for individual features that reference your constitution.

The hierarchy:

  • 🏛️ CLAUDE.md (Lesson 2) → Project-wide rules
  • 📋 Feature Spec (this lesson) → Rules for one feature

Now let's learn what goes into a complete feature specification. A complete specification is like a detailed blueprint for your code. It tells you exactly what needs to be built, how it should behave, and what to watch out for. This is especially important when working with APIs, where clear communication between different parts of a system is critical.

By the end of this lesson, you will know how to break down a feature into a full specification, use AI to help generate specs, and review real examples to see what a good spec looks like.

Quick Recall: Key Elements of a Specification

Let's quickly remind ourselves what a specification is. A specification, or spec, is a document that describes what a feature or component should do. It does not describe how to implement it, but rather what the expected behavior is.

In the last lesson, you saw a simple spec for an API endpoint. Here's a quick reminder of what a basic spec might look like:

# Endpoint: /hello

## Purpose
Returns a greeting message.

## Interface
Inputs: None
Outputs: message: string

## Behavior
Returns a JSON object with a greeting message.

## Constraints
None

## Edge Cases
None

## Error Conditions
None

## Examples
Input: (none)
Output: {"message": "Hello, world!"}

This is a simple example, but as features get more complex, specs need to be more detailed. That's what we'll focus on next.

Dissecting the Specification Template

A complete specification has several key sections. Let's go through each one, using the User Profile feature (with avatar, bio, and location) as our running example.

1. Purpose

This section explains what the component or feature is for, in one sentence.

## Purpose
Stores and displays user profile information, including avatar, bio, and location.

Explanation:
The purpose should be clear and concise. It helps everyone understand why this feature exists.

2. Interface

Here, you list the inputs and outputs, along with their types and any constraints.

## Interface
Inputs:
- avatar_url: string (valid URL, optional)
- bio: string (max 160 characters, optional)
- location: string (max 50 characters, optional)

Outputs:
- profile: object (contains avatar_url, bio, location)

Explanation:

  • Inputs are the data the feature receives.
  • Outputs are what it returns or produces.
  • Constraints (like "max 160 characters") help prevent errors and keep data clean.
3. Behavior

Describe what happens when the feature is used, but not how it's implemented.

## Behavior
When a user updates their profile, the system saves the new avatar, bio, and location. If any field is missing, the previous value is kept.

Explanation:
Focus on what the system should do, not the code or logic behind it.

4. Constraints

List any rules that must always be true.

## Constraints
- Avatar URL must be a valid URL if provided.
- Bio must not exceed 160 characters.
- Location must not exceed 50 characters.

Explanation:
Constraints help ensure the data is always valid.

5. Edge Cases

Think about unusual or boundary situations.

## Edge Cases
- All fields are empty (profile remains unchanged).
- Bio or location at maximum length.
- Avatar URL is invalid.

Explanation:
Edge cases help you think about what could go wrong or be unexpected.

6. Error Conditions

Describe when the feature should fail and how.

## Error Conditions
- If avatar_url is not a valid URL, return an error.
- If bio or location exceeds the maximum length, return an error.

Explanation:
This section helps you plan for problems and how to handle them.

7. Examples

Provide concrete input/output pairs.

## Examples
Input:
{
  "avatar_url": "https://example.com/avatar.png",
  "bio": "Hello, I love coding!",
  "location": "San Francisco"
}
Output:
{
  "profile": {
    "avatar_url": "https://example.com/avatar.png",
    "bio": "Hello, I love coding!",
    "location": "San Francisco"
  }
}

Input:
{
  "bio": "A" * 161
}
Output:
{
  "error": "Bio must not exceed 160 characters."
}

Explanation:
Examples make the spec concrete and easy to understand. They show exactly what should happen in real situations.

Complete Specification Template

Now that you understand each section, here's the complete template you can use for any feature:

# [Feature Name]

**Version:** [X.Y.Z]

## Purpose
[One sentence describing what this feature does]

## Interface
**Inputs:**
- [input_name]: [type] ([constraints, e.g., "required", "optional", "max 50 chars"])
- ...

**Outputs:**
- [output_name]: [type] ([description])
- ...

## Behavior
[Describe what happens when the feature is used, without implementation details]

## Constraints
- [Rule that must always be true]
- ...

## Edge Cases
- [Unusual or boundary situation]
- ...

## Error Conditions
- [Condition that causes failure]: [Error response]
- ...

## Examples
**Example 1: [Description]**
Input:
```
[input data]
```
Output:
```
[output data]
```

**Example 2: [Description]**
Input:
```
[input data]
```
Output:
```
[output data]
```

For API endpoints, also include:

## HTTP Status Codes
- 200: Success (resource retrieved/updated)
- 201: Created (new resource)
- 204: No Content (successful deletion)
- 400: Bad Request (validation failed)
- 401: Unauthorized (authentication required)
- 403: Forbidden (insufficient permissions)
- 404: Not Found (resource doesn't exist)
- 422: Unprocessable Entity (business rule violation)

## Error Response Format
TaskMaster uses FastAPI's HTTPException with the `detail` field:

```json
{
  "detail": "Human-readable error message"
}
```

**Examples:**
- 404: `{"detail": "Task not found"}`
- 403: `{"detail": "Not authorized to access this task"}`
- 400: `{"detail": "Title is required"}`
- 422: `{"detail": "Cannot transition from completed to pending"}`

When to use this template:

  • When designing a new feature or component
  • When documenting an API endpoint
  • When clarifying requirements before implementation
  • When you need to communicate feature details to AI or team members

Key differences for API specs:

  • Include HTTP status codes for all possible responses
  • Provide error response examples with actual JSON structure
  • Show both success and failure cases in examples
Generating Specifications with AI

Now, let's see how you can use AI to help generate a complete specification. On CodeSignal, you can use a prompt pattern to ask the AI to create a spec for a feature.

Here's the prompt pattern:

Generate complete specification for: [feature description]

Template:
- Purpose: One sentence
- Interface: Inputs/outputs with types
- Behavior: What happens (not how)
- Constraints: Rules that must be true
- Edge Cases: Boundary conditions
- Error Conditions: When to fail
- Examples: Concrete cases

Let's try it for the User Profile feature:

Generate complete specification for: User Profile (avatar, bio, location)

Template:
- Purpose: One sentence
- Interface: Inputs/outputs with types
- Behavior: What happens (not how)
- Constraints: Rules that must be true
- Edge Cases: Boundary conditions
- Error Conditions: When to fail
- Examples: Concrete cases

Sample Output:

Purpose: Stores and updates user profile information (avatar, bio, location).
Interface: 
  Inputs: avatar_url (string, optional, valid URL), bio (string, optional, max 160 chars), location (string, optional, max 50 chars)
  Outputs: profile (object with avatar_url, bio, location)
Behavior: Updates user profile fields; keeps previous values if not provided.
Constraints: avatar_url must be a valid URL; bio ≤ 160 chars; location ≤ 50 chars.
Edge Cases: All fields empty; max length fields; invalid URL.
Error Conditions: Invalid URL; bio/location too long.
Examples: 
  Input: { "bio": "Hello!" } 
  Output: { "profile": { "bio": "Hello!" } }

Explanation:
The AI follows the template and fills in each section. You can then review and adjust the output as needed.

Reviewing Real-World Examples

Now that you understand the template, let's look at two real specifications from the TaskMaster project: specs/user-model-v1.0.md and specs/auth-api-v1.0.md. These files are in your workspace and demonstrate complete specifications for real features.

Example 1: User Model Specification

Here's the complete User Model spec:

# Model: User

**Version:** 1.0.0

## Purpose
Authenticated user with secure credential storage.

## Fields
- **id**: UUID (primary key)
- **email**: string (unique, lowercase)
- **username**: string (unique, 3-50 chars)
- **password_hash**: string (bcrypt)
- **is_active**: boolean (default true)
- **created_at**: timestamp (UTC)
- **updated_at**: timestamp (UTC)

## Behavior

### set_password(password: str)
Hash and store password using bcrypt (12 rounds).

### verify_password(password: str) -> bool
Verify password against stored hash.

## Constraints
- Email must be valid format
- Username: alphanumeric + underscore only
- Password minimum 8 characters
- Email and username case-insensitive unique

## Errors
- `ValueError`: Invalid email/username/password
- `IntegrityError`: Duplicate email/username

What Makes This Spec Good:

  • Clear purpose: One sentence explains what this model does
  • Detailed interface: All fields listed with types and constraints
  • Behavior described: Methods explained without implementation details
  • Constraints explicit: Rules like "alphanumeric + underscore only"
  • Error conditions: Specifies when errors occur

What Could Be Improved:

  • ⚠️ Missing examples showing actual usage
  • ⚠️ No edge cases listed (e.g., what happens with whitespace in email?)
Example 2: Authentication API Specification

Here's a portion of the Auth API spec (open specs/auth-api-v1.0.md to see the complete version):

# API: Authentication

**Version:** 1.0.0

## Base URL
`/api/auth`

## Endpoints

### POST /api/auth/register
Create new user account.

**Request:**
```json
{
  "email": "user@example.com",
  "username": "johndoe",
  "password": "SecurePass123"
}
```

**Response (201):**
```json
{
  "id": "uuid",
  "email": "user@example.com",
  "username": "johndoe",
  "is_active": true,
  "created_at": "2024-01-15T10:30:00Z"
}
```

---

### POST /api/auth/login
Authenticate and receive JWT token.

**Request:**
```json
{
  "email": "user@example.com",
  "password": "SecurePass123"
}
```

**Response (200):**
```json
{
  "access_token": "eyJhbGc...",
  "token_type": "Bearer",
  "expires_in": 900
}
```

## Security
- JWT tokens expire in 15 minutes
- Passwords hashed with bcrypt (cost 12)
- All endpoints except register/login require authentication

What Makes This Spec Good:

  • Concrete examples: Shows exact JSON for requests and responses
  • HTTP status codes: Indicates expected response codes (201, 200)
  • Security considerations: Lists important security details
  • Complete interface: Every endpoint is documented

What Could Be Improved:

  • ⚠️ Missing error response examples (What does 409 Conflict look like?)
  • ⚠️ No edge cases (What if password is empty string?)
  • ⚠️ Could specify error conditions more explicitly

Good specifications make implementation straightforward because there's no ambiguity. When reviewing specs, ask yourself: "Could someone implement this feature without asking me any questions?" If not, the spec needs more detail. In many cases, these specifications act as the primary API Schema for the agent during the build phase.

Summary And What's Next

In this lesson, you learned how to break down a feature into a complete specification using a clear template. You saw how each section — Purpose, Interface, Behavior, Constraints, Edge Cases, Error Conditions, and Examples — helps make your specs more useful and reliable. You also learned how to use AI to generate specs and how to review real-world examples for quality.

Next, you'll get hands-on practice: you'll use AI to generate a specification for a User Profile feature, then review and validate its completeness. This will help you build the skills to write and review specs for any feature you work on.

Sign up
Join the 1M+ learners on CodeSignal
Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal