Specification Writing Guide
crefft > Documentation > Specifications
The Spec for Specs: Engineering Documentation in the AI Era.
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in RFC 2119.
Table of Contents
- Philosophy
- Document Types
- The Modern Specification Stack
- Writing for Humans and AI
- Big Tech Patterns
- Document Formats
- Architecture Documentation
- AI-Era Documentation
- Tooling and Automation
- Anti-Patterns
- Templates
- References
Philosophy
The Documentation Paradox
Documentation has two audiences in 2025: humans who make decisions and AI agents who execute work. The best specifications serve both without compromise.
Core Principles
1. Narrative Over Bullets
“PowerPoint is a sales tool. Internally, the last thing you want to do is sell. You’re truth-seeking.” — Jeff Bezos
Full sentences force clarity of thought. Bullet points hide fuzzy thinking. Write narratively, then extract summaries for quick reference.
2. Docs as Code
Specifications MUST live alongside code in version control. They are first-class artifacts, reviewed in PRs, validated in CI, and deployed with releases.
3. Single Source of Truth
Each fact exists in exactly one place. Other documents link, never duplicate. When information changes, it changes once.
4. Write for Change
Good specs anticipate evolution. Use ADRs to capture decisions. Version specs alongside code. Make deprecation explicit.
5. AI-Native by Default
Modern specs are consumed by LLMs, AI coding assistants, and autonomous agents. Structure content for machine parsing without sacrificing human readability.
Document Types
Every engineering organization needs these document types. Each serves a distinct purpose:
| Document | Purpose | Audience | Lifespan |
|---|---|---|---|
| RFC | Propose significant changes | Team/Org | Until decided |
| Design Doc | Detail implementation approach | Engineers | Project duration |
| ADR | Record architectural decisions | Future team | Permanent |
| PRD | Define product requirements | Cross-functional | Feature lifecycle |
| PR/FAQ | Validate customer value | Leadership | Until launch |
| Technical Spec | Define system contracts | Engineers | System lifetime |
| Runbook | Operational procedures | SREs/Operators | Continuous |
When to Use Each
┌─────────────────────────────────────────────────────────────────┐
│ DECISION TREE │
├─────────────────────────────────────────────────────────────────┤
│ │
│ "I need to propose a significant change" │
│ └──▶ RFC (Request for Comments) │
│ │
│ "I need to explain how we'll build something" │
│ └──▶ Design Doc │
│ │
│ "I need to record why we chose approach X over Y" │
│ └──▶ ADR (Architecture Decision Record) │
│ │
│ "I need to define what the product should do" │
│ └──▶ PRD (Product Requirements Document) │
│ │
│ "I need to validate customer value before building" │
│ └──▶ PR/FAQ (Amazon Working Backwards) │
│ │
│ "I need to define contracts between systems" │
│ └──▶ Technical Spec / API Spec │
│ │
│ "I need to document how to operate something" │
│ └──▶ Runbook │
│ │
└─────────────────────────────────────────────────────────────────┘
The Modern Specification Stack
Tier 1: Strategic (Why)
PR/FAQ — Working Backwards from the customer
- Written before any engineering work begins
- Forces customer-centric thinking
- Kills bad ideas cheaply (words are cheaper than code)
PRD — Product Requirements
- Defines the “what” without the “how”
- Owned by Product Management
- Versioned with the project’s releases; see the Versioning Guide for library SemVer and CalVer
Tier 2: Tactical (What/How)
RFC — Request for Comments
- Proposes significant changes requiring consensus
- Time-boxed discussion period
- Results in accept/reject/modify decision
Design Doc — Implementation Blueprint
- Details the “how” for a specific project
- Living document during development
- Archived after completion
Tier 3: Operational (Record)
ADR — Architecture Decision Records
- Captures decisions and context permanently
- Never deleted, only superseded
- Enables future archaeology
Technical Specs — System Contracts
- API specifications (OpenAPI, GraphQL SDL)
- Data schemas (JSON Schema, Protobuf)
- Interface definitions
Tier 4: Execution (Do)
Runbooks — Operational Procedures
- Step-by-step incident response
- Deployment procedures
- Maintenance tasks
Writing for Humans and AI
The Dual-Audience Challenge
In 2025, your specifications will be read by:
- Engineers making implementation decisions
- Product managers understanding scope
- AI coding assistants (Cursor, Copilot, Claude Code)
- AI agents executing autonomous tasks
- RAG systems answering questions about your product
Structure for Both
MUST follow these structural patterns:
# Title (H1 - exactly one per document)
## Section (H2 - major logical divisions)
### Subsection (H3 - detailed breakdowns)
Narrative paragraphs for complex explanations. Full sentences
force complete thoughts. Each paragraph addresses one concept.
**Bold key terms** on first use. Use `code formatting` for
technical identifiers, commands, and literals.
| Tables | For | Structured | Data |
|--------|-----|------------|------|
| Row 1 | ... | ... | ... |
Semantic Chunking
AI systems chunk documents for embedding and retrieval. MUST structure for clean chunking:
## Feature: User Authentication ← Clear topic boundary
### Overview ← Standalone summary
Brief description that makes sense in isolation.
### Requirements ← Distinct chunk
1. Requirement with full context
2. Self-contained requirement
### Implementation Notes ← Separate concern
Technical details grouped together.
Anti-pattern:
## Feature
See above for context... ← Lost when chunked
As mentioned in the introduction... ← Broken reference
Machine-Readable Frontmatter
Every specification SHOULD include YAML frontmatter:
---
title: "User Authentication System"
type: design-doc # rfc | adr | design-doc | prd | spec
status: approved # draft | review | approved | superseded
authors:
- name: Jane Smith
email: jane@example.com
created: 2025-01-15
updated: 2025-03-20
supersedes: ADR-0042
related:
- RFC-0089
- ADR-0051
tags:
- authentication
- security
- api
---
Big Tech Patterns
Google: Design Docs
Google’s design doc culture emphasizes informal but rigorous documentation1.
Structure:
- Context and Scope — Problem definition and boundaries
- Goals and Non-Goals — Explicit inclusions/exclusions
- Design — The proposed solution
- Alternatives Considered — Options evaluated and rejected
- Cross-cutting Concerns — Security, privacy, scalability
Key Practice: Design docs are created in collaborative editors (Google Docs), not wikis. Comments and suggestions are inline, fostering discussion.
Duration: Days to weeks of iteration before coding begins.
Amazon: 6-Pagers and PR/FAQ
Amazon banned PowerPoint in favor of narrative documents2.
6-Pager Structure:
- 2 pages: General background
- 2 pages: Specific background
- 2 pages: Action and plan
PR/FAQ Structure:
- Press Release (< 1 page): Customer announcement
- FAQ (< 5 pages): Internal and external questions
Key Practice: Meetings begin with 20-30 minutes of silent reading. Discussion follows shared understanding.
Philosophy: “The fact that most PR/FAQs don’t get approved is a feature, not a bug.”
Stripe: Writing Culture
Stripe elevates writing to a core engineering skill3.
Key Practices:
- Sample docs (not templates) provide context, not fill-in-the-blanks
- Engineers review writing like they review code
- Documentation included in engineering career ladder
- API review is a formal, rigorous process
Philosophy: “Sharing ideas through writing eliminates the need for repetitive verbal updates.”
Meta: Move Fast with Docs
Meta combines high velocity with documentation discipline4.
Key Practices:
- Internal Phabricator for code review includes doc review
- Workplace serves as wiki + communication + social
- Strong emphasis on ADRs for knowledge preservation across team changes
Microsoft: Well-Architected Framework
Microsoft formalizes documentation into frameworks5.
Key Artifacts:
- Functional Specification: What and why (not how)
- Technical Specification: How (for engineering)
- Architecture Design Specification: Decisions and diagrams
Document Formats
RFC Format
---
type: rfc
rfc: "RFC-0123"
title: "Implement Event Sourcing for Order Service"
status: draft
authors: ["Jane Smith <jane@example.com>"]
created: 2025-01-15
---
# RFC-0123: Implement Event Sourcing for Order Service
## Summary
One paragraph explaining the proposal at a high level.
## Motivation
Why are we doing this? What problems does it solve?
What is the expected outcome?
## Detailed Design
Technical details of the proposal. Include:
- Architecture diagrams
- API changes
- Data model changes
- Migration strategy
## Alternatives Considered
### Alternative A: Continue with CRUD
Rejected because...
### Alternative B: Use Kafka Streams
Rejected because...
## Risks and Mitigations
| Risk | Impact | Likelihood | Mitigation |
|------|--------|------------|------------|
| Data migration failure | High | Medium | Rollback plan |
## Open Questions
- [ ] How will we handle schema evolution?
- [ ] What is the retention policy?
## References
- [Event Sourcing Pattern](https://martinfowler.com/eaaDev/EventSourcing.html)
ADR Format
Based on Michael Nygard’s format6:
---
type: adr
adr: "ADR-0042"
title: "Use PostgreSQL for Primary Database"
status: accepted
date: 2025-01-15
deciders: ["Jane Smith", "John Doe"]
---
# ADR-0042: Use PostgreSQL for Primary Database
## Status
Accepted
## Context
We need to choose a primary database for the new order service.
The system must handle 10,000 transactions per second with
ACID guarantees. We have existing PostgreSQL expertise.
## Decision
We will use PostgreSQL 16 as the primary database.
## Consequences
### Positive
- Leverages existing team expertise
- Strong ACID compliance
- Excellent tooling ecosystem
### Negative
- Horizontal scaling requires additional architecture
- License considerations for enterprise features
### Neutral
- Requires infrastructure provisioning
## Alternatives Considered
### MySQL 8
Rejected: Weaker JSON support, team has less experience.
### MongoDB
Rejected: ACID requirements favor relational model.
Design Doc Format
This template nests text, typescript, and sql blocks, so its outer fence
uses four backticks. A three-backtick outer fence ends at the first nested
block and the rest of the template renders as page content.
---
type: design-doc
title: "Payment Processing Redesign"
status: approved
authors: ["Jane Smith"]
reviewers: ["John Doe", "Alice Johnson"]
created: 2025-01-15
approved: 2025-01-22
---
# Payment Processing Redesign
## Overview
One paragraph summary for executives and future readers.
## Context and Scope
### Background
What led to this design? What's the current state?
### Goals
- **G1:** Process payments in < 100ms p99
- **G2:** Support 3 new payment providers
### Non-Goals
- **NG1:** Mobile app changes (separate project)
- **NG2:** Cryptocurrency support
## Design
### System Architecture
```text
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ Client │────▶│ API Gateway │────▶│ Payment │
└─────────────┘ └──────────────┘ │ Service │
└──────┬──────┘
│
┌───────────────────────────┼───────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Stripe │ │ PayPal │ │ Square │
└──────────┘ └──────────┘ └──────────┘
```
### API Changes
```typescript
// New endpoint
POST /v2/payments
{
"amount": 1000,
"currency": "USD",
"provider": "stripe",
"idempotency_key": "uuid-v4"
}
```
### Data Model
```sql
CREATE TABLE payments (
id UUID PRIMARY KEY,
amount BIGINT NOT NULL,
currency VARCHAR(3) NOT NULL,
provider VARCHAR(50) NOT NULL,
status payment_status NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW()
);
```
## Alternatives Considered
### Option A: Extend Existing System
Rejected because...
### Option B: Third-Party Orchestration
Rejected because...
## Security Considerations
- PCI DSS compliance requirements
- Token storage strategy
- Audit logging
## Testing Strategy
- Unit tests for business logic
- Integration tests with provider sandboxes
- Load testing for p99 targets
## Rollout Plan
1. **Week 1:** Deploy to staging
2. **Week 2:** Canary (1% traffic)
3. **Week 3:** Gradual rollout (10% → 50% → 100%)
## Open Questions
- [ ] Retry strategy for failed webhooks?
PR/FAQ Format (Amazon Working Backwards)
---
type: prfaq
title: "Automated Deployment Pipeline"
status: draft
author: "Jane Smith"
created: 2025-01-15
---
# Automated Deployment Pipeline
## Press Release
**FOR IMMEDIATE RELEASE**
**ACME Corp Launches Zero-Touch Deployment Pipeline**
*Engineers deploy to production in minutes, not days*
SEATTLE — January 15, 2025 — ACME Corp today announced the launch
of its new Automated Deployment Pipeline, enabling engineering
teams to deploy code changes to production in under 10 minutes
with zero manual intervention.
"Our engineers were spending 40% of their time on deployment
coordination," said Jane Smith, VP of Engineering. "Now they
spend that time building features customers love."
The new pipeline includes automated testing, security scanning,
canary deployments, and one-click rollback. Early adopters
report a 75% reduction in deployment-related incidents.
To learn more, visit docs.acme.com/deployments.
## Frequently Asked Questions
### External FAQ
**Q: How long does a deployment take?**
A: From merge to production, typically 8-12 minutes including
all automated checks.
**Q: What if something goes wrong?**
A: One-click rollback returns to the previous version in under
60 seconds. Automatic rollback triggers on error rate spikes.
### Internal FAQ
**Q: What's the estimated development cost?**
A: 3 engineers for 6 months, approximately $600K fully loaded.
**Q: What are the main technical risks?**
A: Integration with legacy deployment systems. Mitigation:
parallel operation for 3 months.
**Q: Why now?**
A: Deployment incidents increased 40% YoY. Current manual
process doesn't scale with team growth.
**Q: What won't this solve?**
A: Database migrations remain manual. Test flakiness is
a separate initiative.
Architecture Documentation
C4 Model
The C4 Model provides four levels of abstraction7:
Level 1: System Context — How system fits in the world
Level 2: Container — High-level technology choices
Level 3: Component — Components within containers
Level 4: Code — Implementation details (optional)
SHOULD include at minimum Levels 1 and 2 for every system.
Diagrams as Code
MUST use text-based diagramming for version control:
Mermaid (GitHub/GitLab native):
graph TD
A[Client] --> B[API Gateway]
B --> C[Auth Service]
B --> D[Order Service]
D --> E[(PostgreSQL)]
PlantUML (more expressive):
@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml
Person(user, "User", "A customer")
System_Boundary(system, "E-Commerce") {
Container(web, "Web App", "React", "Customer UI")
Container(api, "API", "FastAPI", "Business logic")
ContainerDb(db, "Database", "PostgreSQL", "Stores orders")
}
Rel(user, web, "Uses", "HTTPS")
Rel(web, api, "Calls", "JSON/HTTPS")
Rel(api, db, "Reads/Writes", "SQL")
@enduml
arc42 Template
For comprehensive architecture documentation, SHOULD follow arc428:
- Introduction and Goals
- Constraints
- Context and Scope
- Solution Strategy
- Building Block View
- Runtime View
- Deployment View
- Crosscutting Concepts
- Architectural Decisions
- Quality Requirements
- Risks and Technical Debt
- Glossary
AI-Era Documentation
llms.txt
The llms.txt standard enables LLMs to efficiently consume documentation9.
SHOULD provide /llms.txt at documentation root:
# ACME Platform
> Enterprise platform for widget management
## Docs
- [Getting Started](https://docs.acme.com/getting-started.md): Quick start guide
- [API Reference](https://docs.acme.com/api/): Complete API documentation
- [Authentication](https://docs.acme.com/auth.md): OAuth 2.0 integration
## Optional
- [Examples](https://docs.acme.com/examples/): Code samples
- [Changelog](https://docs.acme.com/changelog.md): Version history
SHOULD also provide /llms-full.txt with complete documentation concatenated.
Model Context Protocol (MCP)
MCP enables AI agents to retrieve structured context10. Teams SHOULD serve documentation through an MCP server so agents read current content instead of relying on training data.
MCP revisions are dates, not SemVer versions; the current revision is
2026-07-28. Every request declares its revision in params._meta under
io.modelcontextprotocol/protocolVersion, and the server accepts or rejects
each request independently — a server that does not support the requested
revision returns UnsupportedProtocolVersionError (-32022) listing the
revisions it does support. Documentation MUST state the revision its
examples target: negotiation happens per request, so an example that omits the
revision cannot be copied into a client without guessing, and a wrong guess
returns a protocol error instead of a resource list.
Messages are JSON-RPC 2.0. Listing documentation resources is a
resources/list request:
{
"jsonrpc": "2.0",
"id": 1,
"method": "resources/list",
"params": {
"_meta": {
"io.modelcontextprotocol/protocolVersion": "2026-07-28",
"io.modelcontextprotocol/clientInfo": {
"name": "acme-docs-agent",
"version": "1.0.0"
},
"io.modelcontextprotocol/clientCapabilities": {}
}
}
}
io.modelcontextprotocol/protocolVersion and
io.modelcontextprotocol/clientCapabilities are REQUIRED on every request;
omitting either is a malformed request that the server MUST reject with
JSON-RPC -32602. io.modelcontextprotocol/clientInfo is optional, and
clients SHOULD send it for logging and debugging.
The result carries resultType and the resource list. Only uri and name
are required per resource; mimeType is optional but SHOULD be set so
agents know how to parse each document. The caching hints ttlMs and
cacheScope are REQUIRED on this result; use public only for
documentation that is identical for every caller:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"resultType": "complete",
"resources": [
{
"uri": "https://docs.acme.com/api/users.md",
"name": "users-api",
"title": "Users API Reference",
"description": "REST endpoints for user management",
"mimeType": "text/markdown"
}
],
"ttlMs": 300000,
"cacheScope": "public"
}
}
Structured for Retrieval
MUST optimize for RAG (Retrieval-Augmented Generation):
- Self-contained sections — Each H2 makes sense in isolation
- Explicit definitions — Define terms where used
- Consistent formatting — Predictable patterns aid parsing
- Code in fenced blocks — Always specify language
- Tables for structured data — Easier to parse than prose
AI-Assisted Writing
LLMs can assist documentation workflows11:
| Task | AI Contribution | Human Review |
|---|---|---|
| First drafts | Generate from specs | Required |
| Changelog entries | Generate from commits | Required |
| API docs | Generate from OpenAPI | Required |
| Translation | Translate content | Required |
| Proofreading | Grammar, clarity | Recommended |
MUST NOT publish AI-generated content without human review.
Tooling and Automation
Docs as Code Pipeline
# .github/workflows/docs.yml
name: Documentation
on:
push:
paths: ['docs/**', '*.md']
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
# Install the pinned documentation toolchain
- run: npm ci
# Lint markdown
- run: npx markdownlint-cli2@0.23.2 "**/*.md"
# Check links
- run: npx markdown-link-check@3.15.0 docs/**/*.md
# Validate frontmatter against the checked-in schema
- run: node scripts/check-frontmatter.mjs
# Render diagrams: one input path and one output path per invocation
- run: |
git ls-files -z -- '*.md' | while IFS= read -r -d '' file; do
grep -q '^```mermaid' "$file" || continue
mkdir -p "build/$(dirname "$file")"
node_modules/.bin/mmdc -i "$file" -o "build/$file"
done
# Validate the site build (Mintlify projects)
- run: node_modules/.bin/mint validate
The tools invoked from node_modules/.bin come from a committed manifest and
lockfile, installed by npm ci:
{
"devDependencies": {
"@mermaid-js/mermaid-cli": "11.17.0",
"ajv": "8.20.0",
"mint": "4.2.876",
"yaml": "2.9.0"
}
}
Frontmatter Validation
No maintained CLI validates Markdown frontmatter against JSON Schema, so the contract lives in the repository as a schema file and CI applies it. Teams MUST keep the schema in version control rather than inlining rules in a workflow step, so editors, pre-commit hooks, and CI enforce one definition.
docs/frontmatter.schema.json encodes the contract from
Machine-Readable Frontmatter:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://docs.acme.com/schemas/frontmatter.json",
"type": "object",
"additionalProperties": false,
"required": ["title", "type", "status", "authors", "created"],
"properties": {
"title": { "type": "string", "minLength": 1 },
"type": { "enum": ["rfc", "adr", "design-doc", "prd", "spec"] },
"status": { "enum": ["draft", "review", "approved", "superseded"] },
"authors": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"additionalProperties": false,
"required": ["name"],
"properties": {
"name": { "type": "string" },
"email": { "type": "string" }
}
}
},
"created": { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$" },
"updated": { "type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$" },
"supersedes": { "type": "string" },
"related": { "type": "array", "items": { "type": "string" } },
"tags": { "type": "array", "items": { "type": "string" } }
}
}
scripts/check-frontmatter.mjs reports every violation and exits non-zero:
import { execFileSync } from 'node:child_process';
import { readFileSync } from 'node:fs';
import Ajv2020 from 'ajv/dist/2020.js';
import { parse } from 'yaml';
const schema = JSON.parse(readFileSync('docs/frontmatter.schema.json', 'utf8'));
const validate = new Ajv2020({ allErrors: true }).compile(schema);
const files = execFileSync('git', ['ls-files', '-z', '--', 'docs/*.md'], {
encoding: 'utf8',
}).split('\0').filter(Boolean);
let failures = 0;
for (const file of files) {
const matched = /^---\r?\n([\s\S]*?)\r?\n---/.exec(readFileSync(file, 'utf8'));
if (!matched) {
console.error(`${file}: missing YAML frontmatter`);
failures += 1;
} else if (!validate(parse(matched[1]))) {
for (const error of validate.errors) {
console.error(`${file}: ${error.instancePath || '/'} ${error.message}`);
}
failures += 1;
}
}
process.exit(failures === 0 ? 0 : 1);
The yaml parser follows the YAML 1.2 core schema, so created: 2025-01-15
stays a string and the schema’s date pattern applies. Parsers that coerce
timestamps to date objects MUST NOT be used here, because the coerced value
no longer matches a string constraint.
Diagram Rendering
mmdc takes exactly one input path through -i and one output path through
-o. It rejects positional file arguments with error: too many arguments,
and it aborts when the output directory does not exist, so the step creates the
directory before each invocation. Rendering into build/ keeps generated SVGs
out of the source tree; sites that render Mermaid at build time SHOULD drop
this step entirely.
Site Validation
mint validate builds the site in strict mode and exits non-zero on any
warning or error. It does not publish: Mintlify deploys from the connected Git
repository, and mint export writes an offline archive. There is no
mintlify build command, and the step applies only to Mintlify projects.
Recommended Tools
| Category | Tool | Purpose |
|---|---|---|
| Linting | markdownlint | Markdown style |
| Links | markdown-link-check | Broken link detection |
| Diagrams | Mermaid, PlantUML | Diagrams as code |
| Site | Mintlify, Docusaurus | Documentation sites |
| API Docs | OpenAPI, AsyncAPI | API specifications |
| ADRs | adr-tools | ADR management |
| Search | Algolia DocSearch | Documentation search |
ADR Tooling
Install adr-tools12:
# macOS
brew install adr-tools
# Create new ADR
adr new "Use PostgreSQL for primary database"
# Supersede existing ADR
adr new -s 42 "Switch to CockroachDB"
Anti-Patterns
1. The Dead Doc
Problem: Documentation written once, never updated.
Solution:
- Link docs to code in CI (fail if out of sync)
- Review docs in PRs that change related code
- Add expiration dates or review reminders
2. The Wiki Wasteland
Problem: Documentation scattered across wikis, losing version history.
Solution:
- Docs live in code repositories
- Single source of truth per topic
- Wiki only for ephemeral/operational content
3. The Template Trap
Problem: Empty templates filled with placeholder text.
Solution:
- Use sample docs, not blank templates
- Delete sections that don’t apply
- Require narrative over checkboxes
4. The Specification Novel
Problem: 50-page specs no one reads.
Solution:
- Executive summary in first paragraph
- Link to details, don’t inline everything
- Time-box reading: if it takes > 30 minutes, split it
5. The Orphaned Decision
Problem: Decisions made in Slack, lost forever.
Solution:
- Formal ADR process for architectural decisions
- Bot to prompt “Should this be an ADR?”
- Quarterly ADR audits
6. The Human-Only Doc
Problem: Documentation AI assistants can’t parse.
Solution:
- Structured frontmatter
- Consistent heading hierarchy
- Self-contained sections
- Machine-readable formats (OpenAPI, JSON Schema)
Templates
Quick Reference
Copy the appropriate template and customize:
| Template | Path | Use Case |
|---|---|---|
| RFC | templates/rfc.md | Proposing changes |
| ADR | templates/adr.md | Recording decisions |
| Design Doc | templates/design-doc.md | Implementation planning |
| PR/FAQ | templates/prfaq.md | Customer validation |
Minimal Spec (Quick Start)
For smaller changes, use this minimal format:
---
title: "Feature Name"
type: spec
status: draft
author: "Your Name"
date: 2025-01-15
---
# Feature Name
## Summary
One paragraph: what, why, and for whom.
## Requirements
1. **Functional:** What it must do
2. **Non-functional:** Performance, security constraints
## Design
How it works. Include diagrams if helpful.
## Risks
What could go wrong and how we mitigate.
## Questions
- [ ] Open questions to resolve
Success Metrics
Documentation Quality (DORA)
The 2024 DORA Report confirms documentation directly impacts team performance13:
| Metric | Poor Docs | Good Docs | Impact |
|---|---|---|---|
| Onboarding time | Weeks | Days | 3x faster |
| Deployment frequency | Monthly | Daily | 30x |
| Change failure rate | 45% | 15% | 3x better |
| Developer satisfaction | Low | High | Retention |
Leading Indicators
- Coverage: % of services with up-to-date specs
- Freshness: Days since last update
- Usage: Page views, search queries
- AI Compatibility: llms.txt present, MCP integration
Summary
Modern specifications serve dual audiences—humans and AI—without compromise. They live as code, evolve with products, and encode organizational knowledge that outlasts any individual.
Key Takeaways:
- Write narratively — Full sentences force complete thoughts
- Structure for both — Humans scan, AI chunks
- Version everything — Docs in git, reviewed in PRs
- Capture decisions — ADRs create institutional memory
- Validate before building — PR/FAQ kills bad ideas cheaply
- Automate quality — Lint, link-check, validate in CI
- Optimize for AI — llms.txt, MCP, structured content
References
See Also
- Markdown Guide — Markdown formatting standards
- AGENTS.md Patterns — AI assistant context files
- GitHub Templates — Issue and PR templates
- CI/CD Guide — Automation pipelines