arial
GitHub

Spec File Format

Complete reference for Arial spec files.


Overview

A spec is a markdown file that describes a unit of work for Arial to execute. Each spec file becomes one workstream.


File Location

Specs are stored in a directory you specify:

specs/
├── auth.md      → workstream "auth"
├── api.md       → workstream "api"
└── tests.md     → workstream "tests"

The filename (without .md) becomes the workstream ID.


Basic Structure

A spec should include a title and enough context for an AI agent to complete the work:

# Title

## Goal
What you want to achieve.

## Requirements
- Specific requirement 1
- Specific requirement 2

## Technical Notes
- Constraints or preferences
- Libraries to use
- Patterns to follow

Required Elements

ElementPurpose
`# Title`First H1 heading becomes the workstream title
Goal/contextEnough information for the agent to understand the task

Optional Elements

ElementPurpose
`## Goal`High-level objective
`## Requirements`Specific, verifiable deliverables
`## Technical Notes`Implementation constraints, libraries, patterns
`## Context`Background information, related code
`## Examples`Sample inputs/outputs, API shapes

Spec Examples

Feature Implementation

# Add User Authentication

## Goal
Implement JWT-based authentication for the API.

## Requirements
- POST /auth/register - Create new user account
- POST /auth/login - Authenticate and return JWT token
- Auth middleware to protect routes
- Password hashing with bcrypt

## Technical Notes
- Use jsonwebtoken package
- Token expiry: 24 hours
- Follow existing error handling patterns in src/middleware/

Bug Fix

# Fix Login Rate Limiting

## Goal
Users are being rate limited too aggressively on login attempts.

## Context
Current implementation in src/middleware/rateLimit.ts applies a global limit.
Need per-IP limiting instead.

## Requirements
- Change rate limiter to per-IP tracking
- Allow 5 attempts per minute per IP
- Add proper 429 response with Retry-After header

## Technical Notes
- Use existing Redis connection for state
- Add tests for rate limiting behavior

Refactoring

# Extract Payment Processing Module

## Goal
Payment logic is scattered across multiple files. Consolidate into a single module.

## Files to Refactor
- src/controllers/checkout.ts (lines 45-120)
- src/controllers/subscription.ts (lines 80-150)
- src/utils/stripe.ts (all)

## Requirements
- Create src/modules/payments/
- Move all Stripe interactions to new module
- Maintain existing API contracts
- Update imports across codebase

## Technical Notes
- Keep backward compatibility during transition
- Add index.ts for clean public API

Writing Effective Specs

Be Specific

Vague specs lead to unexpected results:

# Bad: Too vague
Add authentication to the app.

# Good: Specific
Implement JWT-based authentication with:
- Registration endpoint accepting email/password
- Login endpoint returning access token
- Token validation middleware

Include Context

Reference existing patterns and files:

## Technical Notes
- Follow the controller pattern in src/controllers/users.ts
- Use the existing validation helpers from src/utils/validate.ts
- Match error response format from src/middleware/errorHandler.ts

List Verifiable Requirements

Make requirements concrete and testable:

## Requirements
- POST /auth/register returns 201 with user object
- POST /auth/register returns 400 for duplicate email
- POST /auth/login returns 200 with JWT token
- Protected routes return 401 without valid token

One Concern Per Spec

Keep specs focused on a single area:

# Good: Focused
specs/
├── auth.md         → authentication logic
├── user-api.md     → user CRUD endpoints
└── user-tests.md   → tests for user features

# Bad: Mixed concerns
specs/
└── users.md        → auth + API + tests (too broad)

Spec Independence

Since workstreams run in parallel, specs should be independent:

Avoid File Conflicts

If two specs modify the same files, you may get merge conflicts:

# Risky: Both touch src/routes/index.ts
specs/
├── auth-routes.md   → adds /auth routes
└── user-routes.md   → adds /user routes

# Better: Self-contained
specs/
├── auth.md          → adds src/routes/auth.ts
└── users.md         → adds src/routes/users.ts

Avoid Logical Dependencies

Don't assume one spec completes before another:

# Risky: tests.md depends on auth.md completing first
specs/
├── auth.md          → implements auth
└── tests.md         → tests auth (but auth might not exist yet)

# Better: Each spec is self-contained
specs/
├── auth.md          → implements auth with its own tests
└── api.md           → implements API with its own tests

Workstream ID Rules

The workstream ID is derived from the filename:

FilenameWorkstream ID
`auth.md``auth`
`user-api.md``user-api`
`Add_Feature.md``Add_Feature`

IDs are used in:

  • Branch names: arial/auth-abc123
  • Worktree paths: .arial/worktrees/auth/
  • Status output and logs

Title Extraction

The workstream title comes from the first H1 heading:

# Add User Authentication    ← This becomes the title

## Goal
...

If no H1 is found, the filename is used as the title.