agents/openai.yaml
interface:
display_name: "Technical Documentation"
short_description: "Writes and reorganizes docs-as-code for software repos"
default_prompt: "Use $docs-codebase for Writes and reorganizes docs-as-code for software repos. Use when updating READMEs, runbooks, onboarding docs, API references, or agent instruction files."
assets/api-reference/api-docs-template.md
# API Documentation
Base URL: `https://api.example.com/v1`
Version: 1.0.0
Last Updated: 2025-01-15
## Table of Contents
- [Authentication](#authentication)
- [Rate Limiting](#rate-limiting)
- [Error Handling](#error-handling)
- [Pagination](#pagination)
- [Endpoints](#endpoints)
- [Users](#users)
- [Posts](#posts)
- [Comments](#comments)
## Authentication
All API requests require authentication via Bearer token.
### Obtaining an Access Token
```http
POST /api/v1/auth/login
Content-Type: application/json
{
"email": "user@example.com",
"password": "securepassword123"
}
```
**Response:**
```json
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "dGhpcyBpcyBhIHJlZnJlc2ggdG9rZW4..."
}
```
### Using the Access Token
Include the token in the `Authorization` header:
```http
GET /api/v1/users
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
```
### Token Expiration
- Access tokens expire after 1 hour
- Use the refresh token to obtain a new access token without re-authenticating
```http
POST /api/v1/auth/refresh
Content-Type: application/json
{
"refresh_token": "dGhpcyBpcyBhIHJlZnJlc2ggdG9rZW4..."
}
```
## Rate Limiting
API requests are rate-limited to prevent abuse.
**Limits:**
- Authenticated users: 1000 requests per hour
- Unauthenticated requests: 100 requests per hour
**Headers:**
```http
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 995
X-RateLimit-Reset: 1642521600
```
**Rate Limit Exceeded Response:**
```http
HTTP/1.1 429 Too Many Requests
Content-Type: application/json
{
"type": "https://api.example.com/errors/rate-limit-exceeded",
"title": "Rate limit exceeded",
"status": 429,
"detail": "Rate limit exceeded. Please try again later.",
"instance": "/api/v1/users",
"retry_after": 3600
}
```
## Error Handling
The API uses standard HTTP status codes and returns errors in RFC 9457 Problem Details format.
### Error Response Format
```json
{
"type": "https://api.example.com/errors/validation-error",
"title": "Validation Error",
"status": 422,
"detail": "The request body contains invalid data",
"instance": "/api/v1/users",
"errors": [
{
"field": "email",
"code": "INVALID_FORMAT",
"message": "Email address is not valid"
},
{
"field": "age",
"code": "OUT_OF_RANGE",
"message": "Age must be between 18 and 120"
}
]
}
```
### Status Codes
| Code | Meaning | Description |
|------|---------|-------------|
| 200 | OK | Request succeeded |
| 201 | Created | Resource created successfully |
| 204 | No Content | Request succeeded, no response body |
| 400 | Bad Request | Invalid request format |
| 401 | Unauthorized | Missing or invalid authentication |
| 403 | Forbidden | Authenticated but not authorized |
| 404 | Not Found | Resource does not exist |
| 422 | Unprocessable Entity | Validation error |
| 429 | Too Many Requests | Rate limit exceeded |
| 500 | Internal Server Error | Server error |
| 503 | Service Unavailable | Temporary unavailability |
## Pagination
List endpoints support cursor-based pagination.
### Request
```http
GET /api/v1/users?limit=20&cursor=eyJpZCI6MTIzfQ
```
**Query Parameters:**
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `limit` | integer | No | Number of items (1-100, default: 20) |
| `cursor` | string | No | Pagination cursor from previous response |
### Response
```json
{
"data": [
{ "id": 1, "name": "John Doe", ... },
{ "id": 2, "name": "Jane Smith", ... }
],
"pagination": {
"next_cursor": "eyJpZCI6MjB9",
"has_more": true,
"total": 150
}
}
```
## Endpoints
---
## Users
### List Users
Retrieve a paginated list of users.
```http
GET /api/v1/users
```
**Query Parameters:**
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `limit` | integer | No | Number of items (default: 20, max: 100) |
| `cursor` | string | No | Pagination cursor |
| `sort` | string | No | Sort field (`name`, `-created_at`) |
| `status` | string | No | Filter by status (`active`, `inactive`) |
| `search` | string | No | Search by name or email |
**Example Request:**
```bash
curl -X GET "https://api.example.com/v1/users?limit=10&sort=-created_at&status=active" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```
**Response:**
```http
HTTP/1.1 200 OK
Content-Type: application/json
{
"data": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "john.doe@example.com",
"name": "John Doe",
"avatar_url": "https://cdn.example.com/avatars/john.jpg",
"status": "active",
"created_at": "2025-01-15T10:30:00Z",
"updated_at": "2025-01-15T10:30:00Z"
}
],
"pagination": {
"next_cursor": "eyJpZCI6MTB9",
"has_more": true,
"total": 150
}
}
```
---
### Get User by ID
Retrieve a specific user by ID.
```http
GET /api/v1/users/:id
```
**Path Parameters:**
| Parameter | Type | Description |
|-----------|------|-------------|
| `id` | UUID | User ID |
**Example Request:**
```bash
curl -X GET "https://api.example.com/v1/users/550e8400-e29b-41d4-a716-446655440000" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```
**Response:**
```http
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "john.doe@example.com",
"name": "John Doe",
"bio": "Software engineer and open source enthusiast",
"avatar_url": "https://cdn.example.com/avatars/john.jpg",
"location": "San Francisco, CA",
"website": "https://johndoe.com",
"status": "active",
"created_at": "2025-01-15T10:30:00Z",
"updated_at": "2025-01-15T10:30:00Z"
}
```
**Error Responses:**
```http
HTTP/1.1 404 Not Found
Content-Type: application/json
{
"type": "https://api.example.com/errors/user-not-found",
"title": "User not found",
"status": 404,
"detail": "User with ID 550e8400-e29b-41d4-a716-446655440000 not found",
"instance": "/api/v1/users/550e8400-e29b-41d4-a716-446655440000"
}
```
---
### Create User
Create a new user.
```http
POST /api/v1/users
```
**Request Body:**
```json
{
"email": "newuser@example.com",
"name": "New User",
"password": "SecurePassword123!",
"bio": "Optional bio text",
"location": "New York, NY"
}
```
**Required Fields:**
| Field | Type | Constraints |
|-------|------|-------------|
| `email` | string | Valid email address, unique |
| `name` | string | 1-100 characters |
| `password` | string | Minimum 8 characters, must include uppercase, lowercase, number, special char |
**Optional Fields:**
| Field | Type | Constraints |
|-------|------|-------------|
| `bio` | string | Maximum 500 characters |
| `location` | string | Maximum 100 characters |
| `website` | string | Valid URL |
**Example Request:**
```bash
curl -X POST "https://api.example.com/v1/users" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"email": "newuser@example.com",
"name": "New User",
"password": "SecurePassword123!"
}'
```
**Response:**
```http
HTTP/1.1 201 Created
Content-Type: application/json
Location: /api/v1/users/660e8400-e29b-41d4-a716-446655440000
{
"id": "660e8400-e29b-41d4-a716-446655440000",
"email": "newuser@example.com",
"name": "New User",
"status": "active",
"created_at": "2025-01-20T14:30:00Z",
"updated_at": "2025-01-20T14:30:00Z"
}
```
**Error Responses:**
```http
HTTP/1.1 422 Unprocessable Entity
Content-Type: application/json
{
"type": "https://api.example.com/errors/validation-error",
"title": "Validation Error",
"status": 422,
"errors": [
{
"field": "email",
"code": "DUPLICATE_EMAIL",
"message": "Email address is already registered"
},
{
"field": "password",
"code": "WEAK_PASSWORD",
"message": "Password must include at least one uppercase letter"
}
]
}
```
---
### Update User
Update an existing user.
```http
PUT /api/v1/users/:id
```
**Path Parameters:**
| Parameter | Type | Description |
|-----------|------|-------------|
| `id` | UUID | User ID |
**Request Body:**
```json
{
"name": "Updated Name",
"bio": "Updated bio text",
"location": "Los Angeles, CA",
"website": "https://updated-website.com"
}
```
All fields are optional. Only provided fields will be updated.
**Example Request:**
```bash
curl -X PUT "https://api.example.com/v1/users/550e8400-e29b-41d4-a716-446655440000" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "John D.",
"bio": "Updated bio"
}'
```
**Response:**
```http
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"email": "john.doe@example.com",
"name": "John D.",
"bio": "Updated bio",
"status": "active",
"updated_at": "2025-01-20T15:00:00Z"
}
```
---
### Delete User
Delete a user permanently.
```http
DELETE /api/v1/users/:id
```
**Path Parameters:**
| Parameter | Type | Description |
|-----------|------|-------------|
| `id` | UUID | User ID |
**Example Request:**
```bash
curl -X DELETE "https://api.example.com/v1/users/550e8400-e29b-41d4-a716-446655440000" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
```
**Response:**
```http
HTTP/1.1 204 No Content
```
**Error Responses:**
```http
HTTP/1.1 403 Forbidden
Content-Type: application/json
{
"type": "https://api.example.com/errors/forbidden",
"title": "Forbidden",
"status": 403,
"detail": "You do not have permission to delete this user",
"instance": "/api/v1/users/550e8400-e29b-41d4-a716-446655440000"
}
```
---
## Webhooks
Subscribe to events via webhooks.
### Webhook Events
| Event | Description |
|-------|-------------|
| `user.created` | New user registered |
| `user.updated` | User profile updated |
| `user.deleted` | User deleted |
| `post.created` | New post published |
### Webhook Payload
```json
{
"event": "user.created",
"timestamp": "2025-01-20T14:30:00Z",
"data": {
"id": "660e8400-e29b-41d4-a716-446655440000",
"email": "newuser@example.com",
"name": "New User"
}
}
```
### Webhook Signature
All webhook requests include an `X-Signature` header with HMAC-SHA256 signature.
**Verify signature:**
```javascript
const crypto = require('crypto');
function verifyWebhook(payload, signature, secret) {
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature)
);
}
```
---
## SDKs and Libraries
Official SDKs are available for:
- [JavaScript/TypeScript](https://github.com/example/sdk-js)
- [Python](https://github.com/example/sdk-python)
- [Go](https://github.com/example/sdk-go)
- [Ruby](https://github.com/example/sdk-ruby)
---
## Support
- Documentation: https://docs.example.com
- API Status: https://status.example.com
- Support Email: api-support@example.com
- Discord: https://discord.gg/example-api
---
## Changelog
See [API Changelog](https://docs.example.com/changelog) for version history and breaking changes.
assets/architecture/adr-template.md
# ADR-XXX: [Short Title of Decision]
## Status
[Proposed | Accepted | Rejected | Deprecated | Superseded by ADR-YYY]
## Context
What is the issue that we're seeing that is motivating this decision or change?
- What is the background context?
- What problem are we trying to solve?
- What are the business/technical constraints?
- What are the forces at play (technical, political, social, project)?
Example:
> We need to choose a database for our new microservice that will handle high-volume user profile data. The service must support:
> - 10,000+ writes/second
> - Complex queries with joins
> - ACID transactions
> - Horizontal scaling
> - Sub-100ms read latency
## Decision
We will [decision statement].
Be specific and actionable. State the architecture decision you've made clearly.
Example:
> We will use PostgreSQL 15 with read replicas as the primary database for the user profile service.
## Consequences
### Positive
What becomes easier or better after this decision?
- Benefit 1 with explanation
- Benefit 2 with explanation
- Benefit 3 with explanation
Example:
> - Full ACID compliance ensures data integrity for financial transactions
> - Rich ecosystem of tools (pgAdmin, PostgREST, Hasura)
> - Excellent JSON support via jsonb type for flexible schemas
> - Battle-tested at scale (Instagram, Spotify, Reddit)
> - Strong community support and extensive documentation
### Negative
What becomes more difficult or worse? What tradeoffs are we accepting?
- Drawback 1 with explanation
- Drawback 2 with explanation
- Drawback 3 with explanation
Example:
> - Vertical scaling limitations (mitigated with read replicas and sharding)
> - More complex operational overhead than managed NoSQL solutions
> - Requires careful index design for optimal query performance
> - Connection pooling required for high concurrency
### Neutral
What changes that are neither positive nor negative?
- Neutral change 1
- Neutral change 2
Example:
> - Team needs to learn PostgreSQL-specific features (JSONB, CTEs, window functions)
> - Migration from existing SQLite database requires schema transformation
> - New monitoring setup required (pg_stat_statements, pg_badger)
## Alternatives Considered
### Alternative 1: [Name]
**Description:** Brief description of the alternative
**Pros:**
- Pro 1
- Pro 2
**Cons:**
- Con 1
- Con 2
**Why rejected:** Specific reason this alternative was not chosen
Example:
### Alternative 1: MongoDB
**Description:** Document database with flexible schema
**Pros:**
- Excellent horizontal scaling with built-in sharding
- Flexible schema allows rapid iteration
- Simple JSON-like document model
**Cons:**
- No ACID transactions across collections (only at document level)
- Eventual consistency model unsuitable for financial data
- Less mature tooling for complex analytical queries
**Why rejected:** Lack of ACID transactions is a dealbreaker for our use case
### Alternative 2: MySQL
**Description:** Popular relational database
**Pros:**
- Wide adoption and large community
- Good performance for read-heavy workloads
- Familiar to most developers
**Cons:**
- Weaker JSON support compared to PostgreSQL
- Oracle licensing concerns for enterprise use
- Less powerful query optimizer
**Why rejected:** PostgreSQL's superior JSON support and query capabilities better align with our requirements
## Implementation
How will this decision be implemented? Include:
- Specific steps to execute
- Timeline estimates
- Team responsibilities
- Rollback plan
Example:
### Phase 1: Infrastructure Setup (Week 1)
- Provision PostgreSQL 15 on AWS RDS
- Configure read replicas in multiple availability zones
- Set up connection pooling with PgBouncer
- Configure automated backups and point-in-time recovery
**Responsible:** DevOps team
### Phase 2: Schema Design (Week 2)
- Design normalized schema for user profiles
- Create indexes for common query patterns
- Implement partitioning strategy for large tables
- Set up migration scripts with Flyway
**Responsible:** Backend team
### Phase 3: Application Integration (Weeks 3-4)
- Implement data access layer with connection pooling
- Add query optimization and caching logic
- Write comprehensive tests for data layer
- Performance testing and tuning
**Responsible:** Backend team
### Phase 4: Migration (Week 5)
- Blue-green deployment with gradual traffic shift
- Data migration from SQLite with validation
- Monitor performance and error rates
- Rollback plan: revert to SQLite if issues detected
**Responsible:** Full team
## Success Metrics
How will we measure if this decision was successful?
- Metric 1: Target value
- Metric 2: Target value
- Metric 3: Target value
Example:
- Write latency: <50ms p95
- Read latency: <10ms p95
- Database uptime: >99.95%
- Zero data inconsistencies
- Query performance: <100ms for complex joins
- Successful migration with <1hr downtime
## Risks and Mitigation
What could go wrong, and how will we handle it?
| Risk | Likelihood | Impact | Mitigation |
|------|------------|--------|------------|
| Database performance degradation | Medium | High | Load testing before production, read replicas, query optimization |
| Data migration issues | Low | Critical | Extensive testing, rollback plan, phased migration |
| Team knowledge gap | Medium | Medium | Training sessions, pair programming, documentation |
## References
- [PostgreSQL Documentation](https://www.postgresql.org/docs/)
- [AWS RDS PostgreSQL Best Practices](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_PostgreSQL.html)
- Internal: Database Comparison Spreadsheet (link)
- Internal: Performance Benchmarks (link)
## Related ADRs
- ADR-001: Microservices Architecture
- ADR-015: API Design Standards
- Supersedes: ADR-008: SQLite for User Data
## Notes
Any additional context, learnings, or future considerations
Example:
> This decision assumes our current scale of 10k writes/second. If we exceed 50k writes/second, we should revisit sharding strategies (ADR-XXX) or evaluate NewSQL databases like CockroachDB.
>
> PostgreSQL's LISTEN/NOTIFY feature may be useful for real-time updates in the future.
---
**Author:** John Doe
**Date:** 2025-01-15
**Last Updated:** 2025-01-15
**Reviewers:** Jane Smith (Tech Lead), Bob Johnson (DBA), Alice Williams (Security)
assets/architecture/gap-analysis-template.md
# Gap Analysis - [System Name]
> **Date:** YYYY-MM-DD
> **Status:** Draft | Final
> **Scope:** [Repos, services, or documents analyzed]
> **Evidence Base:** [Links to profiles, source code paths, or as-is documentation]
> **Method:** Use [qa-docs-coverage](../../../qa-docs-coverage/SKILL.md) to discover components, rank gaps, and collect evidence. Use this template to publish the resulting assessment.
## How to Read This Document
Each gap should include:
- **Severity:** `HIGH`, `MEDIUM`, or `LOW`
- **Blocker:** whether it blocks the next migration, launch, or decommissioning step
- **Evidence:** a source code path, document section, or generated profile reference
- **Addressed By:** the ADR, task, or target component expected to resolve the gap
## [Category Name]
### GAP-01: [Title] [HIGH]
- **Evidence:** `path/to/file.ext:line` or `docs/path.md#Section`
- **Risk:** [What happens if unresolved]
- **Blocker:** Yes / No
- **Addressed By:** [ADR, task, or target service]
- **Notes:** [Validation window, dependency, or owner]
### GAP-02: [Title] [MEDIUM]
- **Evidence:** `path/to/file.ext:line`
- **Risk:** [Operational or delivery impact]
- **Blocker:** Yes / No
- **Addressed By:** [ADR, task, or target service]
- **Notes:** [Any sequencing details]
## Risk Summary
| Gap ID | Category | Severity | Blocker | Summary | Addressed By |
|--------|----------|----------|---------|---------|--------------|
| GAP-01 | Messaging | HIGH | Yes | Topic cutover undefined | ADR-012 |
## Summary Statistics
| Severity | Count | Blockers |
|----------|-------|----------|
| HIGH | 0 | 0 |
| MEDIUM | 0 | 0 |
| LOW | 0 | 0 |
## Next Actions
1. Link each HIGH gap to a concrete resolution owner.
2. Confirm blockers are reflected in the migration plan or backlog.
3. Re-run the assessment after the next major architecture change or delivery phase.
assets/ci/.markdownlint.yaml
# .markdownlint.yaml
# Markdownlint configuration for documentation quality CI.
# Reference: https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md
default: true
# MD013 — Line length.
# Disabled: long lines are common in tables, code blocks, and template files.
# Set to true and configure line_length if the team wants enforcement.
MD013: false
# MD024 — Multiple headings with the same content.
# Allow duplicate headings only when they are not siblings (e.g., same H2 in different H1 sections).
MD024:
siblings_only: true
# MD033 — Inline HTML.
# Allow inline HTML; useful for badges, collapsible sections, and custom callouts.
MD033: false
# MD041 — First line should be a top-level heading.
# Disable for files that start with frontmatter (YAML ---) or template preambles.
MD041: false
# MD034 — Bare URL used.
# Disabled for internal reference files that list raw URLs intentionally.
MD034: false
# MD007 — Unordered list indentation.
# Enforce 2-space indentation for consistent nesting.
MD007:
indent: 2
# MD009 — Trailing spaces.
# Enabled; trailing spaces indicate unfinished edits.
MD009: true
# MD010 — Hard tabs.
# Enabled; use spaces throughout markdown.
MD010: true
# MD022 — Headings should be surrounded by blank lines.
MD022: true
# MD023 — Headings must start at the beginning of the line.
MD023: true
# MD025 — Multiple top-level headings.
# One H1 per file.
MD025: true
# MD031 — Fenced code blocks should be surrounded by blank lines.
MD031: true
# MD036 — Emphasis used instead of a heading.
# Catches patterns like **Bold line** used as a section title.
MD036: true
# MD047 — Files should end with a single newline.
MD047: true
assets/ci/.vale.ini
; .vale.ini — Vale prose linter configuration.
; Reference: https://vale.sh/docs/topics/config/
;
; Usage:
; vale docs/
; vale --config=.vale.ini docs/
;
; First-time setup:
; vale sync # downloads configured styles into StylesPath
StylesPath = .vale/styles
; Minimum alert level to surface: suggestion | warning | error
; Start with "warning" and tighten to "error" once the team is used to it.
MinAlertLevel = warning
; Vocab: project-specific terms that vale should never flag.
; Add entries to .vale/styles/Vocab/accept.txt (one word/phrase per line).
Vocab = Base
[*.md]
; Microsoft style is a well-maintained, balanced starting point.
; Covers: passive voice, first-person, hedging, heading capitalisation, etc.
; To enable, run: vale sync (after configuring packages below).
BasedOnStyles = Microsoft
; Proselint is an alternative / supplement that catches clichés, redundancy,
; and common writing anti-patterns.
; Uncomment and run "vale sync" to add it:
; BasedOnStyles = Microsoft, proselint
; ---- Per-rule overrides ----
; Disable rules that conflict with technical writing norms.
; Microsoft.Headings — enforce sentence-case headings.
; Set to NO if your team uses title case throughout.
Microsoft.Headings = YES
; Microsoft.Passive — passive voice warnings.
; Useful but noisy in runbooks/reference docs. Set to suggestion.
Microsoft.Passive = suggestion
; Microsoft.We — flags first-person "we" in docs.
; Disable in team wikis and internal runbooks where "we" is natural.
Microsoft.We = NO
; Microsoft.Wordiness — flags verbose phrases ("in order to" → "to").
Microsoft.Wordiness = warning
[*.yaml]
; Lint YAML-embedded markdown strings if you use vale on config files.
; Usually leave this section empty unless you have prose in YAML values.
; ---- Package configuration ----
; Uncomment the Packages line after running "vale sync" to auto-download styles.
; Packages = Microsoft, proselint
assets/ci/docs-quality.yml
name: Docs Quality
on:
pull_request:
paths:
- "docs/**"
- "**.md"
jobs:
markdownlint:
name: Markdown lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Install markdownlint-cli
run: npm install -g markdownlint-cli
- name: Run markdownlint
# Adjust the glob to match your docs layout.
# --config points at the shared config from this skill.
run: |
markdownlint \
--config .markdownlint.yaml \
"docs/**/*.md" "*.md" \
--ignore node_modules \
--ignore .archive
link-check:
name: Markdown link check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Install markdown-link-check
run: npm install -g markdown-link-check
- name: Run link check
# --quiet suppresses successful link output; remove for verbose logs.
# The .mlc-config.json (optional) can whitelist localhost or slow external URLs.
run: |
find docs -name "*.md" ! -path "*/.archive/*" | \
xargs -I {} markdown-link-check {} \
--quiet \
--config .mlc-config.json || true
# "|| true" prevents the job from failing on transient external link failures.
# Remove it if you want strict enforcement of external links.
vale:
name: Vale prose lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Install Vale
uses: errata-ai/vale-action@v2
with:
# Point at the .vale.ini from this skill, or the repo root copy.
config: .vale.ini
# Lint the docs/ directory. Adjust if your docs live elsewhere.
files: docs/
# Fail on warnings and above. Set to "error" for a lighter touch.
fail_on_error: true
env:
# Required for private repos when vale-action fetches style packages.
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
assets/docs-as-code/docs-structure-template.md
# Docs-as-Code Structure Template (Core, Non-AI)
Purpose: define a maintainable documentation structure with ownership and freshness mechanisms.
## Inputs
- Product/repo scope (modules, audiences, support burden)
- Tooling constraints (MkDocs/Docusaurus/README-only, CI availability)
## Outputs
- Docs information architecture (IA) and folder structure
- Ownership model and freshness SLAs (who updates what, when)
## Core
### 1) Suggested Information Architecture (Diátaxis-style)
- Tutorials: step-by-step learning paths
- How-to guides: task-oriented procedures
- Reference: exhaustive API/config specs
- Explanation: conceptual context and rationale
### 2) Suggested Repo Layout
```
docs/
index.md
tutorials/
how-to/
reference/
explanation/
runbooks/
adr/
_assets/
```
If docs live in the root:
- `README.md` (quick start + links)
- `docs/` for deeper content
### 3) Required “Freshness” Metadata (per page)
- Owner: team or individual
- Last reviewed: date
- Review cadence: monthly / quarterly / yearly
### 4) CI Checks (recommended)
- Link checker (internal + external if allowed)
- Markdown linting and style guide checks
- “Stale docs” check (fails if last reviewed > cadence)
## Decision Rules
- No docs without owners.
- Prefer small, frequently updated docs over giant “wiki pages”.
- If a runbook exists, it must be testable (commands verified and current).
## Risks
- Docs drift: code changes, docs don’t
- Over-documentation: too much text, no one reads/updates
- Tooling lock-in: docs format prevents contribution
## Optional: AI / Automation
Use only if allowed by policy and data handling rules.
- Generate doc diffs and summarize PR changes; humans review before merging.
- Suggest missing docs based on code changes; do not auto-publish without review.
assets/docs-as-code/ownership-model.md
# Docs Ownership Model (Core, Non-AI)
Purpose: make documentation freshness a first-class operational responsibility.
## Inputs
- Org structure (teams, on-call, product areas)
- Doc types in scope (README, runbooks, ADRs, API docs, user docs)
## Outputs
- Ownership map for doc types and areas
- Review cadence and escalation path for stale docs
## Core
### Ownership Roles
- **Directly Responsible Individual (DRI)**: accountable for updates and quality
- **Approver**: reviews for correctness (often tech lead or PM)
- **Steward**: maintains IA and standards (docs lead or platform team)
### Ownership Table
| Doc type | Owner (DRI) | Approver | Review cadence | Where tracked |
|----------|-------------|----------|----------------|--------------|
| README | {{TEAM}} | {{LEAD}} | Quarterly | PRs |
| Runbooks | {{ON_CALL_TEAM}} | {{SRE_LEAD}} | Monthly | Incident retros |
| ADRs | {{ARCH_TEAM}} | {{ARCH_LEAD}} | On change | ADR index |
| API docs | {{API_TEAM}} | {{API_LEAD}} | On release | CI |
### Freshness SLAs
- Runbooks: reviewed at least monthly or after incidents
- API docs: updated with every backward-incompatible change
- README quick start: updated when install/run commands change
### Enforcement Options
- CI checks for “last reviewed” dates
- Scheduled issues for upcoming reviews
- On-call post-incident action: update runbook + link
## Decision Rules
- If a doc is used during incidents, it must have an owner and a cadence.
- If a doc page has no owner, it is either assigned or deleted.
## Risks
- Ownership theatre (owners listed but no time allocated)
- Stale docs increase support burden and incident time
## Optional: AI / Automation
Use only if allowed by policy and data handling rules.
- Generate “stale docs” reports and draft updates; humans review before publishing.
assets/operational/runbook-template.md
# {{SERVICE_NAME}} Runbook
> **Owner:** {{TEAM_OR_INDIVIDUAL_OWNER}}
> **Last verified:** {{LAST_VERIFIED_DATE}}
> **Review cadence:** {{REVIEW_CADENCE}} (e.g., quarterly, after each incident)
> **Runbook status:** {{STATUS}} (active | draft | deprecated)
---
## Service Overview
| Field | Value |
|---|---|
| **Service name** | {{SERVICE_NAME}} |
| **Short description** | {{ONE_LINE_DESCRIPTION}} |
| **Primary owner** | {{OWNER_NAME}} ({{OWNER_EMAIL_OR_SLACK}}) |
| **Secondary owner / backup** | {{BACKUP_OWNER}} |
| **Repo** | {{REPO_URL}} |
| **Deploy pipeline** | {{CI_CD_LINK}} |
| **Dashboards** | {{DASHBOARD_URL}} |
| **Logs** | {{LOG_AGGREGATION_URL}} |
| **Alerts** | {{ALERTING_PLATFORM_LINK}} |
---
## SLOs
| Metric | Target | Measurement window |
|---|---|---|
| Availability | {{SLO_AVAILABILITY}} % (e.g., 99.9%) | {{WINDOW}} (e.g., rolling 30d) |
| Latency (p99) | < {{SLO_LATENCY_P99}} ms | {{WINDOW}} |
| Error rate | < {{SLO_ERROR_RATE}} % | {{WINDOW}} |
Error budget calculation: `(1 - target_availability) * window_minutes`. At 99.9% over 30 days → 43.2 minutes/month.
---
## Quick Diagnostics
Run these checks first on any page or alert before going deeper.
```bash
# 1. Is the service up?
curl -sf {{HEALTH_ENDPOINT_URL}} || echo "HEALTH CHECK FAILED"
# 2. Recent error rate (last 15 min)
{{LOG_QUERY_OR_CLI_COMMAND_FOR_ERRORS}}
# 3. Resource pressure (CPU / memory)
{{RESOURCE_CHECK_COMMAND}}
# 4. Downstream dependencies alive?
{{DEPENDENCY_HEALTH_COMMAND}}
```
Replace placeholder commands with real CLI invocations for your stack. Keep this section runnable from a terminal with standard credentials.
---
## Common Alerts → Response
### Alert: {{ALERT_NAME_1}}
**What it means:** {{ALERT_DESCRIPTION_1}}
**Severity:** {{P1 | P2 | P3}}
**Triage steps:**
1. {{STEP_1}}
2. {{STEP_2}}
3. {{STEP_3}}
**Resolution:** {{EXPECTED_RESOLUTION}}
**Escalate if:** {{ESCALATION_CONDITION}} (e.g., persists > 15 min after step 3)
---
### Alert: {{ALERT_NAME_2}}
**What it means:** {{ALERT_DESCRIPTION_2}}
**Severity:** {{P1 | P2 | P3}}
**Triage steps:**
1. {{STEP_1}}
2. {{STEP_2}}
**Resolution:** {{EXPECTED_RESOLUTION}}
**Escalate if:** {{ESCALATION_CONDITION}}
---
<!-- Add more alert blocks as needed. One block per distinct alert name. -->
---
## Escalation Path
| Level | Contact | When to escalate | How |
|---|---|---|---|
| On-call engineer | {{ONCALL_ROTATION_LINK}} | Any P1; P2 unresolved > 30 min | PagerDuty / Slack `{{ONCALL_CHANNEL}}` |
| Team lead | {{TEAM_LEAD_NAME}} | P1 customer impact; SLO breach | Slack DM + phone |
| Director / Incident Commander | {{DIRECTOR_NAME}} | Declared incident; data loss risk | Phone + incident bridge `{{BRIDGE_LINK}}` |
**Incident declaration threshold:** {{DECLARATION_THRESHOLD}} (e.g., P1 unresolved > 15 min or user-visible data loss).
---
## Rollback Procedure
Use this procedure when a bad deploy needs to be reverted.
**Prerequisites:** You have deploy pipeline access and the prior release tag `{{PREVIOUS_STABLE_TAG}}`.
```bash
# Step 1: Identify the last known-good deploy
{{COMMAND_TO_LIST_RECENT_DEPLOYS}}
# Step 2: Pin the rollback target
ROLLBACK_TAG={{PREVIOUS_STABLE_TAG}}
# Step 3: Trigger rollback
{{ROLLBACK_COMMAND_OR_PIPELINE_LINK}}
# Step 4: Verify health after rollback
curl -sf {{HEALTH_ENDPOINT_URL}} && echo "Rollback healthy"
# Step 5: Confirm error rate returning to baseline (wait 5 min)
{{LOG_QUERY_OR_CLI_COMMAND_FOR_ERRORS}}
```
**Expected rollback time:** {{ROLLBACK_DURATION}} (e.g., 3–7 minutes).
**Do not rollback if:** {{ROLLBACK_EXCEPTION}} (e.g., rollback would undo a database migration — contact DBA first).
---
## Dependencies
| Dependency | Type | Owner | What breaks if it is down |
|---|---|---|---|
| {{DEP_NAME_1}} | {{upstream \| downstream \| sidecar}} | {{DEP_OWNER_1}} | {{FAILURE_IMPACT_1}} |
| {{DEP_NAME_2}} | {{upstream \| downstream \| sidecar}} | {{DEP_OWNER_2}} | {{FAILURE_IMPACT_2}} |
**Circuit-breaker behavior:** {{DESCRIBE_CIRCUIT_BREAKER_OR_FALLBACK}} (e.g., "falls back to cached response for up to 30 s").
---
## Postmortem Links
| Date | Incident | Link | Key fix |
|---|---|---|---|
| {{INCIDENT_DATE_1}} | {{INCIDENT_TITLE_1}} | {{POSTMORTEM_LINK_1}} | {{KEY_FIX_1}} |
| {{INCIDENT_DATE_2}} | {{INCIDENT_TITLE_2}} | {{POSTMORTEM_LINK_2}} | {{KEY_FIX_2}} |
Add new rows after each postmortem is published. Do not summarize — link directly to the canonical postmortem document.
---
## Additional Notes
{{ANY_SERVICE_SPECIFIC_CONTEXT_THAT_DOES_NOT_FIT_ABOVE}}
Examples of useful additions:
- Known flaky behaviors and safe workarounds.
- Feature flags that affect this service and how to toggle them.
- Scheduled maintenance windows.
- Compliance or data-sensitivity notes (e.g., "this service processes PII — do not log request bodies").
assets/project-management/changelog-template.md
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Added
- New features that have been added but not yet released
### Changed
- Changes to existing functionality
### Deprecated
- Features that are marked for removal in upcoming releases
### Removed
- Features that have been removed
### Fixed
- Bug fixes
### Security
- Security patches and improvements
## [2.1.0] - 2025-01-20
### Added
- User profile avatars with upload functionality (#234)
- Dark mode support across all pages (#245)
- Export data to CSV feature in admin dashboard (#256)
- Rate limiting middleware (100 req/min per user) (#267)
- GraphQL subscriptions for real-time updates (#278)
### Changed
- Updated Node.js from 18.x to 20.x LTS (#289)
- Migrated from REST to GraphQL for user queries (breaking change) (#290)
- Improved database query performance by 40% with optimized indexes (#301)
- Refactored authentication flow to use JWT refresh tokens (#312)
### Deprecated
- `/api/v1/users/search` endpoint (use GraphQL `users` query instead)
- XML response format (will be removed in v3.0.0)
### Security
- Updated `jsonwebtoken` to 9.0.2 to fix CVE-2025-XXXX (#323)
- Implemented Content Security Policy headers (#334)
- Added CSRF protection to all state-changing endpoints (#345)
## [2.0.0] - 2024-12-15
### Added
- Multi-tenancy support with organization isolation (#123)
- Two-factor authentication via TOTP (#134)
- Comprehensive audit logging for compliance (#145)
- Webhook integration system for third-party apps (#156)
- New `/api/v2/reports` endpoint for generating analytics reports (#167)
### Changed
- **BREAKING:** Minimum Node.js version is now 18.x (was 16.x)
- **BREAKING:** Database schema migration required (see migration guide)
- **BREAKING:** API authentication now requires Bearer token (removed API key support)
- Redesigned user interface with Material Design components
- Improved error messages with more context and troubleshooting steps
- Database connection pooling increased from 10 to 50 connections
### Removed
- **BREAKING:** Legacy XML API endpoints (deprecated in v1.5.0)
- **BREAKING:** Support for IE11 browser
- Unused `oldFeature` configuration option
- Deprecated `/api/v1/legacy/users` endpoint
### Fixed
- Memory leak in WebSocket connection handler (#178)
- Race condition in concurrent order processing (#189)
- Incorrect timezone handling for scheduled reports (#190)
- SQL injection vulnerability in search endpoint (CVE-2024-XXXX) (#201)
### Security
- Migrated password hashing from bcrypt to Argon2id (#212)
- Implemented rate limiting to prevent brute force attacks (#223)
- Added automated security scanning in CI/CD pipeline (#234)
## [1.5.0] - 2024-10-01
### Added
- Email notification system with templating (#89)
- User preferences page for customization (#90)
- Bulk import/export functionality for admin users (#91)
- API documentation with interactive Swagger UI (#92)
### Changed
- Updated all dependencies to latest versions
- Improved test coverage from 75% to 90%
- Enhanced logging with structured JSON format
### Deprecated
- XML API endpoints (use JSON instead, will be removed in v2.0.0)
### Fixed
- Pagination bug returning duplicate results (#93)
- Date formatting inconsistency across timezones (#94)
- File upload failing for files >10MB (#95)
## [1.4.1] - 2024-09-15
### Fixed
- Critical hotfix: Database connection pool exhaustion under high load (#81)
- User session expiring prematurely (#82)
- Incorrect currency conversion in checkout (#83)
### Security
- Updated `express` to 4.18.2 to address ReDoS vulnerability (#84)
## [1.4.0] - 2024-09-01
### Added
- Search functionality with full-text search (#67)
- User activity dashboard with charts (#68)
- API versioning support (v1 and v2 endpoints) (#69)
### Changed
- Improved Docker image size (reduced by 40%) (#70)
- Optimized database queries for better performance (#71)
### Fixed
- Login redirect loop for certain edge cases (#72)
- Broken pagination on user list page (#73)
## [1.3.0] - 2024-08-01
### Added
- OAuth2 authentication with Google and GitHub (#45)
- User roles and permissions system (#46)
- Automated database backups to S3 (#47)
### Changed
- Migrated from MongoDB to PostgreSQL (#48)
- Updated UI framework from Bootstrap 4 to Bootstrap 5 (#49)
### Fixed
- Performance issues with large dataset exports (#50)
- CORS configuration blocking valid requests (#51)
## [1.2.0] - 2024-07-01
### Added
- RESTful API with JWT authentication (#23)
- File attachment support for user profiles (#24)
- Admin panel for user management (#25)
### Changed
- Improved error handling with better error messages (#26)
- Updated branding and logo (#27)
### Fixed
- Form validation errors not displaying correctly (#28)
- Email delivery failures for certain providers (#29)
## [1.1.0] - 2024-06-01
### Added
- User registration and login functionality (#12)
- Password reset via email (#13)
- Basic user profile management (#14)
### Fixed
- Database migration script errors (#15)
- Broken CSS on mobile devices (#16)
## [1.0.0] - 2024-05-01
### Added
- Initial release of the application
- Basic CRUD operations for resources
- PostgreSQL database integration
- Express.js REST API
- User authentication with JWT
- Docker deployment configuration
- Comprehensive test suite
- CI/CD pipeline with GitHub Actions
---
## Version Format
This project follows [Semantic Versioning](https://semver.org/):
- **MAJOR** version for incompatible API changes
- **MINOR** version for new features (backward-compatible)
- **PATCH** version for bug fixes (backward-compatible)
## Categories
- **Added:** New features
- **Changed:** Changes to existing functionality
- **Deprecated:** Features marked for removal
- **Removed:** Removed features
- **Fixed:** Bug fixes
- **Security:** Security patches and improvements
## Issue References
Each change includes a reference to the related issue/PR number (e.g., #123).
## Links
[Unreleased]: https://github.com/username/repo/compare/v2.1.0...HEAD
[2.1.0]: https://github.com/username/repo/compare/v2.0.0...v2.1.0
[2.0.0]: https://github.com/username/repo/compare/v1.5.0...v2.0.0
[1.5.0]: https://github.com/username/repo/compare/v1.4.1...v1.5.0
[1.4.1]: https://github.com/username/repo/compare/v1.4.0...v1.4.1
[1.4.0]: https://github.com/username/repo/compare/v1.3.0...v1.4.0
[1.3.0]: https://github.com/username/repo/compare/v1.2.0...v1.3.0
[1.2.0]: https://github.com/username/repo/compare/v1.1.0...v1.2.0
[1.1.0]: https://github.com/username/repo/compare/v1.0.0...v1.1.0
[1.0.0]: https://github.com/username/repo/releases/tag/v1.0.0
assets/project-management/contributing-template.md
# Contributing to [Project Name]
Thank you for your interest in contributing! We welcome contributions from everyone.
## Table of Contents
- [Code of Conduct](#code-of-conduct)
- [Getting Started](#getting-started)
- [Development Setup](#development-setup)
- [How to Contribute](#how-to-contribute)
- [Coding Standards](#coding-standards)
- [Commit Message Guidelines](#commit-message-guidelines)
- [Pull Request Process](#pull-request-process)
- [Testing Guidelines](#testing-guidelines)
- [Documentation](#documentation)
- [Community](#community)
## Code of Conduct
This project adheres to the `CODE_OF_CONDUCT.md`. By participating, you are expected to uphold this code. Please report unacceptable behavior to [conduct@example.com](mailto:conduct@example.com).
## Getting Started
### Prerequisites
Before you begin, ensure you have:
- [Node.js](https://nodejs.org/) 18.0 or higher
- [Git](https://git-scm.com/)
- A GitHub account
- Familiarity with JavaScript/TypeScript
- Basic understanding of the project architecture
### Finding Issues to Work On
- **Good first issues**: Check issues labeled [`good first issue`](https://github.com/username/repo/labels/good%20first%20issue)
- **Help wanted**: Issues labeled [`help wanted`](https://github.com/username/repo/labels/help%20wanted) are open for contribution
- **Bug fixes**: Look for issues labeled [`bug`](https://github.com/username/repo/labels/bug)
## Development Setup
### 1. Fork the Repository
Fork the repository to your GitHub account by clicking the "Fork" button.
### 2. Clone Your Fork
```bash
git clone https://github.com/YOUR_USERNAME/project-name.git
cd project-name
```
### 3. Add Upstream Remote
```bash
git remote add upstream https://github.com/original-owner/project-name.git
```
### 4. Install Dependencies
```bash
npm install
```
### 5. Create a Feature Branch
```bash
git checkout -b feature/your-feature-name
```
**Branch naming conventions:**
- `feature/description` - New features
- `fix/description` - Bug fixes
- `docs/description` - Documentation changes
- `refactor/description` - Code refactoring
- `test/description` - Test improvements
### 6. Run Development Server
```bash
npm run dev
```
The application will be available at http://localhost:3000
### 7. Run Tests
```bash
# Run all tests
npm test
# Run tests in watch mode
npm run test:watch
# Run tests with coverage
npm run test:coverage
```
## How to Contribute
### Reporting Bugs
Before creating a bug report, please check if the issue already exists.
**When filing a bug report, include:**
- **Title**: Clear, descriptive summary
- **Description**: Detailed description of the issue
- **Steps to Reproduce**: Step-by-step instructions
- **Expected Behavior**: What should happen
- **Actual Behavior**: What actually happens
- **Environment**: OS, Node.js version, browser (if applicable)
- **Screenshots**: If applicable
- **Logs**: Relevant error messages or logs
**Bug Report Template:**
```markdown
## Description
A clear description of the bug.
## Steps to Reproduce
1. Go to '...'
2. Click on '...'
3. See error
## Expected Behavior
What you expected to happen.
## Actual Behavior
What actually happened.
## Environment
- OS: [e.g., macOS 13.0]
- Node.js: [e.g., 18.16.0]
- Browser: [e.g., Chrome 115]
## Additional Context
Any other context, screenshots, or logs.
```
### Suggesting Enhancements
Enhancement suggestions are welcome! Please create an issue with:
- **Clear title**: Concise description of the enhancement
- **Use case**: Why this enhancement would be useful
- **Detailed description**: How it should work
- **Mockups/Examples**: If applicable
### Submitting Code Changes
1. **Create or find an issue**: Ensure there's an issue for your change
2. **Discuss your approach**: Comment on the issue before starting work
3. **Fork and create a branch**: Follow the branching guidelines
4. **Make your changes**: Write code following our standards
5. **Write tests**: Add tests for new functionality
6. **Update documentation**: Update relevant docs
7. **Run tests and linters**: Ensure all checks pass
8. **Commit your changes**: Use conventional commit messages
9. **Push to your fork**: `git push origin feature/your-feature`
10. **Open a Pull Request**: From your fork to the main repository
## Coding Standards
### JavaScript/TypeScript Style
We follow the [Airbnb JavaScript Style Guide](https://github.com/airbnb/javascript) with some modifications.
**Key Points:**
- Use 2 spaces for indentation
- Use single quotes for strings
- Always use semicolons
- Use camelCase for variables and functions
- Use PascalCase for classes and types
- Use UPPER_SNAKE_CASE for constants
- Prefer `const` over `let`, avoid `var`
- Use arrow functions for anonymous functions
- Use template literals for string interpolation
**Example:**
```javascript
// Good
const getUserName = (user) => {
return user.firstName + ' ' + user.lastName;
};
const MAX_RETRY_COUNT = 3;
// Bad
var get_user_name = function(user) {
return user.firstName + " " + user.lastName
}
const maxRetryCount = 3;
```
### Linting and Formatting
Run ESLint and Prettier before committing:
```bash
# Lint code
npm run lint
# Fix linting errors automatically
npm run lint:fix
# Format code
npm run format
# Type check (TypeScript)
npm run type-check
```
**Pre-commit hook automatically runs these checks.**
### TypeScript Guidelines
- Use strict type checking
- Avoid `any` type (use `unknown` if type is truly unknown)
- Define interfaces for all object shapes
- Use type guards for type narrowing
- Document complex types with JSDoc comments
**Example:**
```typescript
// Good
interface User {
id: string;
name: string;
email: string;
}
function getUser(id: string): User | null {
// implementation
}
// Bad
function getUser(id: any): any {
// implementation
}
```
### File and Folder Structure
```
src/
├── api/ # API routes and controllers
├── models/ # Database models
├── services/ # Business logic
├── utils/ # Helper functions
├── types/ # TypeScript type definitions
└── __tests__/ # Test files (co-located with source)
```
## Commit Message Guidelines
We follow the [Conventional Commits](https://www.conventionalcommits.org/) specification.
### Format
```
<type>(<scope>): <subject>
<body>
<footer>
```
### Types
- `feat`: New feature
- `fix`: Bug fix
- `docs`: Documentation changes
- `style`: Code style changes (formatting, no logic change)
- `refactor`: Code refactoring
- `perf`: Performance improvements
- `test`: Adding or updating tests
- `build`: Build system or dependency changes
- `ci`: CI configuration changes
- `chore`: Other changes that don't modify src or test files
### Scope
Optional, indicates the area of the codebase (e.g., `auth`, `api`, `ui`).
### Subject
- Use imperative mood ("add" not "added")
- Don't capitalize first letter
- No period at the end
- Limit to 50 characters
### Body
- Optional, provides additional context
- Wrap at 72 characters
- Explain what and why, not how
### Footer
- Optional, references issues or breaking changes
- Use `Closes #123` to auto-close issues
- Use `BREAKING CHANGE:` for breaking changes
### Examples
```
feat(auth): add OAuth2 authentication
Implements OAuth2 authorization code flow with Google and GitHub providers.
Includes token refresh and secure storage.
Closes #123
```
```
fix(api): handle null response from database
Adds null check before accessing user.email property to prevent TypeError.
Fixes #456
```
```
docs: update API documentation for v2 endpoints
BREAKING CHANGE: v1 endpoints are deprecated and will be removed in next major release
```
## Pull Request Process
### Before Submitting
- [ ] Create an issue if one doesn't exist
- [ ] Fork the repository
- [ ] Create a feature branch
- [ ] Write code following our standards
- [ ] Add tests for new functionality
- [ ] Update documentation
- [ ] Run tests: `npm test`
- [ ] Run linter: `npm run lint`
- [ ] Ensure type checking passes: `npm run type-check`
- [ ] Commit with conventional commit messages
- [ ] Rebase on latest `main` if needed
### PR Title and Description
**Title Format:**
```
<type>(<scope>): <short summary>
```
**Description Template:**
```markdown
## Description
Brief description of changes
## Related Issue
Closes #123
## Type of Change
- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] Documentation update
## Testing
- [ ] All tests pass locally
- [ ] Added tests for new functionality
- [ ] Manual testing completed
## Checklist
- [ ] Code follows project style guidelines
- [ ] Self-review completed
- [ ] Comments added for complex code
- [ ] Documentation updated
- [ ] No new warnings generated
- [ ] Tests added and passing
## Screenshots (if applicable)
```
### Review Process
1. **Automated checks**: CI must pass (tests, linting, type checking)
2. **Code review**: At least one maintainer approval required
3. **Discussion**: Address reviewer feedback
4. **Approval**: Once approved, a maintainer will merge
### After PR is Merged
1. Delete your feature branch
2. Pull latest main: `git pull upstream main`
3. Thank the reviewers!
## Testing Guidelines
### Writing Tests
- **Unit tests**: Test individual functions and modules
- **Integration tests**: Test interactions between components
- **E2E tests**: Test complete user workflows
### Test Structure
```javascript
describe('Feature Name', () => {
describe('functionName', () => {
it('should do something specific', () => {
// Arrange
const input = 'test';
// Act
const result = functionName(input);
// Assert
expect(result).toBe('expected output');
});
it('should handle edge cases', () => {
expect(() => functionName(null)).toThrow();
});
});
});
```
### Test Coverage
- Aim for >80% code coverage
- All new features must include tests
- Bug fixes should include regression tests
```bash
# Check coverage
npm run test:coverage
# View HTML report
open coverage/index.html
```
## Documentation
### Code Documentation
- Add JSDoc comments for public APIs
- Explain complex logic with inline comments
- Keep comments up-to-date with code changes
### User Documentation
- Update README.md for user-facing changes
- Add examples to docs/ folder
- Update API documentation for endpoint changes
### Writing Good Documentation
- Use clear, concise language
- Include code examples
- Explain the "why" not just the "what"
- Keep documentation DRY (Don't Repeat Yourself)
## Community
### Getting Help
- **Discord**: https://discord.gg/project-name
- **GitHub Discussions**: https://github.com/username/repo/discussions
- **Stack Overflow**: Tag with `project-name`
### Recognition
Contributors are recognized in:
- `CONTRIBUTORS.md`
- GitHub contributor graph
- Release notes
## License
By contributing, you agree that your contributions will be licensed under the project's `LICENSE`.
---
**Questions?** Feel free to ask in [GitHub Discussions](https://github.com/username/repo/discussions) or on [Discord](https://discord.gg/project-name).
**Thank you for contributing!** [CELEBRATE]
assets/project-management/readme-template.md
# Project Name
Brief one-line description of what this project does and why it exists.
## Features
- Key feature 1
- Key feature 2
- Key feature 3
- Key feature 4
## Prerequisites
Before you begin, ensure you have the following installed:
- [Node.js](https://nodejs.org/) 18.0 or higher
- [PostgreSQL](https://www.postgresql.org/) 14 or higher
- [Redis](https://redis.io/) 7.0 or higher (optional, for caching)
## Installation
### 1. Clone the repository
```bash
git clone https://github.com/username/project-name.git
cd project-name
```
### 2. Install dependencies
```bash
npm install
```
### 3. Configure environment variables
```bash
cp .env.example .env
```
Edit `.env` with your configuration:
```env
PORT=3000
DATABASE_URL=postgresql://user:password@localhost:5432/dbname
REDIS_URL=redis://localhost:6379
API_KEY=your-api-key-here
```
### 4. Initialize database
```bash
npm run db:migrate
npm run db:seed
```
### 5. Start development server
```bash
npm run dev
```
The application will be available at http://localhost:3000
## Configuration
### Environment Variables
| Variable | Description | Required | Default |
|----------|-------------|----------|---------|
| `PORT` | Server port | No | `3000` |
| `DATABASE_URL` | PostgreSQL connection string | Yes | - |
| `REDIS_URL` | Redis connection string | No | `redis://localhost:6379` |
| `API_KEY` | External API key | Yes | - |
| `LOG_LEVEL` | Logging level (`debug`, `info`, `warn`, `error`) | No | `info` |
| `NODE_ENV` | Environment (`development`, `production`, `test`) | No | `development` |
## Usage
### Basic Example
```javascript
const { Client } = require('@yourorg/package');
const client = new Client({
apiKey: process.env.API_KEY
});
async function example() {
const result = await client.doSomething({
param: 'value'
});
console.log(result);
}
example();
```
### Advanced Example
```javascript
const { Client, Config } = require('@yourorg/package');
const config = new Config({
apiKey: process.env.API_KEY,
timeout: 5000,
retries: 3
});
const client = new Client(config);
async function advancedExample() {
try {
const result = await client.doComplexOperation({
filters: { category: 'example' },
sort: 'name',
limit: 10
});
result.items.forEach(item => {
console.log(item.name);
});
} catch (error) {
console.error('Operation failed:', error.message);
}
}
advancedExample();
```
## API Documentation
### REST API Endpoints
Base URL: `https://api.example.com/v1`
#### Authentication
All requests require authentication via Bearer token:
```bash
curl -H "Authorization: Bearer YOUR_API_KEY" \
https://api.example.com/v1/users
```
#### Endpoints
- **GET /api/v1/users** - List all users
- **POST /api/v1/users** - Create a new user
- **GET /api/v1/users/:id** - Get user by ID
- **PUT /api/v1/users/:id** - Update user
- **DELETE /api/v1/users/:id** - Delete user
For complete API documentation, see `docs/API.md`.
## Development
### Project Structure
```
project-name/
├── src/
│ ├── api/ # API routes and controllers
│ ├── models/ # Database models
│ ├── services/ # Business logic
│ ├── utils/ # Helper functions
│ └── index.js # Application entry point
├── tests/ # Test files
├── docs/ # Documentation
├── scripts/ # Build and deployment scripts
├── .env.example # Example environment variables
├── package.json # Dependencies and scripts
└── README.md # This file
```
### Available Scripts
```bash
# Development
npm run dev # Start development server with hot reload
npm run dev:debug # Start with debugger attached
# Building
npm run build # Build for production
npm run build:watch # Build with watch mode
# Testing
npm test # Run all tests
npm run test:watch # Run tests in watch mode
npm run test:coverage # Run tests with coverage report
npm run test:e2e # Run end-to-end tests
# Code Quality
npm run lint # Run ESLint
npm run lint:fix # Fix ESLint errors automatically
npm run format # Format code with Prettier
npm run type-check # Run TypeScript type checking
# Database
npm run db:migrate # Run database migrations
npm run db:seed # Seed database with sample data
npm run db:reset # Reset database (drop + migrate + seed)
# Utilities
npm run clean # Remove build artifacts
npm run docs # Generate documentation
```
## Testing
### Running Tests
```bash
# Run all tests
npm test
# Run with coverage
npm run test:coverage
# Run specific test file
npm test -- path/to/test.js
# Run tests in watch mode
npm run test:watch
```
### Writing Tests
Tests are located in the `tests/` directory and follow this naming convention: `*.test.js`
Example test:
```javascript
const { calculateTotal } = require('../src/utils');
describe('calculateTotal', () => {
it('should calculate total with tax', () => {
const result = calculateTotal(100, 0.08);
expect(result).toBe(108);
});
it('should throw error for negative price', () => {
expect(() => calculateTotal(-10, 0.08)).toThrow();
});
});
```
## Deployment
### Production Build
```bash
npm run build
npm start
```
### Docker
```bash
# Build image
docker build -t project-name .
# Run container
docker run -p 3000:3000 \
-e DATABASE_URL=postgresql://... \
-e API_KEY=... \
project-name
```
### Docker Compose
```bash
docker-compose up -d
```
For detailed deployment instructions, see `docs/DEPLOYMENT.md`.
## Architecture
This project follows a layered architecture:
- **API Layer:** Express routes and controllers
- **Service Layer:** Business logic and orchestration
- **Data Layer:** Database models and queries
- **Infrastructure:** Configuration, logging, error handling
For detailed architecture documentation, see `docs/ARCHITECTURE.md`.
## Contributing
We welcome contributions! Please see `CONTRIBUTING.md` for guidelines.
### Quick Start for Contributors
1. Fork the repository
2. Create a feature branch: `git checkout -b feature/your-feature-name`
3. Make your changes
4. Run tests: `npm test`
5. Commit with conventional commits: `git commit -m "feat: add new feature"`
6. Push to your fork: `git push origin feature/your-feature-name`
7. Open a Pull Request
## Troubleshooting
### Common Issues
**Issue: Database connection fails**
- Verify `DATABASE_URL` is correct
- Check PostgreSQL is running: `pg_isready`
- Ensure database exists: `createdb dbname`
- Check network connectivity and firewall rules
**Issue: Port already in use**
- Change `PORT` in `.env` file
- Or kill process using the port: `lsof -ti:3000 | xargs kill`
**Issue: Module not found errors**
- Delete `node_modules` and reinstall: `rm -rf node_modules && npm install`
- Clear npm cache: `npm cache clean --force`
**Issue: TypeScript errors**
- Regenerate types: `npm run type-check`
- Update `@types/*` packages: `npm update @types/*`
For more troubleshooting help, see `docs/TROUBLESHOOTING.md` or [open an issue](https://github.com/username/project-name/issues).
## Performance
- Supports 1000+ requests/second
- Average response time: <50ms
- Database connection pooling enabled
- Redis caching for frequently accessed data
## Security
- Input validation on all endpoints
- SQL injection protection via parameterized queries
- XSS protection with content security policy
- Rate limiting: 100 requests/min per IP
- API keys encrypted at rest
For security issues, please email security@example.com instead of opening a public issue.
## License
This project is licensed under the MIT License - see the `LICENSE` file for details.
## Support
- **Documentation:** https://docs.example.com
- **Issues:** https://github.com/username/project-name/issues
- **Discord:** https://discord.gg/project-name
- **Email:** support@example.com
## Changelog
See `CHANGELOG.md` for a list of changes.
## Acknowledgments
- [Express](https://expressjs.com/) - Web framework
- [PostgreSQL](https://www.postgresql.org/) - Database
- [Redis](https://redis.io/) - Caching layer
- All our [contributors](https://github.com/username/project-name/graphs/contributors)
---
**Built with ❤ by [Your Team Name](https://example.com)**
assets/project-management/template-doc-sync-checklist.md
# Template: Documentation Sync Checklist
Use this after implementation milestones to keep docs consistent.
## Context
- Milestone/feature set: `_____________________________`
- Canonical status doc: `____________________________`
- Date: `YYYY-MM-DD`
- Owner: `________________________________________`
## Checklist
- [ ] Canonical status source updated with date and owner.
- [ ] Dependent docs checked for stale/conflicting status text.
- [ ] Temporary reports marked with lifecycle metadata.
- [ ] Integrated reports marked `integrated` or `superseded`.
- [ ] `delete_by` dates assigned for temporary docs.
- [ ] Links updated to canonical source (no duplicated policy prose).
## Conflict Log
| File | Old Claim | New Canonical State | Action Taken |
|---|---|---|---|
| | | | |
| | | | |
## Closure
- [ ] Sync complete
- [ ] Follow-up required
- Follow-up owner/date: `____________________________`
data/sources.json
{
"metadata": {
"skill": "docs-codebase",
"updated": "2026-08-09",
"total_sources": 40,
"description": "Primary standards and practical tools for docs-as-code, OpenAPI and AsyncAPI documentation, AI-readable docs, cross-platform instruction files, and documentation quality checks.",
"version": "2.5",
"title": "Docs Codebase - Sources",
"last_updated": "2026-08-09"
},
"categories": {
"style_guides_and_writing": [
{
"name": "Google Developer Documentation Style Guide",
"url": "https://developers.google.com/style",
"type": "documentation",
"relevance": "Practical, widely used style guide for clear technical writing.",
"update_frequency": "continuous",
"access": "free",
"add_as_web_search": true,
"tags": [
"writing",
"style"
]
},
{
"name": "Microsoft Writing Style Guide",
"url": "https://learn.microsoft.com/en-us/style-guide/welcome/",
"type": "documentation",
"relevance": "Modern technical writing guidance with examples and conventions.",
"update_frequency": "continuous",
"access": "free",
"add_as_web_search": true,
"tags": [
"writing",
"style"
]
},
{
"name": "Diataxis Framework",
"url": "https://diataxis.fr/",
"type": "framework",
"relevance": "Information architecture model for tutorials, how-to guides, reference, and explanation docs.",
"update_frequency": "continuous",
"access": "free",
"add_as_web_search": true,
"tags": [
"docs-ia",
"framework"
]
},
{
"name": "blader/humanizer",
"url": "https://github.com/blader/humanizer",
"type": "tool",
"relevance": "Source taxonomy for AI-writing tells (elegant variation, copula avoidance, negative parallelisms, false ranges, knowledge-cutoff disclaimers, etc.) adapted into writing-best-practices.md's AI-Writing Tells section. Pinned at commit 523374dee72d67c7b2b5f858ea0094ffda49c3ac (MIT license), extracted 2026-08-09.",
"update_frequency": "static",
"access": "free",
"add_as_web_search": false,
"tags": [
"writing",
"ai-tells",
"style"
]
}
],
"markdown_and_content_standards": [
{
"name": "CommonMark Specification",
"url": "https://commonmark.org/",
"type": "specification",
"relevance": "Reference Markdown spec to reduce renderer inconsistencies.",
"update_frequency": "continuous",
"access": "free",
"add_as_web_search": false,
"tags": [
"markdown"
]
},
{
"name": "Keep a Changelog",
"url": "https://keepachangelog.com/",
"type": "specification",
"relevance": "Changelog format that stays readable and auditable over time.",
"update_frequency": "continuous",
"access": "free",
"add_as_web_search": false,
"tags": [
"changelog"
]
},
{
"name": "Semantic Versioning 2.0.0",
"url": "https://semver.org/",
"type": "specification",
"relevance": "Versioning rules for release notes and compatibility expectations.",
"update_frequency": "static",
"access": "free",
"add_as_web_search": false,
"tags": [
"semver"
]
},
{
"name": "Architecture Decision Records (ADR)",
"url": "https://adr.github.io/",
"type": "reference",
"relevance": "Entry point for ADR patterns and ecosystem.",
"update_frequency": "continuous",
"access": "free",
"add_as_web_search": true,
"tags": [
"adr"
]
}
],
"api_documentation_and_specs": [
{
"name": "OpenAPI Specification",
"url": "https://spec.openapis.org/oas/",
"type": "specification",
"relevance": "Canonical OpenAPI landing page for versioned API documentation.",
"update_frequency": "continuous",
"access": "free",
"add_as_web_search": true,
"tags": [
"openapi"
]
},
{
"name": "OpenAPI 3.2.0",
"url": "https://spec.openapis.org/oas/v3.2.0.html",
"type": "specification",
"relevance": "Latest published OpenAPI version with sequential media types, richer tags, and query operation improvements.",
"update_frequency": "static",
"access": "free",
"add_as_web_search": true,
"tags": [
"openapi",
"version"
]
},
{
"name": "AsyncAPI Specification v3.1.0",
"url": "https://www.asyncapi.com/docs/reference/specification/v3.1.0",
"type": "specification",
"relevance": "Primary spec for event-driven, streaming, and message-driven API documentation.",
"update_frequency": "static",
"access": "free",
"add_as_web_search": true,
"tags": [
"asyncapi",
"events"
]
},
{
"name": "Arazzo Specification",
"url": "https://spec.openapis.org/arazzo/latest.html",
"type": "specification",
"relevance": "Workflow descriptions for multi-step API usage and task-oriented API docs.",
"update_frequency": "continuous",
"access": "free",
"add_as_web_search": true,
"tags": [
"arazzo",
"api-workflows"
]
},
{
"name": "RFC 9457 - Problem Details for HTTP APIs",
"url": "https://www.rfc-editor.org/rfc/rfc9457",
"type": "specification",
"relevance": "Current standard error format for HTTP APIs; obsoletes RFC 7807.",
"update_frequency": "static",
"access": "free",
"add_as_web_search": false,
"tags": [
"api",
"errors",
"rfc"
]
}
],
"docs_quality_and_ci": [
{
"name": "Vale",
"url": "https://vale.sh/",
"type": "tool",
"relevance": "Prose linter for consistent terminology and style in docs-as-code pipelines.",
"update_frequency": "continuous",
"access": "free",
"add_as_web_search": true,
"tags": [
"lint",
"docs"
]
},
{
"name": "markdownlint",
"url": "https://github.com/DavidAnson/markdownlint",
"type": "tool",
"relevance": "Markdown style rules for consistent formatting across large doc sets.",
"update_frequency": "continuous",
"access": "free",
"add_as_web_search": false,
"tags": [
"lint",
"markdown"
]
},
{
"name": "markdown-link-check",
"url": "https://github.com/tcort/markdown-link-check",
"type": "tool",
"relevance": "Automated link checking for docs to prevent broken navigation.",
"update_frequency": "continuous",
"access": "free",
"add_as_web_search": false,
"tags": [
"links",
"ci"
]
},
{
"name": "cspell",
"url": "https://cspell.org/",
"type": "tool",
"relevance": "Spell checking for docs and codebases with custom dictionaries.",
"update_frequency": "continuous",
"access": "free",
"add_as_web_search": false,
"tags": [
"spelling",
"ci"
]
},
{
"name": "Redocly CLI",
"url": "https://redocly.com/docs/cli",
"type": "tool",
"relevance": "API linting, bundling, and governance checks for OpenAPI and related specifications.",
"update_frequency": "continuous",
"access": "free",
"add_as_web_search": true,
"tags": [
"openapi",
"lint",
"contracts"
]
}
],
"accessibility": [
{
"name": "Web Content Accessibility Guidelines (WCAG) 2.2",
"url": "https://www.w3.org/TR/WCAG22/",
"type": "specification",
"relevance": "Accessibility baseline referenced by many orgs and policies; impacts docs sites and exported artifacts.",
"update_frequency": "static",
"access": "free",
"add_as_web_search": false,
"tags": [
"accessibility",
"wcag"
]
},
{
"name": "WCAG 3.0 Working Draft",
"url": "https://www.w3.org/TR/wcag-3.0/",
"type": "specification",
"relevance": "Preview of outcome-based accessibility guidance for long-term planning.",
"update_frequency": "continuous",
"access": "free",
"add_as_web_search": true,
"tags": [
"accessibility",
"wcag3"
]
}
],
"adr_and_architecture": [
{
"name": "AWS ADR Process",
"url": "https://docs.aws.amazon.com/prescriptive-guidance/latest/architectural-decision-records/adr-process.html",
"type": "documentation",
"relevance": "Enterprise ADR process with lifecycle management and collaboration patterns.",
"update_frequency": "continuous",
"access": "free",
"add_as_web_search": true,
"tags": [
"adr",
"enterprise"
]
},
{
"name": "Google Cloud ADR Guide",
"url": "https://docs.cloud.google.com/architecture/architecture-decision-records",
"type": "documentation",
"relevance": "Google's ADR framework with lifecycle and after-action guidance.",
"update_frequency": "continuous",
"access": "free",
"add_as_web_search": true,
"tags": [
"adr",
"enterprise"
]
},
{
"name": "AWS ADR Best Practices",
"url": "https://aws.amazon.com/blogs/architecture/master-architecture-decision-records-adrs-best-practices-for-effective-decision-making/",
"type": "article",
"relevance": "Practical team workflows for review cadence, readouts, and ADR maintenance.",
"update_frequency": "static",
"access": "free",
"add_as_web_search": false,
"tags": [
"adr",
"best-practices"
]
}
],
"docs_site_generators": [
{
"name": "MkDocs",
"url": "https://www.mkdocs.org/",
"type": "documentation",
"relevance": "Simple Markdown docs sites, especially strong for Python and ops-oriented repos.",
"update_frequency": "continuous",
"access": "free",
"add_as_web_search": true,
"tags": [
"docs-site",
"mkdocs"
]
},
{
"name": "Docusaurus",
"url": "https://docusaurus.io/",
"type": "documentation",
"relevance": "Versioned docs portals with strong ecosystem support for large product documentation.",
"update_frequency": "continuous",
"access": "free",
"add_as_web_search": true,
"tags": [
"docs-site",
"docusaurus"
]
},
{
"name": "VitePress",
"url": "https://vitepress.dev/",
"type": "documentation",
"relevance": "Modern Vue-powered docs site generator with strong Markdown ergonomics and llms.txt support.",
"update_frequency": "continuous",
"access": "free",
"add_as_web_search": true,
"tags": [
"docs-site",
"vitepress",
"llms"
]
},
{
"name": "Astro Starlight",
"url": "https://starlight.astro.build/",
"type": "documentation",
"relevance": "Astro-based documentation framework with strong content architecture and plugin ecosystem.",
"update_frequency": "continuous",
"access": "free",
"add_as_web_search": true,
"tags": [
"docs-site",
"starlight",
"astro"
]
}
],
"ai_documentation_platforms": [
{
"name": "Mintlify",
"url": "https://www.mintlify.com",
"type": "tool",
"relevance": "Hosted developer docs platform with API docs, search, and AI-facing content features.",
"update_frequency": "continuous",
"access": "freemium",
"add_as_web_search": true,
"tags": [
"ai",
"docs-platform"
]
},
{
"name": "ReadMe",
"url": "https://readme.com/",
"type": "tool",
"relevance": "Hosted API and product documentation platform with changelogs, metrics, and interactive docs.",
"update_frequency": "continuous",
"access": "freemium",
"add_as_web_search": true,
"tags": [
"ai",
"api-docs",
"docs-platform"
]
},
{
"name": "Apidog",
"url": "https://apidog.com/",
"type": "tool",
"relevance": "Integrated API platform spanning design, testing, mocking, and documentation.",
"update_frequency": "continuous",
"access": "freemium",
"add_as_web_search": true,
"tags": [
"api",
"docs-platform",
"testing"
]
}
],
"agent_readable_docs_and_protocols": [
{
"name": "OpenAI Harness Engineering",
"url": "https://openai.com/index/harness-engineering/",
"type": "article",
"relevance": "Current OpenAI engineering guidance on making repositories agent-legible through versioned, repo-local artifacts instead of ad hoc instructions.",
"update_frequency": "static",
"access": "free",
"add_as_web_search": true,
"tags": [
"codex",
"agent-readable",
"repo-context"
]
},
{
"name": "Anthropic Effective Context Engineering for AI Agents",
"url": "https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents",
"type": "article",
"relevance": "Current context-engineering guidance for token utility, separation of concerns, and avoiding bloated ambiguous context.",
"update_frequency": "static",
"access": "free",
"add_as_web_search": true,
"tags": [
"context-engineering",
"agents",
"agent-readable"
]
},
{
"name": "VS Code Copilot Custom Instructions",
"url": "https://code.visualstudio.com/docs/copilot/customization/custom-instructions",
"type": "documentation",
"relevance": "Current Microsoft guidance on AGENTS.md, file-based instructions, concise rules, and selective instruction loading.",
"update_frequency": "continuous",
"access": "free",
"add_as_web_search": true,
"tags": [
"copilot",
"agents-md",
"instructions"
]
},
{
"name": "llms.txt",
"url": "https://llmstxt.org/",
"type": "specification",
"relevance": "Reference convention for publishing AI-readable summaries and deeper docs indexes.",
"update_frequency": "continuous",
"access": "free",
"add_as_web_search": true,
"tags": [
"llms",
"agent-readable",
"docs"
]
},
{
"name": "Model Context Protocol - Build a Server",
"url": "https://modelcontextprotocol.io/docs/develop/build-server",
"type": "documentation",
"relevance": "Primary protocol documentation for building MCP-backed documentation workflows and tooling.",
"update_frequency": "continuous",
"access": "free",
"add_as_web_search": true,
"tags": [
"mcp",
"protocol",
"docs"
]
}
],
"cross_platform_ai_standards": [
{
"name": "OpenAI AGENTS.md Guide",
"url": "https://developers.openai.com/codex/guides/agents-md",
"type": "documentation",
"relevance": "Official OpenAI guide for repo-wide and subdirectory AGENTS.md instruction files.",
"update_frequency": "continuous",
"access": "free",
"add_as_web_search": true,
"tags": [
"agents-md",
"codex",
"cross-platform"
]
},
{
"name": "OpenAI Codex Advanced Configuration",
"url": "https://developers.openai.com/codex/config-advanced/",
"type": "documentation",
"relevance": "Advanced Codex configuration, including AGENTS.md-related behavior and repo controls.",
"update_frequency": "continuous",
"access": "free",
"add_as_web_search": true,
"tags": [
"codex",
"configuration"
]
},
{
"name": "Claude Code Overview",
"url": "https://code.claude.com/docs/en/overview",
"type": "documentation",
"relevance": "Canonical Claude Code docs entry point for project-scoped behavior and repo workflows.",
"update_frequency": "continuous",
"access": "free",
"add_as_web_search": true,
"tags": [
"claude-code",
"overview"
]
},
{
"name": "Claude Code Best Practices",
"url": "https://code.claude.com/docs/en/best-practices",
"type": "documentation",
"relevance": "Official best practices for keeping Claude Code guidance concise, modular, and scoped.",
"update_frequency": "continuous",
"access": "free",
"add_as_web_search": true,
"tags": [
"claude-code",
"best-practices"
]
},
{
"name": "Claude Code Memory",
"url": "https://code.claude.com/docs/en/memory",
"type": "documentation",
"relevance": "Official documentation for CLAUDE.md memory behavior, imports, and project hierarchy.",
"update_frequency": "continuous",
"access": "free",
"add_as_web_search": true,
"tags": [
"claude-md",
"memory"
]
}
]
}
}
learnings.consolidated.md
# docs-codebase — Consolidated Learnings
Curated, dated, committed memory for this skill. Pruned from raw `learnings.md` via `agents-skills-feedback-loop/scripts/consolidate.py`. Human-approved.
Cap: 60 entries. When exceeded, promote durable rules to `references/`.
## Filter Override
<!-- Add 2-4 bullets that sharpen what counts as a learning for this skill. Leave empty to use the default filter from agents-skills-feedback-loop/references/learnings-format.md. -->
## Patterns That Work
## Mistakes to Avoid
## Domain Knowledge
## Open Questions
## Consolidated Principles
learnings.md
# docs-codebase — Learnings
## Patterns That Work
## Mistakes to Avoid
- [2026-07-11] CI/version examples (actions/checkout, setup-node, Node.js baseline) go stale within a year; re-check majors against upstream releases each audit, not just prose claims.
## Domain Knowledge
- [2026-07-11] OpenAPI 3.2.0 (Sep 2025) and AsyncAPI 3.1.0 verified still current as of July 2026; no OpenAPI 4.0/Moonwalk release yet.
## Open Questions
## Consolidated Principles
references/adr-writing-guide.md
# Architecture Decision Records (ADRs) - Writing Guide
Complete guide for documenting architectural and technical decisions using Architecture Decision Records (ADRs).
## Table of Contents
- [What Are ADRs?](#what-are-adrs)
- [ADR Structure](#adr-structure)
- [1. Title](#1-title)
- [2. Status](#2-status)
- [Status](#status)
- [3. Context](#3-context)
- [Context](#context)
- [4. Decision](#4-decision)
- [Decision](#decision)
- [5. Consequences](#5-consequences)
- [Consequences](#consequences)
- [Positive](#positive)
- [Negative](#negative)
- [Neutral](#neutral)
- [6. Alternatives Considered](#6-alternatives-considered)
- [Alternatives Considered](#alternatives-considered)
- [MySQL 8.0](#mysql-80)
- [MongoDB 6.0](#mongodb-60)
- [DynamoDB](#dynamodb)
- [7. Implementation (Optional)](#7-implementation-optional)
- [Implementation](#implementation)
- [Phase 1: Setup (Week 1)](#phase-1-setup-week-1)
- [Phase 2: Migration (Weeks 2-3)](#phase-2-migration-weeks-2-3)
- [Phase 3: Verification (Week 4)](#phase-3-verification-week-4)
- [8. References](#8-references)
- [References](#references)
- [Complete ADR Example](#complete-adr-example)
- [ADR-001: Use PostgreSQL for Primary Database](#adr-001-use-postgresql-for-primary-database)
- [Status](#status)
- [Context](#context)
- [Decision](#decision)
- [Consequences](#consequences)
- [Positive](#positive)
- [Negative](#negative)
- [Neutral](#neutral)
- [Alternatives Considered](#alternatives-considered)
- [MySQL 8.0](#mysql-80)
- [MongoDB 6.0](#mongodb-60)
- [DynamoDB](#dynamodb)
- [Implementation](#implementation)
- [Phase 1: Setup (Week 1)](#phase-1-setup-week-1)
- [Phase 2: Migration (Weeks 2-3)](#phase-2-migration-weeks-2-3)
- [Phase 3: Verification (Week 4)](#phase-3-verification-week-4)
- [References](#references)
- [ADR Naming Convention](#adr-naming-convention)
- [ADR Index (README)](#adr-index-readme)
- [Architecture Decision Records](#architecture-decision-records)
- [Active ADRs](#active-adrs)
- [Deprecated ADRs](#deprecated-adrs)
- [ADR Anti-Patterns](#adr-anti-patterns)
- [ADR Best Practices](#adr-best-practices)
- [ADR Tools](#adr-tools)
- [adr-tools](#adr-tools)
- [Create new ADR](#create-new-adr)
- [ADR Review Checklist](#adr-review-checklist)
- [Migration ADRs](#migration-adrs)
- [After-Action Reviews (January 2026 Best Practice)](#after-action-reviews-january-2026-best-practice)
- [1. Schedule the Review](#1-schedule-the-review)
- [After-Action Review](#after-action-review)
- [2. Review Questions](#2-review-questions)
- [3. Document Findings](#3-document-findings)
- [After-Action Review - 2026-01-22](#after-action-review-2026-01-22)
- [4. Readout Meeting Style](#4-readout-meeting-style)
- [When to Update ADRs](#when-to-update-adrs)
- [ADR Success Criteria](#adr-success-criteria)
## What Are ADRs?
**Architecture Decision Records** document important architectural decisions made during a project's lifecycle, including the context, decision, and consequences.
**Purpose**:
- Create searchable history of why decisions were made
- Onboard new team members quickly
- Prevent repeating past mistakes
- Document trade-offs and alternatives considered
**When to write an ADR**:
- [OK] Choosing a database technology
- [OK] Selecting a framework or library
- [OK] Architectural pattern changes (microservices, event-driven, etc.)
- [OK] Authentication/authorization approach
- [OK] Deployment strategy
- [OK] API design standards
- [OK] Testing strategy
- [FAIL] Minor refactoring (no ADR needed)
- [FAIL] Bug fixes (no ADR needed)
- [FAIL] Temporary workarounds (no ADR needed)
**ADR freshness rule**: For platform libraries and shared infrastructure, update ADRs in the same delivery cycle as runtime behavior changes. Stale ADRs are not a cosmetic problem — they change how future engineers and agents modify the code, potentially reintroducing bad assumptions that the behavior change was meant to fix.
## ADR Structure
Every ADR should follow this structure:
### 1. Title
**Format**: `ADR-NNN: [Verb] [Technology/Pattern] for [Purpose]`
**Examples**:
- `ADR-001: Use PostgreSQL for Primary Database`
- `ADR-002: Implement Event-Driven Architecture with Kafka`
- `ADR-003: Adopt TypeScript for Frontend Development`
- `ADR-004: Use JWT for API Authentication`
**Best practices**:
- Sequential numbering (001, 002, 003...)
- Action verb (Use, Implement, Adopt, Replace)
- Specific technology/pattern
- Clear purpose
### 2. Status
**Purpose**: Track the decision lifecycle.
**Valid statuses**:
- **Proposed** - Under discussion
- **Accepted** - Decision approved and active
- **Deprecated** - Still in use but being phased out
- **Superseded** - Replaced by another decision (link to new ADR)
- **Rejected** - Considered but not implemented
**Format**:
```markdown
## Status
Accepted
Date: 2025-11-22
```
**Status transitions**:
```
Proposed → Accepted → Deprecated → Superseded
↓
Rejected
```
### 3. Context
**Purpose**: Explain the problem, constraints, and requirements.
**What to include**:
- Problem statement
- Current situation
- Constraints (technical, business, time, budget)
- Requirements (functional and non-functional)
- Stakeholder concerns
**Format**:
```markdown
## Context
We need a primary database for our e-commerce platform that will:
- Handle 10,000+ transactions per day
- Support complex queries with joins
- Provide ACID guarantees for financial data
- Scale to 1TB+ of data over 3 years
- Work with our Node.js backend
**Constraints**:
- Team has limited DBA expertise
- Budget: $500/month for managed hosting
- Must deploy in 3 months
**Current situation**:
- Using SQLite for prototype
- SQLite cannot handle production load
- Need production-ready solution
```
**Best practices**:
- Be specific with numbers (users, transactions, data size)
- Include timeline constraints
- Mention team expertise/limitations
- Reference business requirements
### 4. Decision
**Purpose**: State what was decided clearly and concisely.
**Format**:
```markdown
## Decision
We will use PostgreSQL 14+ as our primary database.
**Implementation**:
- PostgreSQL 14.5 on managed AWS RDS
- Multi-AZ deployment for high availability
- Automated daily backups with 7-day retention
- Connection pooling with PgBouncer
```
**Best practices**:
- Start with declarative statement
- Include version numbers
- Specify deployment details
- Mention critical configuration
### 5. Consequences
**Purpose**: Document impacts (positive, negative, neutral).
**Format**:
```markdown
## Consequences
### Positive
- **ACID compliance** - Full transaction guarantees for financial data
- **Rich ecosystem** - Extensive tooling (pgAdmin, PostgREST, TimescaleDB)
- **JSON support** - Native JSONB for semi-structured data
- **Performance** - Excellent query optimizer for complex joins
- **Community** - Large community, extensive documentation
### Negative
- **Vertical scaling limitations** - Single-node writes limit scale
- **Operational complexity** - More complex than MongoDB for simple CRUD
- **Cost** - $400/month for managed RDS Multi-AZ
- **Learning curve** - Team needs to learn SQL optimization
### Neutral
- **Migration effort** - 2-3 weeks to migrate from SQLite
- **Backup strategy** - Need to implement point-in-time recovery
```
**Best practices**:
- Be honest about negatives
- Include costs (time, money, complexity)
- Quantify impacts where possible
- Consider long-term implications
### 6. Alternatives Considered
**Purpose**: Document options that were rejected and why.
**Format**:
```markdown
## Alternatives Considered
### MySQL 8.0
**Pros**:
- Similar to PostgreSQL in features
- Team has MySQL experience
- Slightly cheaper hosting
**Cons**:
- Weaker JSON support than PostgreSQL
- Oracle licensing concerns
- Less advanced query optimizer
**Why rejected**: PostgreSQL's superior JSON support and query optimizer outweigh familiarity with MySQL.
### MongoDB 6.0
**Pros**:
- Simpler schema-less design
- Horizontal scaling built-in
- Team has MongoDB experience
**Cons**:
- No ACID transactions across collections (until v4.0)
- Eventual consistency model risky for financial data
- Weak support for complex joins
**Why rejected**: Lack of strong ACID guarantees unacceptable for financial transactions.
### DynamoDB
**Pros**:
- Fully managed by AWS
- Excellent horizontal scaling
- Pay-per-use pricing
**Cons**:
- Vendor lock-in to AWS
- Complex query limitations
- Expensive for consistent workloads
- No joins or complex queries
**Why rejected**: Query limitations and vendor lock-in outweigh scaling benefits.
```
**Best practices**:
- Include at least 2-3 alternatives
- Be fair to alternatives (honest pros/cons)
- Explain rejection rationale clearly
- Consider similar complexity options
### 7. Implementation (Optional)
**Purpose**: Next steps and migration plan.
**Format**:
```markdown
## Implementation
### Phase 1: Setup (Week 1)
- [ ] Provision PostgreSQL RDS instance
- [ ] Configure security groups and VPC
- [ ] Set up PgBouncer connection pooling
- [ ] Configure automated backups
### Phase 2: Migration (Weeks 2-3)
- [ ] Create PostgreSQL schema from SQLite
- [ ] Write data migration scripts
- [ ] Test migration on staging environment
- [ ] Migrate production data (scheduled downtime)
### Phase 3: Verification (Week 4)
- [ ] Performance testing
- [ ] Data integrity validation
- [ ] Monitoring and alerting setup
- [ ] Documentation update
**Owner**: Backend team
**Target date**: 2025-12-15
```
### 8. References
**Purpose**: Link to relevant documentation and resources.
**Format**:
```markdown
## References
- PostgreSQL Documentation: https://www.postgresql.org/docs/
- AWS RDS Best Practices: https://docs.aws.amazon.com/rds/
- Internal database comparison spreadsheet: [Google Drive link]
- Slack discussion: #architecture channel, Nov 10-15
- Performance benchmarks: [Confluence link]
```
## Complete ADR Example
```markdown
# ADR-001: Use PostgreSQL for Primary Database
## Status
Accepted
Date: 2025-11-22
## Context
We need a primary database for our e-commerce platform that will:
- Handle 10,000+ transactions per day
- Support complex queries with joins (orders + products + users)
- Provide ACID guarantees for financial data
- Scale to 1TB+ of data over 3 years
- Work with our Node.js backend
**Constraints**:
- Team has limited DBA expertise
- Budget: $500/month for managed hosting
- Must deploy in 3 months
- Need high availability (99.9% uptime SLA)
**Current situation**:
- Using SQLite for prototype
- SQLite cannot handle production load (50 concurrent users)
- Need production-ready solution with automatic failover
## Decision
We will use PostgreSQL 14+ as our primary database.
**Implementation**:
- PostgreSQL 14.5 on managed AWS RDS
- Multi-AZ deployment for high availability
- db.t3.medium instance (2 vCPU, 4GB RAM)
- Automated daily backups with 7-day retention
- Connection pooling with PgBouncer (50 connections)
## Consequences
### Positive
- **ACID compliance** - Full transaction guarantees for financial data
- **Rich ecosystem** - Extensive tooling (pgAdmin, PostgREST, TimescaleDB)
- **JSON support** - Native JSONB for semi-structured data (product attributes)
- **Performance** - Excellent query optimizer for complex joins
- **Community** - Large community, extensive documentation, Stack Overflow support
### Negative
- **Vertical scaling limitations** - Single-node writes limit scale to ~10k writes/sec
- **Operational complexity** - More complex than MongoDB for simple CRUD
- **Cost** - $400/month for managed RDS Multi-AZ (within budget)
- **Learning curve** - Team needs to learn SQL optimization (2-week ramp-up)
### Neutral
- **Migration effort** - 2-3 weeks to migrate from SQLite (50k rows)
- **Backup strategy** - Need to implement point-in-time recovery (AWS RDS built-in)
## Alternatives Considered
### MySQL 8.0
**Pros**:
- Similar to PostgreSQL in features
- Team has MySQL experience (2 developers)
- Slightly cheaper hosting ($350/month)
**Cons**:
- Weaker JSON support than PostgreSQL (JSON vs JSONB)
- Oracle licensing concerns
- Less advanced query optimizer
**Why rejected**: PostgreSQL's superior JSON support and query optimizer outweigh familiarity with MySQL.
### MongoDB 6.0
**Pros**:
- Simpler schema-less design
- Horizontal scaling built-in (sharding)
- Team has MongoDB experience (1 developer)
**Cons**:
- No ACID transactions across collections (until v4.0)
- Eventual consistency model risky for financial data
- Weak support for complex joins (requires $lookup aggregation)
**Why rejected**: Lack of strong ACID guarantees unacceptable for financial transactions.
### DynamoDB
**Pros**:
- Fully managed by AWS (zero operational overhead)
- Excellent horizontal scaling (millions of requests/sec)
- Pay-per-use pricing (~$200/month for our workload)
**Cons**:
- Vendor lock-in to AWS
- Complex query limitations (no joins, limited filtering)
- Expensive for consistent workloads
- No complex queries or analytics
**Why rejected**: Query limitations and vendor lock-in outweigh scaling benefits. Analytics queries impossible.
## Implementation
### Phase 1: Setup (Week 1)
- [ ] Provision PostgreSQL RDS instance (db.t3.medium, Multi-AZ)
- [ ] Configure security groups and VPC (private subnet)
- [ ] Set up PgBouncer connection pooling (50 connections)
- [ ] Configure automated backups (daily, 7-day retention)
### Phase 2: Migration (Weeks 2-3)
- [ ] Create PostgreSQL schema from SQLite (using pg_dump equivalent)
- [ ] Write data migration scripts (Python with psycopg2)
- [ ] Test migration on staging environment (10k test records)
- [ ] Migrate production data (scheduled 2-hour downtime window)
### Phase 3: Verification (Week 4)
- [ ] Performance testing (10k concurrent users with k6)
- [ ] Data integrity validation (checksum comparison)
- [ ] Monitoring and alerting setup (CloudWatch + PagerDuty)
- [ ] Documentation update (runbooks, connection strings)
**Owner**: Backend team (John, Sarah)
**Target date**: 2025-12-15
**Estimated effort**: 80 hours
## References
- PostgreSQL Documentation: https://www.postgresql.org/docs/14/
- AWS RDS Best Practices: https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_BestPractices.html
- Internal database comparison spreadsheet: https://docs.google.com/spreadsheets/d/xyz
- Slack discussion: #architecture channel, Nov 10-15
- Performance benchmarks: https://confluence.internal/benchmarks
- ADR template: [Link to this template]
```
## ADR Naming Convention
**File naming**:
```
docs/adr/
├── 0001-use-postgresql-for-primary-database.md
├── 0002-implement-event-driven-architecture.md
├── 0003-adopt-typescript-for-frontend.md
└── README.md # Index of all ADRs
```
**Numbering**:
- Zero-padded (0001, 0002, not 1, 2)
- Sequential (no gaps)
- Never reuse numbers
## ADR Index (README)
Create an index in `docs/adr/README.md`:
```markdown
# Architecture Decision Records
## Active ADRs
| ADR | Title | Status | Date |
|-----|-------|--------|------|
| [0001](0001-use-postgresql-for-primary-database.md) | Use PostgreSQL for Primary Database | Accepted | 2025-11-22 |
| [0002](0002-implement-event-driven-architecture.md) | Implement Event-Driven Architecture | Accepted | 2025-11-25 |
## Deprecated ADRs
| ADR | Title | Status | Date | Superseded By |
|-----|-------|--------|------|---------------|
| [0003](0003-use-mongodb.md) | Use MongoDB for Sessions | Superseded | 2025-10-01 | ADR-0001 |
```
## ADR Anti-Patterns
**BAD: Avoid**:
- **No context** - Decision without explaining why
- **No alternatives** - Looks like no research was done
- **No consequences** - Ignoring trade-offs
- **Too vague** - "Use a database" instead of "Use PostgreSQL 14"
- **Too detailed** - Implementation code in ADR (link to PRs instead)
- **No date** - Can't track when decision was made
- **Retroactive ADRs** - Writing ADRs for old decisions (acceptable for critical legacy decisions)
## ADR Best Practices
**GOOD: Do**:
- Write ADRs when decision is made (not before, not after)
- Keep ADRs immutable (don't edit after acceptance)
- Supersede with new ADRs (don't delete old ADRs)
- Be specific with versions and dates
- Include quantitative data (numbers, metrics)
- Link to related ADRs
- Update index/README when adding ADRs
- Get team review before accepting
- Store ADRs in version control with code
## ADR Tools
**Generators**:
- `adr-tools` - CLI for creating/managing ADRs
- `log4brains` - ADR management with web UI
**Installation**:
```bash
# adr-tools
npm install -g adr-log
# Create new ADR
adr new "Use PostgreSQL for Primary Database"
```
**Templates**:
- [MADR](https://adr.github.io/madr/) - Markdown ADR format
- [Nygard ADRs](https://cognitect.com/blog/2011/11/15/documenting-architecture-decisions) - Original format
## ADR Review Checklist
Before accepting an ADR, verify:
- [ ] Title follows naming convention
- [ ] Status is set (Proposed/Accepted)
- [ ] Date is included
- [ ] Context explains the problem clearly
- [ ] Decision is specific (versions, technologies)
- [ ] Consequences include positives AND negatives
- [ ] At least 2-3 alternatives considered
- [ ] Alternatives have fair pros/cons
- [ ] References link to relevant docs
- [ ] File named with sequential number
- [ ] Index/README updated
## Migration ADRs
Migration ADRs document how to get from the current state to the target state, not just what the target state is. Use them when a decision includes phased rollout, coexistence, decommissioning, or regulated cutover work.
When writing migration ADRs:
- **Context** should include the current-state problems, what triggers the migration, and any compliance, contractual, or customer deadlines.
- **Decision** should name the target architecture and the proven patterns, packages, or workflows being reused from the current estate.
- **Alternatives** should include keeping the current state as an explicit option, with concrete downsides and risk acceptance.
- **Consequences** should separate positive outcomes, negative trade-offs, operational risks, and external dependencies.
- **Implementation** should define phase ordering, validation windows, rollback triggers, ownership, and exit criteria.
Migration ADR checklist:
- source and target systems named explicitly
- migration trigger and deadline stated
- keep-current-state alternative documented
- rollback and cutover criteria included
- dependencies and validation period called out
## After-Action Reviews (January 2026 Best Practice)
**Purpose**: Review each ADR one month after acceptance to compare documented expectations with actual outcomes.
**When to conduct**:
- 1 month after ADR acceptance (standard)
- After major milestone completion
- When unexpected issues arise related to the decision
**Review Process**:
### 1. Schedule the Review
```markdown
## After-Action Review
**ADR**: ADR-001: Use PostgreSQL for Primary Database
**Review Date**: 2026-01-22 (30 days after acceptance)
**Attendees**: Backend team, Tech Lead
```
### 2. Review Questions
Ask these questions during the review:
- Did the decision achieve its stated goals?
- Were there unexpected consequences (positive or negative)?
- Did the predicted costs and benefits materialize?
- Would we make the same decision today with current knowledge?
- What should we document for future similar decisions?
### 3. Document Findings
```markdown
### After-Action Review - 2026-01-22
**Goals Achieved**:
- [OK] ACID compliance working as expected for financial data
- [OK] Query performance meets requirements (avg 50ms)
- [PARTIAL] JSON support used less than expected
**Unexpected Consequences**:
- Positive: PgBouncer connection pooling reduced costs by 20%
- Negative: Backup restore took 4 hours (expected 1 hour)
**Lessons Learned**:
- Test backup restore procedures before production
- Consider read replicas earlier for reporting workloads
**Recommendation**: No changes to ADR status. Add backup testing to future ADR checklist.
```
### 4. Readout Meeting Style
AWS recommends a "readout meeting" approach:
1. Attendees spend 10-15 minutes reading the ADR silently
2. Written comments on sections requiring clarification
3. Discussion of differing opinions
4. Keep total participants under 10 people
**After-Action Review Checklist**:
- [ ] Review scheduled 30 days after acceptance
- [ ] Original decision-makers invited
- [ ] Affected teams represented
- [ ] Goals vs actuals documented
- [ ] Lessons learned captured
- [ ] ADR index updated if status changed
---
## When to Update ADRs
**Never edit** accepted ADRs. Instead:
1. **Status change**: Create new ADR that supersedes it
2. **New information**: Create new ADR referencing the old one
3. **Implementation details**: Update separate implementation docs
**Example**:
- ADR-001: Use PostgreSQL (Accepted) → Later becomes (Superseded by ADR-010)
- ADR-010: Migrate to CockroachDB (Accepted)
## ADR Success Criteria
**A good ADR enables readers to**:
1. [OK] Understand the problem and constraints
2. [OK] See what was decided and why
3. [OK] Know what alternatives were considered
4. [OK] Understand trade-offs and consequences
5. [OK] Find references for more context
6. [OK] Determine if decision is still valid
**Quality metrics**:
- Time to understand decision: < 5 minutes
- Completeness: All sections filled
- Clarity: No ambiguous statements
- Traceability: Links to discussions, docs, PRs
references/ai-documentation-tools.md
# AI Documentation Tools (March 2026)
Guide for choosing and using AI-aware documentation tools without overclaiming what automation can safely do.
---
## Table of Contents
- [What Changed in 2026](#what-changed-in-2026)
- [Tool Categories](#tool-categories)
- [Hosted Documentation Platforms](#hosted-documentation-platforms)
- [Docs Site Generators](#docs-site-generators)
- [Code-Aware Writing Assistants](#code-aware-writing-assistants)
- [AI-Readable Documentation](#ai-readable-documentation)
- [Minimum Standard](#minimum-standard)
- [`llms.txt` and `llms-full.txt`](#llmstxt-and-llms-fulltxt)
- [Instruction Files for Coding Assistants](#instruction-files-for-coding-assistants)
- [MCP for Documentation Workflows](#mcp-for-documentation-workflows)
- [What MCP Actually Enables](#what-mcp-actually-enables)
- [Typical Docs Workflow](#typical-docs-workflow)
- [Filesystem Server Pattern](#filesystem-server-pattern)
- [Tool Evaluation Checklist](#tool-evaluation-checklist)
- [For Any Documentation Platform](#for-any-documentation-platform)
- [For API Documentation Tools](#for-api-documentation-tools)
- [For AI Assistants in Docs Workflows](#for-ai-assistants-in-docs-workflows)
- [Recommended Adoption Path](#recommended-adoption-path)
- [Resources](#resources)
## What Changed in 2026
The strongest documentation workflows now combine:
- AI for draft generation and targeted review, not unsupervised publishing
- machine-readable delivery (`llms.txt`, `llms-full.txt`, stable URLs, predictable headings)
- platform-native instruction files (`AGENTS.md`, `CLAUDE.md`) for coding assistants
- documentation QA gates for links, style, spelling, contracts, and runnable examples
- MCP-backed context access when you need structured access to local docs, specs, tickets, or design systems
Avoid treating "AI docs" as a separate publishing channel. The goal is one canonical documentation set that is readable by humans and reliable for agents.
---
## Tool Categories
### Hosted Documentation Platforms
| Tool | Best For | Strengths | Watchouts |
|------|----------|-----------|-----------|
| **Mintlify** | Developer docs portals | Hosted DX, API docs, search, analytics | Verify current vendor-specific automation before scripting it |
| **ReadMe** | API and product docs | Interactive API reference, changelogs, metrics | Keep spec import and canonical Markdown ownership clear |
| **Apidog** | API teams that want design + testing + docs in one place | Spec, mocking, testing, docs | Avoid making the hosted portal your only source of truth |
### Docs Site Generators
| Tool | Best For | Strengths | Watchouts |
|------|----------|-----------|-----------|
| **VitePress** | Modern Markdown-first docs sites | Fast, simple, strong Markdown ergonomics, `llms.txt` support | Best when your team is comfortable with Node-based docs |
| **Astro Starlight** | Content-heavy product docs | Strong IA, Astro ecosystem, plugin flexibility | Confirm plugin choices early for search and analytics |
| **Docusaurus** | Large versioned docs portals | Mature ecosystem, versioning, React customization | Heavier setup and maintenance than VitePress |
| **MkDocs + Material** | Python and ops-oriented repos | Fast setup, solid search, familiar for infra teams | Less flexible than JS-site stacks for custom app-like docs |
### Code-Aware Writing Assistants
| Tool | Best For | Strengths | Watchouts |
|------|----------|-----------|-----------|
| **Claude Code** | Multi-file repo-aware writing and review | Strong repository context, project memory, imports via `CLAUDE.md` | Keep instructions scoped and current |
| **Codex / AGENTS.md-aware tools** | Repo-native implementation plus docs updates | `AGENTS.md` support, subdirectory scoping | Keep root and local instruction files consistent |
| **Cursor / GitHub Copilot** | Inline drafting inside IDEs | Fast edits and refactors near code | Requires stronger human review for repo-wide canonicalization |
---
## AI-Readable Documentation
### Minimum Standard
- Publish one canonical page per topic.
- Keep stable URLs and avoid duplicate near-identical pages.
- Start each page with a self-contained summary paragraph.
- Add `last_verified` on volatile vendor/platform pages.
- Keep examples complete, labeled, and runnable.
### `llms.txt` and `llms-full.txt`
Use these when your docs platform supports them directly or through a plugin.
- `llms.txt` should point agents to the best starting pages.
- `llms-full.txt` can provide a richer inventory or long-form extract for AI consumption.
- Do not dump every draft page into these files. Include only canonical pages that you would want an agent to trust.
### Instruction Files for Coding Assistants
- Use `AGENTS.md` for OpenAI/Codex-style tooling. Root files and closer subdirectory overrides both matter.
- Use `CLAUDE.md` or `.claude/CLAUDE.md` for Claude Code. Prefer `@path/to/import` for shared guidance instead of copy/paste duplication.
- Keep entry files thin. Put reusable policy or architecture context in shared docs and link or import it from the platform entry file.
---
## MCP for Documentation Workflows
### What MCP Actually Enables
MCP gives agents a structured way to reach tools and context. For docs work, that usually means:
- reading documentation trees or design-system files safely
- looking up API specs, schemas, tickets, dashboards, or runbooks
- validating examples against a live or mocked source of truth
- composing review workflows across code, docs, and external systems
MCP does **not** guarantee automatic synchronization. You still need explicit workflows, review steps, and ownership.
### Typical Docs Workflow
```text
Code/spec change
-> agent reads the affected docs, contracts, and issue context
-> agent proposes a docs diff
-> human reviews wording, scope, and examples
-> CI checks links, lint, contracts, and example validity
```
### Filesystem Server Pattern
Treat configuration as illustrative because server names and startup contracts evolve, but the official filesystem server package is now:
```json
{
"mcpServers": {
"docs-fs": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"./docs",
"."
]
}
}
}
```
Use allowlisted paths only. Give agents access to the smallest set of documentation and repo paths needed for the task.
---
## Tool Evaluation Checklist
### For Any Documentation Platform
- REQUIRED: Canonical source-of-truth workflow (`.md`, OpenAPI, AsyncAPI, or imported content) that fits your repo
- REQUIRED: Preview environments or equivalent review flow before publish
- REQUIRED: Search plus production analytics or query data
- REQUIRED: Link checking, spelling/style linting, and example validation in CI
- BEST: `llms.txt` or another explicit AI-readable export
- BEST: Stable edit URLs, page metadata, and last-updated / last-verified signals
### For API Documentation Tools
- REQUIRED: OpenAPI and/or AsyncAPI import that matches your stack
- REQUIRED: Good handling of auth flows, error models, and versioned changelogs
- BEST: SDK snippets, webhook/event docs, workflow docs, and contract linting
### For AI Assistants in Docs Workflows
- REQUIRED: Repo integration with reviewable diffs
- REQUIRED: Clear handling of confidential content, secrets, and PII
- BEST: Ability to work from specs/contracts instead of prose alone
- BEST: Support for modular instruction files instead of one monolithic prompt
---
## Recommended Adoption Path
1. Make your current docs canonical and trustworthy before adding more automation.
2. Add QA gates: links, style, spelling, contracts, and example checks.
3. Publish AI-readable outputs (`AGENTS.md`, `CLAUDE.md`, `llms.txt`) for the tools you actually use.
4. Introduce AI for drafting and review, starting with low-risk docs like changelogs, onboarding updates, and API examples.
5. Add MCP only when agents need structured access to specs, tickets, or external systems beyond the repo filesystem.
---
## Resources
- **llms.txt**: https://llmstxt.org/
- **Model Context Protocol**: https://modelcontextprotocol.io/docs/develop/build-server
- **OpenAI AGENTS.md Guide**: https://developers.openai.com/codex/guides/agents-md
- **Claude Code Memory**: https://code.claude.com/docs/en/memory
- **VitePress llms.txt Support**: https://vitepress.dev/guide/llms
- **Mintlify**: https://www.mintlify.com
- **ReadMe**: https://readme.com/
- **Apidog**: https://apidog.com/
---
> Success criteria: AI tools reduce drafting and review time while canonical docs remain human-owned, testable, and current.
references/api-documentation-standards.md
# API Documentation Standards
Comprehensive guide for documenting REST, AsyncAPI, GraphQL, gRPC, and API workflow specs with modern standards and tools.
## Table of Contents
- [Modern API Documentation Standards (March 2026)](#modern-api-documentation-standards-march-2026)
- [OpenAPI 3.2.0 Features (September 2025)](#openapi-320-features-september-2025)
- [Streaming Support](#streaming-support)
- [Tag Metadata (Replaces Vendor Extensions)](#tag-metadata-replaces-vendor-extensions)
- [Query Operations](#query-operations)
- [Migration Notes](#migration-notes)
- [Essential API Documentation Elements](#essential-api-documentation-elements)
- [REST API Documentation](#rest-api-documentation)
- [Authentication Section](#authentication-section)
- [Authentication](#authentication)
- [Getting a Token](#getting-a-token)
- [Using the Token](#using-the-token)
- [Token Expiration](#token-expiration)
- [Endpoint Documentation Template](#endpoint-documentation-template)
- [GET /api/v1/users/:id](#get-apiv1usersid)
- [Error Response Format (RFC 9457 Problem Details)](#error-response-format-rfc-9457-problem-details)
- [Rate Limiting](#rate-limiting)
- [Rate Limiting](#rate-limiting)
- [Pagination](#pagination)
- [Pagination](#pagination)
- [Pagination](#pagination)
- [Webhooks](#webhooks)
- [Webhooks](#webhooks)
- [GraphQL API Documentation](#graphql-api-documentation)
- [GraphQL API](#graphql-api)
- [Authentication](#authentication)
- [Schema Introspection](#schema-introspection)
- [Example Queries](#example-queries)
- [Get User](#get-user)
- [Create Order (Mutation)](#create-order-mutation)
- [Error Handling](#error-handling)
- [gRPC API Documentation](#grpc-api-documentation)
- [gRPC API](#grpc-api)
- [Protocol Buffers Definition](#protocol-buffers-definition)
- [Authentication](#authentication)
- [Example Calls](#example-calls)
- [Get User (Go)](#get-user-go)
- [OpenAPI 3.1 Specification](#openapi-31-specification)
- [Swagger UI](#swagger-ui)
- [Redoc](#redoc)
- [API Documentation Checklist](#api-documentation-checklist)
- [API Documentation Success Criteria](#api-documentation-success-criteria)
## Modern API Documentation Standards (March 2026)
**Key Standards**:
- **OpenAPI 3.2.0** (latest published OAS version) - Sequential media types, richer tag metadata, query and path improvements
- **OpenAPI 3.1.x** (widest current tooling support) - JSON Schema alignment, webhooks support
- **AsyncAPI 3.1.0** - Event-driven, streaming, and message-driven APIs
- **Arazzo 1.x** - Multi-step API workflows and task-oriented API guides
- **RFC 9457 Problem Details** - Current standard error model for HTTP APIs
- **GraphQL Schema** - Self-documenting with introspection
- **gRPC Protocol Buffers** - Type-safe service definitions
**Modern Tools**:
- **Interactive docs**: Swagger UI, Redoc, Stoplight, RapiDoc
- **Governance**: Redocly CLI, OpenAPI Generator, GraphQL Code Generator
- **AI-readable delivery**: Mintlify, ReadMe, VitePress, Starlight
- **Testing**: Postman, Insomnia, Thunder Client
---
## OpenAPI 3.2.0 Features (September 2025)
OpenAPI 3.2.0 adds useful improvements for streaming APIs and modern documentation workflows, but many teams should still publish 3.1.x until their renderer, linter, gateway, and SDK toolchain support 3.2.0 cleanly.
### Streaming Support
**New streaming capabilities**:
- **itemSchema**: Define schema for each item in sequential responses
- **itemEncoding**: Describe per-item encoding for sequential or multipart content
- **Sequential media types**: First-class support for formats such as `application/jsonl`, `application/json-seq`, and multipart streams
**Example - JSON Lines (`application/jsonl`)**:
```yaml
openapi: 3.2.0
paths:
/logs/stream:
get:
summary: Stream log entries
responses:
'200':
description: Log stream
content:
application/jsonl:
itemSchema:
$ref: '#/components/schemas/LogEntry'
```
**Example - item encoding for sequential payloads**:
```yaml
paths:
/events/stream:
get:
summary: Stream events
responses:
'200':
description: Event stream
content:
application/json-seq:
itemSchema:
$ref: '#/components/schemas/Event'
itemEncoding:
prefix: "\u001e"
```
### Tag Metadata (Replaces Vendor Extensions)
**New standardized tag fields**:
- **summary**: Brief description for navigation
- **parent**: Hierarchical tag organization
- **kind**: Tag category (resource, operation, domain)
```yaml
tags:
- name: users
summary: User management
kind: resource
description: Operations for creating, reading, updating, and deleting users
- name: users-admin
summary: Admin user operations
parent: users
kind: operation
```
### Query Operations
**New query-related features**:
- **additionalOperations**: Define custom operations beyond the standard HTTP method slots
- **querystring parameter location**: Explicitly document whole-querystring serialization when it matters
```yaml
paths:
/search:
query:
summary: Search across all resources
parameters:
- name: q
in: query
required: true
schema:
type: string
additionalOperations:
SUGGEST:
summary: Return query suggestions
responses:
'200':
description: Suggestion list
```
### Migration Notes
**Upgrading from 3.1.x**:
- Old vendor extensions (`x-summary`, `x-parent`) may still exist in downstream tooling, but prefer standard fields where 3.2.0 is supported
- Verify renderer, linter, gateway, and SDK support before switching production specs to 3.2.0
- Keep 3.1.x as the default publish target when 3.2.0 features are not materially needed
- Streaming payloads and custom operations usually need the most compatibility testing
## Essential API Documentation Elements
Every API documentation should include:
1. **Base URL** - API endpoint base
2. **Authentication** - How to authenticate (Bearer, API key, OAuth)
3. **Endpoints** - All available endpoints with:
- HTTP method and path
- Request parameters
- Request body schema
- Response format with examples
- Status codes
- cURL/code examples
4. **Error Responses** - Standard error format
5. **Rate Limiting** - Limits and rate limit headers
6. **Pagination** - Cursor-based or offset-based
7. **Webhooks** (if applicable) - Event types and payloads
8. **SDKs/Libraries** - Client libraries for different languages
9. **Changelog** - API version history
## REST API Documentation
### Authentication Section
**Purpose**: Explain how to authenticate API requests.
**Common methods**:
- Bearer tokens (JWT)
- API keys
- OAuth 2.0
- Basic authentication (not recommended for production)
**Example**:
```markdown
## Authentication
All API requests require authentication using a Bearer token.
### Getting a Token
**Request**:
```http
POST /api/v1/auth/login
Content-Type: application/json
{
"email": "user@example.com",
"password": "your-password"
}
```
**Response**:
```json
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"expiresIn": 3600
}
```
### Using the Token
Include the token in the `Authorization` header:
```http
GET /api/v1/users
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
```
### Token Expiration
- Tokens expire after 1 hour (3600 seconds)
- Refresh tokens valid for 7 days
- Use `/auth/refresh` endpoint to renew tokens
```
### Endpoint Documentation Template
**For each endpoint, document**:
```markdown
### GET /api/v1/users/:id
Get a user by ID.
**Path Parameters**:
| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `id` | string (UUID) | Yes | User unique identifier |
**Query Parameters**:
| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `include` | string | No | - | Comma-separated related resources (e.g., `orders,payments`) |
| `fields` | string | No | All fields | Comma-separated fields to return (e.g., `email,name`) |
**Request Headers**:
```http
GET /api/v1/users/123e4567-e89b-12d3-a456-426614174000?include=orders
Authorization: Bearer YOUR_ACCESS_TOKEN
Accept: application/json
```
**Response (200 OK)**:
```json
{
"data": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"email": "user@example.com",
"name": "John Doe",
"createdAt": "2025-11-22T10:30:00Z",
"orders": [
{
"id": "order-001",
"total": 99.99,
"status": "completed"
}
]
}
}
```
**Error Responses**:
| Status Code | Description | Response |
|-------------|-------------|----------|
| 400 Bad Request | Invalid UUID format | `{"type":"https://api.example.com/problems/invalid-id","title":"Invalid ID","status":400,"detail":"Invalid user ID format"}` |
| 401 Unauthorized | Missing or invalid token | `{"type":"https://api.example.com/problems/unauthorized","title":"Unauthorized","status":401,"detail":"Invalid authentication token"}` |
| 404 Not Found | User not found | `{"type":"https://api.example.com/problems/not-found","title":"Not found","status":404,"detail":"User not found"}` |
| 429 Too Many Requests | Rate limit exceeded | `{"type":"https://api.example.com/problems/rate-limit-exceeded","title":"Rate limit exceeded","status":429,"detail":"Too many requests"}` |
**Rate Limit**: 1000 requests per hour per user
**Example cURL**:
```bash
curl -X GET \
https://api.example.com/v1/users/123e4567-e89b-12d3-a456-426614174000 \
-H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
-H 'Accept: application/json'
```
**Example JavaScript**:
```javascript
const response = await fetch('https://api.example.com/v1/users/123e4567-e89b-12d3-a456-426614174000', {
headers: {
'Authorization': `Bearer ${token}`,
'Accept': 'application/json'
}
});
const user = await response.json();
console.log(user.data);
```
**Example Python**:
```python
import requests
headers = {
'Authorization': f'Bearer {token}',
'Accept': 'application/json'
}
response = requests.get(
'https://api.example.com/v1/users/123e4567-e89b-12d3-a456-426614174000',
headers=headers
)
user = response.json()
print(user['data'])
```
```
### Error Response Format (RFC 9457 Problem Details)
**Standard error format**:
```json
{
"type": "https://api.example.com/problems/validation-error",
"title": "Validation error",
"status": 422,
"detail": "Request validation failed",
"instance": "/api/v1/users",
"request_id": "req_abc123xyz",
"timestamp": "2026-03-13T10:30:00Z",
"errors": [
{
"field": "email",
"message": "Invalid email format",
"value": "not-an-email"
}
]
}
```
Use the standard Problem Details members (`type`, `title`, `status`, `detail`, `instance`) and add extension members only where they materially help clients, for example `errors`, `request_id`, or `timestamp`.
**Common problem types**:
- `validation-error` - Request validation failed
- `authentication-error` - Authentication failed
- `authorization-error` - Insufficient permissions
- `not-found` - Resource not found
- `conflict` - Resource conflict (duplicate)
- `rate-limit-exceeded` - Too many requests
- `internal-error` - Server error
### Rate Limiting
**Document**:
- Limit (requests per time period)
- Time window
- Rate limit headers
- Behavior when limit exceeded
**Example**:
```markdown
## Rate Limiting
All endpoints are rate-limited to prevent abuse.
**Limits**:
- **Authenticated users**: 1000 requests per hour
- **Unauthenticated users**: 100 requests per hour
**Rate Limit Headers**:
Every response includes rate limit information:
```http
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 987
X-RateLimit-Reset: 1700654400
```
| Header | Description |
|--------|-------------|
| `X-RateLimit-Limit` | Total requests allowed per hour |
| `X-RateLimit-Remaining` | Requests remaining in current window |
| `X-RateLimit-Reset` | Unix timestamp when limit resets |
**Rate Limit Exceeded (429)**:
```json
{
"type": "https://api.example.com/problems/rate-limit-exceeded",
"title": "Rate limit exceeded",
"status": 429,
"detail": "Rate limit exceeded. Try again in 300 seconds.",
"retry_after": 300
}
```
**Best Practices**:
- Monitor `X-RateLimit-Remaining` header
- Implement exponential backoff when rate limited
- Cache responses when possible to reduce API calls
```
### Pagination
**Cursor-based pagination (recommended)**:
```markdown
## Pagination
All list endpoints support cursor-based pagination for consistent results.
**Query Parameters**:
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `cursor` | string | - | Pagination cursor from previous response |
| `limit` | integer | 20 | Items per page (max: 100) |
**Request**:
```http
GET /api/v1/users?limit=20
```
**Response**:
```json
{
"data": [
{ "id": "user-1", "name": "John" },
{ "id": "user-2", "name": "Jane" }
],
"pagination": {
"cursor": "eyJpZCI6InVzZXItMjAifQ==",
"hasMore": true,
"total": 150
}
}
```
**Next Page**:
```http
GET /api/v1/users?cursor=eyJpZCI6InVzZXItMjAifQ==&limit=20
```
**Benefits**:
- Consistent results (no missing/duplicate items)
- Works with real-time data
- Better performance than offset pagination
```
**Offset-based pagination (simpler but less reliable)**:
```markdown
## Pagination
**Query Parameters**:
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `page` | integer | 1 | Page number (1-indexed) |
| `perPage` | integer | 20 | Items per page (max: 100) |
**Response**:
```json
{
"data": [...],
"meta": {
"page": 1,
"perPage": 20,
"total": 150,
"totalPages": 8
}
}
```
```
### Webhooks
**Document webhook events and payloads**:
```markdown
## Webhooks
Subscribe to events by configuring webhook endpoints in your account settings.
**Supported Events**:
| Event | Description | Payload |
|-------|-------------|---------|
| `user.created` | New user registered | `User` object |
| `order.completed` | Order completed | `Order` object |
| `payment.succeeded` | Payment successful | `Payment` object |
| `payment.failed` | Payment failed | `Payment` object with error |
**Webhook Payload Format**:
```json
{
"event": "order.completed",
"timestamp": "2025-11-22T10:30:00Z",
"data": {
"id": "order-123",
"userId": "user-456",
"total": 99.99,
"status": "completed"
},
"webhookId": "wh_abc123"
}
```
**Webhook Signature Verification**:
All webhooks include an `X-Webhook-Signature` header for verification:
```javascript
const crypto = require('crypto');
function verifyWebhook(payload, signature, secret) {
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return signature === expectedSignature;
}
```
**Retry Policy**:
- Failed webhooks retry with exponential backoff
- Retries: immediately, 5 min, 1 hour, 6 hours, 24 hours
- After 5 failures, webhook is disabled
```
## GraphQL API Documentation
**GraphQL benefits**: Self-documenting through introspection.
**Example documentation**:
```markdown
# GraphQL API
**Endpoint**: `https://api.example.com/graphql`
## Authentication
Include Bearer token in Authorization header:
```http
POST /graphql
Authorization: Bearer YOUR_ACCESS_TOKEN
Content-Type: application/json
```
## Schema Introspection
Explore the full schema using GraphQL Playground or GraphiQL:
- **GraphQL Playground**: https://api.example.com/graphql
- **Schema docs**: Auto-generated from schema
## Example Queries
### Get User
```graphql
query GetUser($id: ID!) {
user(id: $id) {
id
email
name
orders {
id
total
status
}
}
}
```
**Variables**:
```json
{
"id": "user-123"
}
```
**Response**:
```json
{
"data": {
"user": {
"id": "user-123",
"email": "user@example.com",
"name": "John Doe",
"orders": [...]
}
}
}
```
### Create Order (Mutation)
```graphql
mutation CreateOrder($input: CreateOrderInput!) {
createOrder(input: $input) {
id
total
status
}
}
```
**Variables**:
```json
{
"input": {
"userId": "user-123",
"items": [
{ "productId": "prod-456", "quantity": 2 }
]
}
}
```
## Error Handling
GraphQL returns errors in `errors` array:
```json
{
"errors": [
{
"message": "User not found",
"extensions": {
"code": "NOT_FOUND",
"userId": "user-999"
}
}
],
"data": null
}
```
```
## gRPC API Documentation
**gRPC**: Define services in Protocol Buffers (.proto files).
**Example documentation**:
```markdown
# gRPC API
**Server**: `api.example.com:50051`
## Protocol Buffers Definition
```protobuf
syntax = "proto3";
package user.v1;
service UserService {
rpc GetUser (GetUserRequest) returns (User) {}
rpc ListUsers (ListUsersRequest) returns (ListUsersResponse) {}
rpc CreateUser (CreateUserRequest) returns (User) {}
}
message User {
string id = 1;
string email = 2;
string name = 3;
int64 created_at = 4;
}
message GetUserRequest {
string id = 1;
}
message ListUsersRequest {
int32 page_size = 1;
string page_token = 2;
}
message ListUsersResponse {
repeated User users = 1;
string next_page_token = 2;
}
```
## Authentication
Use gRPC metadata to pass authentication:
```javascript
const metadata = new grpc.Metadata();
metadata.add('authorization', `Bearer ${token}`);
client.getUser({ id: 'user-123' }, metadata, callback);
```
## Example Calls
### Get User (Go)
```go
import (
pb "path/to/proto/user/v1"
"google.golang.org/grpc"
)
conn, _ := grpc.Dial("api.example.com:50051", grpc.WithInsecure())
client := pb.NewUserServiceClient(conn)
user, err := client.GetUser(ctx, &pb.GetUserRequest{
Id: "user-123",
})
```
```
## OpenAPI 3.1 Specification
**Use OpenAPI for REST APIs**:
```yaml
openapi: 3.1.0
info:
title: Example API
version: 1.0.0
description: API for managing users and orders
servers:
- url: https://api.example.com/v1
description: Production server
security:
- bearerAuth: []
paths:
/users/{id}:
get:
summary: Get user by ID
parameters:
- name: id
in: path
required: true
schema:
type: string
format: uuid
responses:
'200':
description: User found
content:
application/json:
schema:
$ref: '#/components/schemas/User'
'404':
description: User not found
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
schemas:
User:
type: object
properties:
id:
type: string
format: uuid
email:
type: string
format: email
name:
type: string
```
**Generate interactive docs**:
```bash
# Swagger UI
npx @redocly/cli preview-docs openapi.yaml
# Redoc
npx @redocly/cli build-docs openapi.yaml
```
## API Documentation Checklist
**Before publishing API docs**:
- [ ] All endpoints documented
- [ ] Authentication explained with examples
- [ ] Request/response schemas complete
- [ ] Error responses documented
- [ ] Rate limiting explained
- [ ] Pagination documented
- [ ] Code examples in 2-3 languages
- [ ] cURL examples for all endpoints
- [ ] Webhooks documented (if applicable)
- [ ] Changelog included
- [ ] Interactive docs available (Swagger/Redoc)
- [ ] SDKs listed with links
- [ ] Versioning strategy explained
- [ ] Deprecation notices added
- [ ] Contact/support information included
## API Documentation Success Criteria
**Great API documentation enables developers to**:
1. [OK] Authenticate successfully in < 5 minutes
2. [OK] Make first API call in < 10 minutes
3. [OK] Find all endpoints and parameters
4. [OK] Understand error responses
5. [OK] Copy-paste working code examples
6. [OK] Handle rate limits appropriately
7. [OK] Implement webhooks correctly
**Quality metrics**:
- Time to first successful API call: < 10 minutes
- Support questions about authentication: < 5%
- Completeness: All endpoints documented
- Code examples: 3+ languages
- Error clarity: All status codes explained
references/backlog-status-sync-pattern.md
# Backlog Status Sync Pattern
Use this pattern to keep implementation status accurate across canonical documentation after feature delivery waves.
## Canonical-First Model
1. Choose one canonical status source (for example feature matrix or roadmap doc).
2. Apply status update there first with date + owner.
3. Update dependent docs by linking to canonical source instead of duplicating status text.
## Required Metadata for Temporary Reports
Include in dated report files:
- `Status`: `pending-integration | integrated | superseded`
- `Integrates-into`: canonical path
- `Owner`
- `Delete-by`
## Sync Audit Steps
- grep for stale status phrases in docs
- reconcile conflicts against canonical source
- verify moved paths, renamed files, and canonical links after restructures
- re-count filesystem-backed totals when docs mention file counts, repo counts, or matrix dimensions
- check `full inventory` and `complete map` claims against source-of-truth artifacts
- label partial examples as examples instead of full coverage
- mark integrated reports and schedule deletion
## Failure Modes Prevented
- docs claiming old backlog state after implementation
- duplicate contradictory status statements in multiple files
- LLM agents consuming stale report snapshots as truth
references/changelog-best-practices.md
# Changelog Best Practices
Comprehensive guide for maintaining changelogs using the "Keep a Changelog" format and semantic versioning.
## Table of Contents
- [What Is a Changelog?](#what-is-a-changelog)
- [Keep a Changelog Format](#keep-a-changelog-format)
- [Basic Structure](#basic-structure)
- [Changelog](#changelog)
- [[Unreleased]](#unreleased)
- [Added](#added)
- [[1.2.0] - 2025-11-22](#120-2025-11-22)
- [Added](#added)
- [Changed](#changed)
- [Deprecated](#deprecated)
- [Removed](#removed)
- [Fixed](#fixed)
- [Security](#security)
- [[1.1.0] - 2025-10-15](#110-2025-10-15)
- [Change Categories](#change-categories)
- [Added](#added)
- [Added](#added)
- [Changed](#changed)
- [Changed](#changed)
- [Deprecated](#deprecated)
- [Deprecated](#deprecated)
- [Removed](#removed)
- [Removed](#removed)
- [Fixed](#fixed)
- [Fixed](#fixed)
- [Security](#security)
- [Security](#security)
- [Version Numbering (Semantic Versioning)](#version-numbering-semantic-versioning)
- [MAJOR (Breaking Changes)](#major-breaking-changes)
- [[2.0.0] - 2025-11-22](#200-2025-11-22)
- [Removed](#removed)
- [Changed](#changed)
- [MINOR (New Features)](#minor-new-features)
- [[1.3.0] - 2025-11-22](#130-2025-11-22)
- [Added](#added)
- [PATCH (Bug Fixes)](#patch-bug-fixes)
- [[1.2.1] - 2025-11-22](#121-2025-11-22)
- [Fixed](#fixed)
- [Security](#security)
- [Complete Changelog Example](#complete-changelog-example)
- [Changelog](#changelog)
- [[Unreleased]](#unreleased)
- [Added](#added)
- [Changed](#changed)
- [[1.2.0] - 2025-11-22](#120-2025-11-22)
- [Added](#added)
- [Changed](#changed)
- [Deprecated](#deprecated)
- [Fixed](#fixed)
- [Security](#security)
- [[1.1.0] - 2025-10-15](#110-2025-10-15)
- [Added](#added)
- [Changed](#changed)
- [Fixed](#fixed)
- [[1.0.0] - 2025-09-01](#100-2025-09-01)
- [Added](#added)
- [Unreleased Section](#unreleased-section)
- [[Unreleased]](#unreleased)
- [Added](#added)
- [Fixed](#fixed)
- [[Unreleased]](#unreleased)
- [Added](#added)
- [[Unreleased]](#unreleased)
- [[1.3.0] - 2025-11-22](#130-2025-11-22)
- [Added](#added)
- [Linking to Commits](#linking-to-commits)
- [Changelog Anti-Patterns](#changelog-anti-patterns)
- [Changed](#changed)
- [Changed](#changed)
- [Fixed](#fixed)
- [Fixed](#fixed)
- [[1.2.0] ← Missing date](#120-←-missing-date)
- [[1.2.0] - 2025-11-22](#120-2025-11-22)
- [Automated Changelog Generation](#automated-changelog-generation)
- [semantic-release](#semantic-release)
- [standard-version](#standard-version)
- [Writing Style Guidelines](#writing-style-guidelines)
- [Audience](#audience)
- [Tone](#tone)
- [Format](#format)
- [Added](#added)
- [Added](#added)
- [Breaking Changes](#breaking-changes)
- [[2.0.0] - 2025-11-22 - BREAKING CHANGES](#200-2025-11-22-breaking-changes)
- [Removed](#removed)
- [Changed](#changed)
- [Changelog Maintenance Checklist](#changelog-maintenance-checklist)
- [Tools for Changelog Management](#tools-for-changelog-management)
- [Verify CHANGELOG.md was updated](#verify-changelogmd-was-updated)
- [Examples of Great Changelogs](#examples-of-great-changelogs)
- [Changelog Success Criteria](#changelog-success-criteria)
## What Is a Changelog?
A **changelog** is a file documenting all notable changes made to a project in chronological order.
**Purpose**:
- Help users understand what changed between versions
- Communicate breaking changes clearly
- Show project activity and maintenance status
- Enable informed upgrade decisions
**Standard**: [Keep a Changelog](https://keepachangelog.com/) v1.1.0
## Keep a Changelog Format
### Basic Structure
```markdown
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Added
- New features that are not yet released
## [1.2.0] - 2025-11-22
### Added
- Feature descriptions
### Changed
- Changes to existing functionality
### Deprecated
- Features marked for removal in future versions
### Removed
- Features removed in this version
### Fixed
- Bug fixes
### Security
- Security vulnerability patches
## [1.1.0] - 2025-10-15
...
[Unreleased]: https://github.com/user/repo/compare/v1.2.0...HEAD
[1.2.0]: https://github.com/user/repo/compare/v1.1.0...v1.2.0
[1.1.0]: https://github.com/user/repo/compare/v1.0.0...v1.1.0
```
## Change Categories
### Added
**Purpose**: New features or capabilities.
**Examples**:
```markdown
### Added
- OAuth2 authentication with Google and GitHub providers
- Rate limiting with Redis (100 requests per minute per user)
- Webhook support for order completion events
- Export functionality for user reports (CSV and JSON formats)
- Dark mode toggle in user settings
```
**Best practices**:
- Start with verb (passive voice acceptable)
- Be specific about what was added
- Include relevant details (providers, formats, limits)
### Changed
**Purpose**: Changes to existing functionality.
**Examples**:
```markdown
### Changed
- Improved search performance by 60% using Elasticsearch
- Updated Node.js requirement from 16+ to 18+
- Changed default pagination limit from 10 to 20 items
- Refactored authentication flow for better security
- Updated UI design to match new brand guidelines
```
**Best practices**:
- Explain the change clearly
- Include performance improvements with metrics
- Mention requirement changes
- Note visual/UX changes
### Deprecated
**Purpose**: Features that will be removed in future versions.
**Examples**:
```markdown
### Deprecated
- Legacy API v1 endpoints (will be removed in v2.0.0)
- Use API v2 endpoints instead: `/api/v2/users`
- `getUserData()` function (use `fetchUserProfile()` instead)
- XML response format (JSON is now the standard)
- Support for Node.js 14 (end-of-life 2023-04-30)
```
**Best practices**:
- State removal timeline
- Provide migration path/alternative
- Explain reason for deprecation
### Removed
**Purpose**: Features removed in this version.
**Examples**:
```markdown
### Removed
- API v1 endpoints (deprecated in v1.5.0)
- Internet Explorer 11 support
- Legacy authentication using session cookies
- `/legacy-api/*` routes
- Deprecated `config.old.json` format
```
**Best practices**:
- Reference when it was deprecated
- Keep brief (removal was communicated in deprecation)
- List breaking changes prominently
### Fixed
**Purpose**: Bug fixes.
**Examples**:
```markdown
### Fixed
- Memory leak in WebSocket connections (#456)
- Race condition in order processing queue (#789)
- Incorrect timezone handling in date picker (#321)
- XSS vulnerability in comment rendering (CVE-2025-12345)
- 404 error when navigating to user profiles with special characters
```
**Best practices**:
- Link to issue numbers
- Describe the bug clearly
- Include CVE numbers for security fixes
- Mention user-facing impact
### Security
**Purpose**: Security vulnerability patches.
**Examples**:
```markdown
### Security
- Updated jsonwebtoken to 9.0.0 (CVE-2022-23529)
- Fixed SQL injection vulnerability in search endpoint (CVSS 8.1)
- Patched XSS vulnerability in markdown renderer (CVE-2025-1234)
- Upgraded axios to 1.6.0 to fix SSRF vulnerability
- Added rate limiting to prevent brute-force attacks on login
```
**Best practices**:
- **Always list security fixes** in a dedicated section
- Include CVE numbers if assigned
- Include CVSS scores for severity
- Link to security advisories
- Don't expose exploit details
## Version Numbering (Semantic Versioning)
**Format**: `MAJOR.MINOR.PATCH`
### MAJOR (Breaking Changes)
Increment when making incompatible API changes.
**Examples**:
- Removing deprecated endpoints
- Changing function signatures
- Changing response formats
- Removing configuration options
- Requiring new dependencies
**Changelog entry**:
```markdown
## [2.0.0] - 2025-11-22
### Removed
- API v1 endpoints (use v2 instead)
### Changed
- `createUser()` now returns Promise instead of callback
- Changed response format from XML to JSON
```
### MINOR (New Features)
Increment when adding functionality in a backward-compatible manner.
**Examples**:
- Adding new endpoints
- Adding optional parameters
- Adding new features
- Extending functionality
**Changelog entry**:
```markdown
## [1.3.0] - 2025-11-22
### Added
- OAuth2 authentication support
- Export to PDF functionality
- GraphQL API endpoint
```
### PATCH (Bug Fixes)
Increment when making backward-compatible bug fixes.
**Examples**:
- Fixing bugs
- Security patches
- Performance improvements
- Documentation updates
**Changelog entry**:
```markdown
## [1.2.1] - 2025-11-22
### Fixed
- Memory leak in connection pooling (#234)
- Incorrect date formatting in exports
### Security
- Updated dependencies to patch vulnerabilities
```
## Complete Changelog Example
```markdown
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
### Added
- Bulk user import from CSV files
- Email notifications for order status changes
### Changed
- Improved dashboard loading time by 40%
## [1.2.0] - 2025-11-22
### Added
- OAuth2 authentication with Google and GitHub (#123)
- Rate limiting with Redis: 100 requests per minute per user (#145)
- Webhook support for `order.completed` and `user.created` events (#167)
- Export user reports in CSV and JSON formats (#189)
- Dark mode toggle in user settings (#201)
### Changed
- Improved search performance by 60% using Elasticsearch instead of PostgreSQL full-text search (#134)
- Updated minimum Node.js version from 16.x to 18.x (#156)
- Changed default pagination limit from 10 to 20 items per page (#178)
- Refactored authentication flow to use JWT instead of sessions (#192)
### Deprecated
- Legacy API v1 endpoints under `/api/v1/*` (will be removed in v2.0.0)
- Migrate to `/api/v2/*` endpoints
- See migration guide: [MIGRATION.md](MIGRATION.md)
### Fixed
- Memory leak in WebSocket connections after 24 hours of runtime (#456)
- Race condition in order processing queue causing duplicate charges (#489)
- Incorrect timezone handling in date picker component (#321)
- 404 error when navigating to user profiles with special characters (#367)
### Security
- Updated jsonwebtoken from 8.5.1 to 9.0.0 (CVE-2022-23529, CVSS 7.5)
- Fixed SQL injection vulnerability in search endpoint (CVE-2025-1234, CVSS 8.1)
- Patched XSS vulnerability in markdown renderer (CVE-2025-5678)
- Upgraded axios to 1.6.0 to fix SSRF vulnerability
## [1.1.0] - 2025-10-15
### Added
- Two-factor authentication (2FA) with TOTP (#98)
- User profile customization options (#112)
- Admin dashboard for user management (#134)
### Changed
- Migrated from JavaScript to TypeScript (#87)
- Updated UI design to match new brand guidelines (#101)
### Fixed
- Email verification links expiring too quickly (#76)
- Pagination breaking on last page (#89)
## [1.0.0] - 2025-09-01
### Added
- Initial release
- User authentication and registration
- Product catalog with search
- Shopping cart functionality
- Stripe payment integration
- Order management system
- Admin panel
- Email notifications
[Unreleased]: https://github.com/user/repo/compare/v1.2.0...HEAD
[1.2.0]: https://github.com/user/repo/compare/v1.1.0...v1.2.0
[1.1.0]: https://github.com/user/repo/compare/v1.0.0...v1.1.0
[1.0.0]: https://github.com/user/repo/releases/tag/v1.0.0
```
## Unreleased Section
**Purpose**: Track upcoming changes before release.
**Usage**:
```markdown
## [Unreleased]
### Added
- Feature X that will be in next release
### Fixed
- Bug Y that will be in next release
```
**When releasing**:
1. Create new version section
2. Move Unreleased items to version section
3. Add release date
4. Clear Unreleased section
**Example transformation**:
**Before release**:
```markdown
## [Unreleased]
### Added
- Dark mode support
```
**After 1.3.0 release**:
```markdown
## [Unreleased]
## [1.3.0] - 2025-11-22
### Added
- Dark mode support
```
## Linking to Commits
**At the bottom of CHANGELOG.md**:
```markdown
[Unreleased]: https://github.com/user/repo/compare/v1.2.0...HEAD
[1.2.0]: https://github.com/user/repo/compare/v1.1.0...v1.2.0
[1.1.0]: https://github.com/user/repo/compare/v1.0.0...v1.1.0
[1.0.0]: https://github.com/user/repo/releases/tag/v1.0.0
```
**Benefits**:
- Click version to see all changes on GitHub
- Visual diff between versions
- Traceability to commits
## Changelog Anti-Patterns
**BAD: Avoid**:
**Commit dumps**:
```markdown
### Changed
- Fixed typo
- Updated package.json
- Refactored code
- Fixed bug
- Updated README
```
Instead, group related changes:
```markdown
### Changed
- Improved user authentication security
- Implemented rate limiting
- Added 2FA support
- Fixed session timeout bug
```
**Vague entries**:
```markdown
### Fixed
- Fixed bugs
- Performance improvements
- Various updates
```
Instead, be specific:
```markdown
### Fixed
- Memory leak in WebSocket connections (#456)
- Search performance improved by 60%
```
**No dates**:
```markdown
## [1.2.0] ← Missing date
```
Instead:
```markdown
## [1.2.0] - 2025-11-22
```
**Missing links**:
```markdown
[1.2.0]: Missing
```
Instead:
```markdown
[1.2.0]: https://github.com/user/repo/compare/v1.1.0...v1.2.0
```
## Automated Changelog Generation
### semantic-release
**Installation**:
```bash
npm install --save-dev semantic-release
```
**Configuration** (`.releaserc.json`):
```json
{
"branches": ["main"],
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/changelog",
"@semantic-release/npm",
"@semantic-release/github",
"@semantic-release/git"
]
}
```
**Commit format** (Conventional Commits):
```
feat: add OAuth2 authentication
fix: resolve memory leak in WebSocket
docs: update API documentation
chore: upgrade dependencies
```
### standard-version
**Installation**:
```bash
npm install --save-dev standard-version
```
**Usage**:
```bash
npm run release
```
**What it does**:
1. Bumps version in `package.json`
2. Generates/updates `CHANGELOG.md`
3. Creates git tag
4. Commits changes
## Writing Style Guidelines
### Audience
Write for:
- Users upgrading to new version
- Developers integrating your library
- Product managers tracking features
### Tone
- **Clear and concise** - No marketing fluff
- **Technical but accessible** - Avoid jargon when possible
- **Action-oriented** - Start with verbs
- **User-focused** - Explain impact on users
### Format
**Good**:
```markdown
### Added
- OAuth2 authentication with Google and GitHub providers
- Rate limiting: 100 requests per minute per user (configurable)
```
**Bad**:
```markdown
### Added
- We've added the amazing new feature of OAuth2! Now you can log in with Google or GitHub!
```
### Breaking Changes
**Always highlight breaking changes prominently**:
```markdown
## [2.0.0] - 2025-11-22 - BREAKING CHANGES
### Removed
- [WARNING] **BREAKING**: API v1 endpoints removed (use v2 instead)
- [WARNING] **BREAKING**: Node.js 14 support dropped (requires 18+)
### Changed
- [WARNING] **BREAKING**: `createUser()` signature changed
- **Old**: `createUser(name, email, callback)`
- **New**: `createUser({ name, email }): Promise<User>`
```
## Changelog Maintenance Checklist
**When releasing**:
- [ ] Move Unreleased items to new version section
- [ ] Add release date in YYYY-MM-DD format
- [ ] Update version number (semantic versioning)
- [ ] Add comparison link at bottom
- [ ] Update Unreleased link
- [ ] Verify all issue/PR links work
- [ ] Check for typos and formatting
- [ ] Highlight breaking changes
- [ ] Include migration guide link if needed
- [ ] Tag release in Git
## Tools for Changelog Management
**Generators**:
- `semantic-release` - Automated versioning and changelog
- `standard-version` - Conventional Commits to changelog
- `auto-changelog` - Generate from Git history
- `conventional-changelog` - Changelog from commits
**Validators**:
- `changelogithub` - Validate changelog format
- Custom CI scripts to enforce format
**Example CI check**:
```bash
# Verify CHANGELOG.md was updated
git diff --name-only HEAD~1 | grep CHANGELOG.md || {
echo "Error: CHANGELOG.md not updated"
exit 1
}
```
## Examples of Great Changelogs
**Open Source Projects**:
- **Rust**: https://github.com/rust-lang/rust/blob/master/RELEASES.md
- **React**: https://github.com/facebook/react/blob/main/CHANGELOG.md
- **Next.js**: https://github.com/vercel/next.js/releases
- **fastify**: https://github.com/fastify/fastify/blob/main/CHANGELOG.md
## Changelog Success Criteria
**A great changelog enables readers to**:
1. [OK] Understand what changed in 30 seconds
2. [OK] Identify breaking changes immediately
3. [OK] Find relevant issues/PRs for more context
4. [OK] Decide whether to upgrade
5. [OK] Plan migration for breaking changes
6. [OK] Trust the project is actively maintained
**Quality metrics**:
- Completeness: All notable changes documented
- Clarity: Changes easy to understand
- Consistency: Follows Keep a Changelog format
- Traceability: Links to issues/commits
- Timeliness: Updated with every release
references/code-commenting-guide.md
# Code Commenting and Docstring Guide
Comprehensive guide for writing effective code comments, docstrings, and inline documentation that improves code maintainability.
## Table of Contents
- [Core Commenting Principles](#core-commenting-principles)
- [1. Comment WHY, Not WHAT](#1-comment-why-not-what)
- [2. Avoid Obvious Comments](#2-avoid-obvious-comments)
- [Get user by ID](#get-user-by-id)
- [Check if user exists](#check-if-user-exists)
- [3. Keep Comments Updated](#3-keep-comments-updated)
- [4. Use Comments for Complex Logic](#4-use-comments-for-complex-logic)
- [Docstrings for Functions/Methods](#docstrings-for-functionsmethods)
- [JavaScript (JSDoc)](#javascript-jsdoc)
- [Python (Google Style)](#python-google-style)
- [TypeScript (TSDoc)](#typescript-tsdoc)
- [Go (Godoc)](#go-godoc)
- [Inline Comments](#inline-comments)
- [When to Use Inline Comments](#when-to-use-inline-comments)
- [Comment Placement](#comment-placement)
- [Temporary Comments (TODOs, FIXMEs)](#temporary-comments-todos-fixmes)
- [Comment Anti-Patterns](#comment-anti-patterns)
- [BAD: Commented-Out Code](#bad-commented-out-code)
- [BAD: Redundant Comments](#bad-redundant-comments)
- [Initialize counter to zero](#initialize-counter-to-zero)
- [Loop from 1 to 10](#loop-from-1-to-10)
- [Calculate sum of numbers 1-10 using arithmetic series formula](#calculate-sum-of-numbers-1-10-using-arithmetic-series-formula)
- [BAD: Changelog Comments](#bad-changelog-comments)
- [BAD: Divider Comments](#bad-divider-comments)
- [Comments for Complex Business Logic](#comments-for-complex-business-logic)
- [Documentation Comments vs Implementation Comments](#documentation-comments-vs-implementation-comments)
- [Comment Linting](#comment-linting)
- [Accessibility Comments (HTML/JSX)](#accessibility-comments-htmljsx)
- [Comment Maintenance Checklist](#comment-maintenance-checklist)
- [Comment Quality Metrics](#comment-quality-metrics)
## Core Commenting Principles
### 1. Comment WHY, Not WHAT
**The code already shows WHAT it does. Comments explain WHY.**
**BAD: Bad (Explains WHAT)**:
```javascript
// Increment counter by 1
counter++;
// Loop through users array
for (const user of users) {
// Print user name
console.log(user.name);
}
```
**GOOD: Good (Explains WHY)**:
```javascript
// Retry counter incremented to track failed connection attempts.
// We allow up to 3 retries due to transient network issues.
counter++;
// Process each user to send welcome emails. Must be synchronous
// to comply with GDPR "right to erasure" - if user requests deletion
// mid-batch, we need to stop immediately.
for (const user of users) {
await sendWelcomeEmail(user);
}
```
### 2. Avoid Obvious Comments
**Self-explanatory code doesn't need comments.**
**BAD: Bad (Obvious)**:
```python
# Get user by ID
user = get_user(user_id)
# Check if user exists
if user is not None:
# Return user email
return user.email
```
**GOOD: Good (No comments needed - code is clear)**:
```python
user = get_user(user_id)
if user is not None:
return user.email
```
**When code is complex, refactor first, comment second**:
**BAD: Bad (Complex code with comment)**:
```javascript
// Calculate discount based on user tier
const d = u.t === 'gold' ? p * 0.2 : u.t === 'silver' ? p * 0.1 : 0;
```
**GOOD: Good (Self-documenting code)**:
```javascript
function calculateDiscount(user, price) {
const TIER_DISCOUNTS = {
gold: 0.20,
silver: 0.10,
bronze: 0.05
};
return price * (TIER_DISCOUNTS[user.tier] || 0);
}
const discount = calculateDiscount(user, price);
```
### 3. Keep Comments Updated
**Outdated comments are worse than no comments.**
**BAD: Bad (Outdated comment)**:
```javascript
// Connect to MongoDB database
const pool = new Pool({
host: 'localhost',
port: 5432, // PostgreSQL, not MongoDB!
database: 'myapp'
});
```
**GOOD: Good (Updated comment or removed)**:
```javascript
// Connect to PostgreSQL database for user data
const pool = new Pool({
host: 'localhost',
port: 5432,
database: 'myapp'
});
```
**Better: Make code self-documenting**:
```javascript
const postgresPool = new Pool(DATABASE_CONFIG);
```
### 4. Use Comments for Complex Logic
**When logic is unavoidably complex, explain the reasoning.**
**GOOD: Good (Explains complex algorithm)**:
```python
def calculate_shipping_cost(weight, distance, priority):
"""
Calculate shipping cost using complex tiered pricing.
We use exponential pricing for priority shipping because:
1. Courier partners charge us exponentially for faster delivery
2. Higher prices discourage abuse of priority option
3. Revenue from priority offsets losses on free standard shipping
"""
base_cost = weight * 0.5 + distance * 0.1
if priority == 'express':
# Exponential multiplier: express costs 4x standard
# This matches our courier's pricing model
return base_cost * 4
elif priority == 'priority':
# Priority is 2x - sweet spot for customer value vs cost
return base_cost * 2
else:
return base_cost
```
## Docstrings for Functions/Methods
### JavaScript (JSDoc)
**Format**:
```javascript
/**
* Brief description of what function does.
*
* Detailed explanation if needed. Explain parameters, behavior,
* edge cases, or important context.
*
* @param {string} userId - User unique identifier
* @param {Object} options - Optional configuration
* @param {boolean} [options.includeDeleted=false] - Include soft-deleted users
* @param {number} [options.timeout=5000] - Request timeout in milliseconds
* @returns {Promise<User>} User object with profile data
* @throws {NotFoundError} If user doesn't exist
* @throws {TimeoutError} If request exceeds timeout
*
* @example
* const user = await getUser('user-123', { includeDeleted: true });
* console.log(user.email);
*
* @example
* // With timeout
* const user = await getUser('user-123', { timeout: 3000 });
*/
async function getUser(userId, options = {}) {
const { includeDeleted = false, timeout = 5000 } = options;
// Implementation...
}
```
**JSDoc tags**:
| Tag | Purpose | Example |
|-----|---------|---------|
| `@param` | Parameter description | `@param {string} name - User's full name` |
| `@returns` | Return value | `@returns {Promise<User>} User object` |
| `@throws` | Exceptions thrown | `@throws {NotFoundError} If user not found` |
| `@example` | Usage example | `@example const user = await getUser('123')` |
| `@deprecated` | Mark as deprecated | `@deprecated Use fetchUser() instead` |
| `@see` | Related functions | `@see updateUser` |
| `@private` | Private function | `@private Internal use only` |
| `@async` | Async function | `@async` |
### Python (Google Style)
**Format**:
```python
def calculate_total(base_price: float, tax_rate: float, discount_percent: float = 0) -> float:
"""Calculate total price with tax and discount.
Calculates the final price by applying discount to base price,
then adding tax. Tax is calculated after discount to comply with
local tax regulations.
Args:
base_price: Base price before tax and discount (must be positive)
tax_rate: Tax rate as decimal (e.g., 0.08 for 8%)
discount_percent: Discount percentage from 0 to 100 (default: 0)
Returns:
Final price after discount and tax, rounded to 2 decimal places
Raises:
ValueError: If base_price is negative
ValueError: If tax_rate is negative or exceeds 1.0
ValueError: If discount_percent is negative or exceeds 100
Examples:
>>> calculate_total(100, 0.08)
108.0
>>> calculate_total(100, 0.08, discount_percent=10)
97.2
>>> calculate_total(-10, 0.08)
Traceback (most recent call last):
...
ValueError: Base price must be positive
Note:
Tax is calculated AFTER applying discount, as required by
California tax law (CA Revenue and Taxation Code §6011).
"""
if base_price < 0:
raise ValueError("Base price must be positive")
if tax_rate < 0 or tax_rate > 1.0:
raise ValueError("Tax rate must be between 0 and 1.0")
if discount_percent < 0 or discount_percent > 100:
raise ValueError("Discount must be between 0 and 100")
discounted_price = base_price * (1 - discount_percent / 100)
total = discounted_price * (1 + tax_rate)
return round(total, 2)
```
**Python docstring sections**:
| Section | Purpose |
|---------|---------|
| **Summary** | One-line description |
| **Args** | Parameter descriptions |
| **Returns** | Return value description |
| **Raises** | Exceptions that can be raised |
| **Examples** | Usage examples (doctest format) |
| **Note** | Additional context or warnings |
| **See Also** | Related functions |
### TypeScript (TSDoc)
**Format**:
```typescript
/**
* Fetch user data from the API.
*
* @remarks
* This function implements retry logic with exponential backoff.
* It will retry up to 3 times on network errors.
*
* @param userId - The user's unique identifier (UUID v4)
* @param options - Optional fetch configuration
* @returns A promise that resolves to the user object
* @throws {@link NotFoundError} When user doesn't exist
* @throws {@link NetworkError} After 3 failed retry attempts
*
* @example
* ```typescript
* const user = await fetchUser('550e8400-e29b-41d4-a716-446655440000');
* console.log(user.email);
* ```
*
* @see {@link updateUser} for updating user data
* @see {@link deleteUser} for deleting users
*/
async function fetchUser(
userId: string,
options?: FetchOptions
): Promise<User> {
// Implementation...
}
```
### Go (Godoc)
**Format**:
```go
// GetUser retrieves a user by ID from the database.
//
// This function queries the users table and returns a User struct.
// It returns an error if the user is not found or if there's a
// database connection issue.
//
// Parameters:
// - id: User's unique identifier (UUID)
//
// Returns:
// - *User: Pointer to User struct with user data
// - error: ErrNotFound if user doesn't exist, or database error
//
// Example:
//
// user, err := GetUser("user-123")
// if err != nil {
// if errors.Is(err, ErrNotFound) {
// // Handle not found
// }
// return err
// }
// fmt.Println(user.Email)
func GetUser(id string) (*User, error) {
// Implementation...
}
```
## Inline Comments
### When to Use Inline Comments
**Use inline comments for**:
- Complex algorithms
- Non-obvious optimizations
- Workarounds for bugs
- Business logic context
- Regulatory requirements
- Performance considerations
### Comment Placement
**BAD: Bad (Comment after code)**:
```javascript
const result = data.filter(x => x.status === 'active'); // Filter active items
```
**GOOD: Good (Comment before code)**:
```javascript
// Filter to only active items to exclude soft-deleted records
const result = data.filter(x => x.status === 'active');
```
### Temporary Comments (TODOs, FIXMEs)
**Standard tags**:
```javascript
// TODO: Add input validation for email format
// FIXME: Race condition when multiple users update simultaneously
// HACK: Workaround for IE11 bug - remove when dropping IE11 support
// NOTE: This must run synchronously due to GDPR compliance
// OPTIMIZE: Consider caching results - current O(n²) complexity
```
**Best practices**:
- Include issue number: `// TODO(#123): Add pagination`
- Add date: `// FIXME(2025-11-22): Memory leak in WebSocket`
- Assign owner: `// TODO(@john): Implement retry logic`
## Comment Anti-Patterns
### BAD: Commented-Out Code
**Don't commit commented-out code. Use version control instead.**
**BAD: Bad**:
```javascript
function processOrder(order) {
// const discount = calculateDiscount(order);
// order.total -= discount;
const total = order.total;
return total;
}
```
**GOOD: Good**:
```javascript
function processOrder(order) {
const total = order.total;
return total;
}
// If you need old code, check Git history
```
### BAD: Redundant Comments
**BAD: Bad**:
```python
# Initialize counter to zero
counter = 0
# Loop from 1 to 10
for i in range(1, 11):
# Add i to counter
counter += i
```
**GOOD: Good**:
```python
# Calculate sum of numbers 1-10 using arithmetic series formula
counter = 0
for i in range(1, 11):
counter += i
```
### BAD: Changelog Comments
**Don't use comments as changelog. Use Git.**
**BAD: Bad**:
```javascript
// 2025-11-22: Added validation - John
// 2025-11-15: Fixed bug - Sarah
// 2025-11-10: Initial version - Mike
function validateEmail(email) {
// Implementation
}
```
**GOOD: Good**:
```javascript
function validateEmail(email) {
// Implementation
}
// Check Git history for changes:
// git log --follow -- path/to/file.js
```
### BAD: Divider Comments
**Don't use comment dividers. Use file structure instead.**
**BAD: Bad**:
```javascript
// ============================================
// USER FUNCTIONS
// ============================================
function getUser() { }
function updateUser() { }
// ============================================
// ORDER FUNCTIONS
// ============================================
function getOrder() { }
```
**GOOD: Good**:
```
src/
├── users/
│ ├── getUser.js
│ └── updateUser.js
└── orders/
└── getOrder.js
```
## Comments for Complex Business Logic
**Use comments to explain business rules**:
```javascript
function calculateShippingCost(order, user) {
let baseCost = order.weight * COST_PER_KG;
// Free shipping for orders over $100 (marketing campaign requirement)
// Campaign runs until 2025-12-31 - see marketing doc: /docs/campaigns/free-shipping.md
if (order.total >= 100) {
return 0;
}
// Premium members get 20% discount on shipping (loyalty program)
// Approved by CFO on 2025-11-01 - see email thread #12345
if (user.tier === 'premium') {
baseCost *= 0.8;
}
// Express shipping costs 3x standard (courier contract requirement)
// Rates locked until 2026-01-01 per DHL contract clause 4.2
if (order.shippingSpeed === 'express') {
baseCost *= 3;
}
return baseCost;
}
```
## Documentation Comments vs Implementation Comments
**Documentation comments** (docstrings):
- Describe what function does
- Document public API
- Extracted by documentation tools
- Written for users of the function
**Implementation comments** (inline):
- Explain how function works
- Clarify complex logic
- Note edge cases
- Written for maintainers of the code
**Example**:
```python
def calculate_fibonacci(n: int) -> int:
"""Calculate nth Fibonacci number.
This is a DOCUMENTATION COMMENT for users of the function.
Args:
n: Position in Fibonacci sequence (0-indexed)
Returns:
The nth Fibonacci number
Examples:
>>> calculate_fibonacci(0)
0
>>> calculate_fibonacci(5)
5
"""
# IMPLEMENTATION COMMENT for maintainers:
# Use iterative approach instead of recursion to avoid
# stack overflow for large n (n > 1000).
# Time: O(n), Space: O(1)
if n <= 1:
return n
# Track previous two numbers in sequence
prev, curr = 0, 1
for _ in range(2, n + 1):
# Calculate next Fibonacci number
prev, curr = curr, prev + curr
return curr
```
## Comment Linting
**Tools**:
- **ESLint** (JavaScript): `eslint-plugin-jsdoc`
- **Pydocstyle** (Python): Check docstring conventions
- **golint** (Go): Check Godoc comments
- **TSLint** (TypeScript): Check TSDoc comments
**Example ESLint config**:
```json
{
"plugins": ["jsdoc"],
"rules": {
"jsdoc/check-param-names": "error",
"jsdoc/check-tag-names": "error",
"jsdoc/require-param": "error",
"jsdoc/require-returns": "error"
}
}
```
## Accessibility Comments (HTML/JSX)
**Use ARIA labels and comments for screen readers**:
```jsx
// This icon button has no visible text, so we need aria-label
// for screen reader users
<button
onClick={handleDelete}
aria-label="Delete user profile"
>
<TrashIcon />
</button>
{/*
Skip navigation link for keyboard users
Allows skipping header and jumping straight to main content
WCAG 2.1 Level A requirement
*/}
<a href="#main-content" className="sr-only">
Skip to main content
</a>
```
## Comment Maintenance Checklist
**When reviewing code**:
- [ ] Comments explain WHY, not WHAT
- [ ] No obvious/redundant comments
- [ ] Comments are up-to-date with code
- [ ] Complex logic has explanatory comments
- [ ] Public functions have docstrings
- [ ] No commented-out code
- [ ] TODOs have issue numbers or dates
- [ ] Business rules have context/references
- [ ] No divider comments (use file structure)
- [ ] Inline comments placed above code, not after
## Comment Quality Metrics
**Good commenting practices lead to**:
1. [OK] Faster onboarding (new developers understand code quickly)
2. [OK] Fewer bugs (complex logic is explained clearly)
3. [OK] Easier maintenance (context is preserved)
4. [OK] Better documentation (docstrings auto-generate API docs)
5. [OK] Reduced support questions (API usage is clear)
**Warning signs**:
- 🚩 Too many comments (code may be too complex)
- 🚩 No comments (code may be under-documented)
- 🚩 Outdated comments (maintenance issue)
- 🚩 Commented-out code (version control issue)
references/code-graph-documentation-patterns.md
# Code Graph Documentation Patterns
When a repo ships a code graph, document it as a small canonical set:
- JSON schema for inputs and outputs
- generation command
- validation command
- one Markdown report
- optional HTML or Mermaid views
Rules:
- keep raw graph JSON in `graphs/`
- keep validation output in `reports/`
- keep one human-readable canonical report path
- do not duplicate the same graph summary across many docs
- mark parser support and unsupported-language behavior explicitly
references/contributing-guide-standards.md
# Contributing Guide Standards
Comprehensive guide for creating CONTRIBUTING.md files that help contributors understand how to participate in your project effectively.
## Table of Contents
- [What Is a Contributing Guide?](#what-is-a-contributing-guide)
- [Essential Contributing Guide Structure](#essential-contributing-guide-structure)
- [1. Welcome Message](#1-welcome-message)
- [Contributing to [Project Name]](#contributing-to-project-name)
- [Quick Links](#quick-links)
- [2. Ways to Contribute](#2-ways-to-contribute)
- [Ways to Contribute](#ways-to-contribute)
- [Code Contributions](#code-contributions)
- [Non-Code Contributions](#non-code-contributions)
- [3. Getting Started (Development Setup)](#3-getting-started-development-setup)
- [Getting Started](#getting-started)
- [Prerequisites](#prerequisites)
- [Local Development Setup](#local-development-setup)
- [Troubleshooting Setup](#troubleshooting-setup)
- [Change port in .env](#change-port-in-env)
- [Verify PostgreSQL is running](#verify-postgresql-is-running)
- [Ensure Node.js version is correct](#ensure-nodejs-version-is-correct)
- [Clear cache and reinstall](#clear-cache-and-reinstall)
- [4. Development Workflow](#4-development-workflow)
- [Development Workflow](#development-workflow)
- [1. Create a Branch](#1-create-a-branch)
- [2. Make Changes](#2-make-changes)
- [3. Test Your Changes](#3-test-your-changes)
- [Run all tests](#run-all-tests)
- [Run tests in watch mode](#run-tests-in-watch-mode)
- [Run specific test file](#run-specific-test-file)
- [Check test coverage](#check-test-coverage)
- [4. Commit Your Changes](#4-commit-your-changes)
- [Simple commit](#simple-commit)
- [Commit with body](#commit-with-body)
- [Breaking change](#breaking-change)
- [5. Push to Your Fork](#5-push-to-your-fork)
- [6. Open a Pull Request](#6-open-a-pull-request)
- [5. Code Style Guidelines](#5-code-style-guidelines)
- [Code Style Guidelines](#code-style-guidelines)
- [JavaScript/TypeScript](#javascripttypescript)
- [Python](#python)
- [Testing](#testing)
- [6. Code Review Process](#6-code-review-process)
- [Code Review Process](#code-review-process)
- [What Reviewers Look For](#what-reviewers-look-for)
- [Responding to Review Feedback](#responding-to-review-feedback)
- [Review Timeline](#review-timeline)
- [After PR is Merged](#after-pr-is-merged)
- [7. Reporting Issues](#7-reporting-issues)
- [Reporting Issues](#reporting-issues)
- [Before Creating an Issue](#before-creating-an-issue)
- [Bug Reports](#bug-reports)
- [Feature Requests](#feature-requests)
- [Security Vulnerabilities](#security-vulnerabilities)
- [8. Community Guidelines](#8-community-guidelines)
- [Community Guidelines](#community-guidelines)
- [Code of Conduct](#code-of-conduct)
- [Communication Channels](#communication-channels)
- [Getting Help](#getting-help)
- [9. Recognition](#9-recognition)
- [Recognition](#recognition)
- [Contributors](#contributors)
- [Becoming a Maintainer](#becoming-a-maintainer)
- [Complete CONTRIBUTING.md Example](#complete-contributingmd-example)
- [Contributing Guide Checklist](#contributing-guide-checklist)
- [CONTRIBUTING.md Anti-Patterns](#contributingmd-anti-patterns)
- [Tools for Contributing Guides](#tools-for-contributing-guides)
- [Examples of Great Contributing Guides](#examples-of-great-contributing-guides)
- [Contributing Guide Success Criteria](#contributing-guide-success-criteria)
## What Is a Contributing Guide?
A **CONTRIBUTING.md** file explains how others can contribute to your project, including development setup, coding standards, and submission process.
**Purpose**:
- Onboard contributors quickly
- Set clear expectations
- Maintain code quality
- Reduce maintainer burden
- Foster community growth
**Location**: `CONTRIBUTING.md` in repository root
## Essential Contributing Guide Structure
### 1. Welcome Message
**Set a welcoming tone**:
```markdown
# Contributing to [Project Name]
Thank you for your interest in contributing to [Project Name]! We welcome contributions from everyone, whether you're fixing a typo, reporting a bug, or implementing a new feature.
This guide will help you get started quickly and ensure your contributions can be merged smoothly.
## Quick Links
- [Code of Conduct](CODE_OF_CONDUCT.md) - Be respectful and inclusive
- [Issue Tracker](https://github.com/user/repo/issues) - Report bugs or request features
- [Discussions](https://github.com/user/repo/discussions) - Ask questions or share ideas
- [Roadmap](docs/ROADMAP.md) - See what we're working on
```
### 2. Ways to Contribute
**List different contribution types**:
```markdown
## Ways to Contribute
We appreciate all contributions, including:
### Code Contributions
- 🐛 **Bug fixes** - Fix existing issues
- [SPARKLE] **New features** - Implement requested features
- [FAST] **Performance improvements** - Optimize existing code
- ♿ **Accessibility improvements** - Make the project more accessible
### Non-Code Contributions
- [NOTE] **Documentation** - Improve README, guides, or API docs
- [WEB] **Translations** - Translate docs or UI to other languages
- [DESIGN] **Design** - Improve UI/UX, create graphics
- [TEST] **Testing** - Write tests, report bugs
- [COMMENT] **Community** - Answer questions, help other contributors
- **Advocacy** - Blog posts, talks, tutorials about the project
**First-time contributors**: Look for issues labeled [`good first issue`](https://github.com/user/repo/labels/good%20first%20issue).
```
### 3. Getting Started (Development Setup)
**Provide step-by-step setup instructions**:
```markdown
## Getting Started
### Prerequisites
Before you begin, ensure you have:
- **Node.js 24+ LTS** ([download](https://nodejs.org/))
- **Git** ([download](https://git-scm.com/downloads))
- **PostgreSQL 18+** (optional, for database features)
- **Code editor** (we recommend [VS Code](https://code.visualstudio.com/))
### Local Development Setup
1. **Fork the repository**
Click the "Fork" button on GitHub to create your own copy.
2. **Clone your fork**
```bash
git clone https://github.com/YOUR_USERNAME/project.git
cd project
```
3. **Add upstream remote**
```bash
git remote add upstream https://github.com/original/project.git
```
4. **Install dependencies**
```bash
npm install
```
5. **Set up environment variables**
```bash
cp .env.example .env
# Edit .env with your configuration
```
6. **Initialize database** (if applicable)
```bash
npm run db:migrate
npm run db:seed
```
7. **Run development server**
```bash
npm run dev
```
The app should now be running at `http://localhost:3000`.
8. **Run tests to verify setup**
```bash
npm test
```
All tests should pass. If not, see [Troubleshooting](#troubleshooting).
### Troubleshooting Setup
**Port already in use**:
```bash
# Change port in .env
PORT=3001
```
**Database connection fails**:
```bash
# Verify PostgreSQL is running
brew services start postgresql # macOS
sudo systemctl start postgresql # Linux
```
**Tests failing**:
```bash
# Ensure Node.js version is correct
node --version # Should be 24+ LTS or 25+ Current
# Clear cache and reinstall
rm -rf node_modules package-lock.json
npm install
```
```
### 4. Development Workflow
**Explain the contribution workflow**:
```markdown
## Development Workflow
### 1. Create a Branch
Create a feature branch from `main`:
```bash
git checkout main
git pull upstream main
git checkout -b feature/your-feature-name
```
**Branch naming conventions**:
- `feature/` - New features (e.g., `feature/oauth-login`)
- `fix/` - Bug fixes (e.g., `fix/memory-leak`)
- `docs/` - Documentation (e.g., `docs/api-guide`)
- `refactor/` - Code refactoring (e.g., `refactor/auth-service`)
- `test/` - Test additions (e.g., `test/user-controller`)
### 2. Make Changes
- Write code following our [Code Style Guidelines](#code-style)
- Add tests for new features or bug fixes
- Update documentation if needed
- Keep commits focused and atomic
### 3. Test Your Changes
```bash
# Run all tests
npm test
# Run tests in watch mode
npm test -- --watch
# Run specific test file
npm test -- user.test.js
# Check test coverage
npm run test:coverage
```
**Coverage requirements**: Maintain 80%+ overall coverage.
### 4. Commit Your Changes
Follow [Conventional Commits](https://www.conventionalcommits.org/) format:
```
<type>(<scope>): <subject>
<body>
<footer>
```
**Types**:
- `feat`: New feature
- `fix`: Bug fix
- `docs`: Documentation changes
- `style`: Code formatting (no logic changes)
- `refactor`: Code refactoring
- `test`: Adding or updating tests
- `chore`: Maintenance tasks
**Examples**:
```bash
# Simple commit
git commit -m "feat(auth): add OAuth2 support"
# Commit with body
git commit -m "fix(api): resolve race condition in order processing
The order processing queue had a race condition when multiple
workers tried to process the same order. Added distributed locking
with Redis to ensure only one worker processes each order.
Fixes #456"
# Breaking change
git commit -m "feat(api)!: change response format to REST standard
BREAKING CHANGE: API responses now follow REST format with data/meta
wrapper. Update client code to access response.data instead of
response directly."
```
**Commit message guidelines**:
- Use imperative mood ("add feature" not "added feature")
- Keep subject line under 72 characters
- Reference issue numbers (`Fixes #123`, `Closes #456`)
- Explain WHY, not WHAT (code shows what)
### 5. Push to Your Fork
```bash
git push origin feature/your-feature-name
```
### 6. Open a Pull Request
1. Go to your fork on GitHub
2. Click "Compare & pull request"
3. Fill out the PR template:
- **Title**: Clear, descriptive (e.g., "Add OAuth2 authentication")
- **Description**: What changed and why
- **Issue reference**: Closes #123
- **Screenshots**: For UI changes
- **Testing**: How you tested the changes
- **Breaking changes**: List any breaking changes
**Pull Request Checklist**:
Before submitting, verify:
- [ ] Code follows style guidelines
- [ ] Tests added and passing
- [ ] Documentation updated
- [ ] Commit messages follow Conventional Commits
- [ ] Branch is up-to-date with `main`
- [ ] No merge conflicts
- [ ] PR description is complete
```
### 5. Code Style Guidelines
**Define coding standards**:
```markdown
## Code Style Guidelines
### JavaScript/TypeScript
We use **ESLint** and **Prettier** for code formatting.
**Run linter**:
```bash
npm run lint # Check for issues
npm run lint:fix # Auto-fix issues
npm run format # Format with Prettier
```
**Style rules**:
- Use `const` for variables that don't change
- Use `let` for variables that change
- Avoid `var`
- Use arrow functions for callbacks
- Use async/await instead of .then()
- Use template literals for string interpolation
- Prefer named exports over default exports
**Naming conventions**:
```typescript
// camelCase for variables and functions
const userName = 'John';
function getUserData() {}
// PascalCase for classes and types
class UserController {}
interface UserData {}
// UPPERCASE for constants
const MAX_RETRIES = 3;
const API_BASE_URL = 'https://api.example.com';
// kebab-case for file names
user-controller.ts
api-client.ts
```
### Python
Follow **PEP 8** style guide.
**Run linter**:
```bash
black . # Format code
flake8 . # Check style
mypy . # Type checking
```
**Style rules**:
- Use 4 spaces for indentation
- Maximum line length: 88 characters (Black default)
- Use type hints for function parameters and returns
- Use docstrings for all public functions/classes
- Use snake_case for functions and variables
- Use PascalCase for classes
### Testing
**Test structure** (AAA pattern):
```javascript
describe('UserController', () => {
it('should create user with valid data', async () => {
// Arrange - Set up test data
const userData = {
email: 'test@example.com',
name: 'John Doe'
};
// Act - Execute the operation
const user = await createUser(userData);
// Assert - Verify the outcome
expect(user.email).toBe('test@example.com');
expect(user.id).toBeDefined();
});
});
```
**Test naming**:
- Describe what the test does, not implementation details
- Use "should" format: `should return 404 when user not found`
- Group related tests with `describe` blocks
**Coverage requirements**:
- Overall: 80%+
- New features: 90%+
- Critical paths (auth, payments): 100%
```
### 6. Code Review Process
**Explain review expectations**:
```markdown
## Code Review Process
### What Reviewers Look For
- **Correctness**: Does the code work as intended?
- **Tests**: Are there tests? Do they cover edge cases?
- **Documentation**: Is code documented? README updated?
- **Style**: Follows project style guidelines?
- **Performance**: Are there obvious performance issues?
- **Security**: Any security vulnerabilities?
- **Breaking changes**: Are breaking changes justified and documented?
### Responding to Review Feedback
- Be open to feedback - reviews help improve code quality
- Ask questions if feedback is unclear
- Make requested changes in new commits (don't force-push)
- Respond to each comment (thumbs up, "Done", or explain why not)
- Re-request review after addressing feedback
### Review Timeline
- **First review**: Within 2 business days
- **Follow-up reviews**: Within 1 business day
- **Merge**: After approval from 2 maintainers
**No response after 7 days**: PR may be closed for inactivity.
### After PR is Merged
- Delete your feature branch (GitHub will prompt you)
- Update your local repository:
```bash
git checkout main
git pull upstream main
```
Thank you for your contribution! [CELEBRATE]
```
### 7. Reporting Issues
**Guide users on reporting bugs**:
```markdown
## Reporting Issues
### Before Creating an Issue
1. **Search existing issues**: Your issue may already be reported
2. **Check documentation**: Answer might be in docs or FAQ
3. **Verify with latest version**: Bug may be fixed in newer version
### Bug Reports
**Use the bug report template** and include:
- **Description**: What happened vs what you expected
- **Steps to reproduce**: Minimal steps to reproduce the bug
- **Environment**: OS, Node.js version, browser (if applicable)
- **Error messages**: Full error messages and stack traces
- **Screenshots**: For visual bugs
**Example**:
```markdown
**Description**:
User login fails with "Invalid token" error even with correct credentials.
**Steps to Reproduce**:
1. Go to /login
2. Enter email: user@example.com
3. Enter password: correct_password
4. Click "Login"
5. See error: "Invalid token"
**Environment**:
- OS: macOS 14.0
- Browser: Chrome 120
- Node.js: 24.11.0
**Error message**:
```
Error: Invalid token
at verifyToken (auth.js:45)
at loginUser (user-controller.js:23)
```
**Expected**: Successful login and redirect to dashboard
**Actual**: Error message shown, no login
```
### Feature Requests
**Use the feature request template** and include:
- **Problem**: What problem does this solve?
- **Proposed solution**: How should it work?
- **Alternatives**: Other solutions you've considered
- **Use case**: Real-world scenario where this helps
### Security Vulnerabilities
**Do NOT open public issues for security vulnerabilities.**
Instead, email security@example.com with:
- Description of vulnerability
- Steps to reproduce
- Potential impact
- Suggested fix (if known)
We aim to respond within 48 hours.
```
### 8. Community Guidelines
**Reference Code of Conduct**:
```markdown
## Community Guidelines
### Code of Conduct
This project follows the [Contributor Covenant Code of Conduct](CODE_OF_CONDUCT.md).
**In summary**:
- Be respectful and inclusive
- Welcome newcomers
- Provide constructive feedback
- Focus on what's best for the community
- Show empathy towards others
**Unacceptable behavior**:
- Harassment or discrimination
- Trolling or inflammatory comments
- Personal attacks
- Spam or self-promotion
- Publishing others' private information
**Reporting**: Email conduct@example.com to report violations.
### Communication Channels
- **GitHub Issues**: Bug reports and feature requests
- **GitHub Discussions**: Questions, ideas, general discussion
- **Discord**: Real-time chat with maintainers and contributors
- **Twitter**: [@projectname](https://twitter.com/projectname) for announcements
### Getting Help
**Questions about the project**:
- Check [documentation](https://docs.example.com)
- Search [GitHub Discussions](https://github.com/user/repo/discussions)
- Ask in [Discord #help channel](https://discord.gg/example)
**Questions about contributing**:
- Read this guide thoroughly
- Ask in [Discord #contributors channel](https://discord.gg/example)
- Tag maintainers in GitHub Discussions
```
### 9. Recognition
**Acknowledge contributors**:
```markdown
## Recognition
### Contributors
All contributors are recognized in:
- [Contributors page](https://github.com/user/repo/graphs/contributors)
- Release notes (for significant contributions)
- [CHANGELOG.md](CHANGELOG.md) (for features and fixes)
### Becoming a Maintainer
Active contributors may be invited to become maintainers.
**Criteria**:
- Consistent high-quality contributions over 3+ months
- Deep understanding of codebase
- Helpful in reviews and discussions
- Alignment with project values
**Responsibilities**:
- Review pull requests
- Triage issues
- Mentor new contributors
- Make architectural decisions
```
## Complete CONTRIBUTING.md Example
See [assets/project-management/contributing-template.md](../assets/project-management/contributing-template.md) for a complete, copy-paste ready template.
## Contributing Guide Checklist
**Before publishing CONTRIBUTING.md**:
- [ ] Welcome message included
- [ ] Ways to contribute listed (code and non-code)
- [ ] Development setup instructions complete and tested
- [ ] Branch naming conventions defined
- [ ] Commit message format specified (Conventional Commits)
- [ ] Pull request process explained
- [ ] Code style guidelines documented
- [ ] Test requirements stated
- [ ] Code review process described
- [ ] Issue reporting guidelines included
- [ ] Security vulnerability reporting process
- [ ] Code of Conduct linked
- [ ] Communication channels listed
- [ ] Recognition/acknowledgment section
- [ ] All links work correctly
## CONTRIBUTING.md Anti-Patterns
**BAD: Avoid**:
- **No setup instructions** - Contributors can't get started
- **Vague requirements** - "Write good code" isn't actionable
- **Intimidating tone** - Discourages contributions
- **Outdated info** - Setup instructions that don't work
- **No examples** - Hard to understand commit format
- **Missing links** - Links to issue tracker, docs, etc.
- **Only for code** - Ignores non-code contributions
## Tools for Contributing Guides
**Templates**:
- GitHub's default CONTRIBUTING.md template
- [Contributor Covenant](https://www.contributor-covenant.org/)
- [All Contributors](https://allcontributors.org/) - Recognize all contributions
**Automation**:
- **All Contributors Bot**: Automatically add contributors to README
- **Semantic Release**: Auto-generate changelogs from commits
- **PR Templates**: Auto-populate PR descriptions
## Examples of Great Contributing Guides
**Open Source Projects**:
- **React**: https://github.com/facebook/react/blob/main/CONTRIBUTING.md
- **Next.js**: https://github.com/vercel/next.js/blob/canary/contributing.md
- **Vue.js**: https://github.com/vuejs/vue/blob/dev/.github/CONTRIBUTING.md
- **Typescript**: https://github.com/microsoft/TypeScript/blob/main/CONTRIBUTING.md
## Contributing Guide Success Criteria
**A great contributing guide enables contributors to**:
1. [OK] Set up development environment in < 15 minutes
2. [OK] Understand how to create a pull request
3. [OK] Know code style requirements
4. [OK] Write commit messages in correct format
5. [OK] Find communication channels
6. [OK] Report bugs effectively
7. [OK] Understand code of conduct
**Quality metrics**:
- Time to first contribution: < 30 minutes
- PR rejection rate due to guidelines: < 10%
- Contributor retention: > 40% return contributors
- Setup issues: < 5% of new contributors report setup problems
references/docs-as-code-setup.md
# Docs-as-Code Setup Guide
Comprehensive guide to implementing documentation-as-code workflows with version control, automated builds, and CI/CD integration.
## Table of Contents
- [What is Docs-as-Code?](#what-is-docs-as-code)
- [Benefits](#benefits)
- [Choosing a Tool](#choosing-a-tool)
- [MkDocs Setup](#mkdocs-setup)
- [Docusaurus Setup](#docusaurus-setup)
- [CI/CD Integration](#cicd-integration)
- [Repository Documentation Governance](#repository-documentation-governance)
- [Best Practices](#best-practices)
---
## What is Docs-as-Code?
**Docs-as-Code** is an approach that applies software development workflows to documentation:
- Documentation stored in version control (Git)
- Written in plain text (Markdown, reStructuredText)
- Reviewed via pull requests
- Built and deployed automatically
- Versioned alongside code
**Traditional docs:** Word/Confluence → Manual updates → Version confusion
**Docs-as-Code:** Markdown + Git → CI/CD → Automatic deployment
---
## Benefits
### For Documentation Teams
- **Version control:** Full history of changes
- **Collaboration:** Pull request reviews, suggestions
- **Branching:** Work on features independently
- **Automation:** Automatic builds and deploys
### For Developers
- **Familiar tools:** Git, Markdown, code editors
- **Inline updates:** Update docs with code changes
- **Code ownership:** Docs live near code
- **Single source of truth:** No separate wiki
### For Users
- **Always up-to-date:** Automatic deployments
- **Searchable:** Full-text search
- **Versioned:** View docs for specific versions
- **Fast:** Static site generation
---
## Choosing a Tool
| Tool | Language | Best For | Complexity |
|------|----------|----------|------------|
| **VitePress** | Vue/Node | Markdown-first docs with fast iteration and `llms.txt` support | Low |
| **Astro Starlight** | Astro/Node | Content-heavy product docs with strong IA | Medium |
| **MkDocs** | Python | Ops, internal, or Python-adjacent docs sites | Low |
| **Docusaurus** | React | Large versioned portals with custom UX needs | Medium |
| **Nextra** | Next.js | Teams already standardized on Next.js | Medium |
| **Mintlify / ReadMe** | Hosted | Managed developer portals and API docs | Low |
| **GitBook** | Hosted | Writer-led collaboration workflows | Low |
**Recommendation:**
- **Markdown-first docs with AI-readable output:** VitePress
- **Content-heavy docs on Astro stack:** Starlight
- **Ops / Python / internal platform docs:** MkDocs
- **Large multi-version product portal:** Docusaurus
- **Hosted developer portal:** Mintlify or ReadMe
- **Already on Next.js:** Nextra
Choose based on:
- your existing frontend/tooling stack
- whether you need built-in versioning
- whether hosted publishing is acceptable
- whether you want first-class AI-readable outputs such as `llms.txt`
---
## Repository Documentation Governance
Modern agent-readable repos need documentation placement rules as much as they need writing rules. The goal is to make the repo legible without creating a permanent pile of one-off Markdown files.
### Placement Matrix
| Location | Owns | Must Not Own |
|----------|------|--------------|
| `AGENTS.md` / `CLAUDE.md` | Hot execution policy, exact commands, hard constraints, pointers to deeper docs | Codebase catalog, reports, plans, inventories, duplicated docs |
| `README.md` | Navigation, setup entry point, short orientation | Every operational procedure or architecture detail |
| `docs/tech/` or `docs/architecture/` | Canonical technical and architecture docs | Temporary investigation notes |
| `docs/operations/` or `docs/runbooks/` | Operational procedures, incident steps, release steps | Product explanations or generic onboarding prose |
| `docs/api/` | API reference, contracts, examples | Product roadmap or debugging reports |
| `docs/specs/` or `docs/plans/` | Active specs and implementation plans | Permanent status truth after the work ships |
| `docs/reports/` | Time-bound analysis, audits, migration findings | Canonical architecture truth after integration |
| `docs/context/` or `context/` | Generated or compiled LLM context artifacts | Hand-authored source of truth without rebuild ownership |
| `.archive/` | Historical material excluded from normal context | Anything agents should normally read |
| `scripts/README.md` | Script-adjacent commands and maintenance workflow | Repo-wide onboarding or product docs |
### New Markdown Creation Test
Create a new Markdown file only when the answer to each question is yes:
1. Does no existing canonical doc already own this subject?
2. Is the target folder correct for the doc type?
3. Is the file linked from the relevant README, index, docs nav, or context hub?
4. Does the file have an owner or review path?
5. Does volatile content include `last_verified` or a refresh command?
6. Is there a lifecycle state for reports and plans: `active`, `pending-integration`, `integrated`, or `superseded`?
7. If generated, is the source artifact and rebuild command documented?
If the answer is no, update the closest canonical doc or leave the content in the task thread. Do not create root-level `SUMMARY.md`, `MIGRATION.md`, `OPTIMIZATION_NOTES.md`, or similar files unless the repo explicitly asks for that filename.
### Agent Context Pattern
For LLM-facing repo context:
- Keep the hot instruction layer short and precise.
- Put durable detail in canonical docs.
- Put large generated summaries in `docs/context/` or `context/`, built from structured artifacts.
- Keep raw evidence separate from compiled summaries.
- Prefer links and stable headings over duplicated prose.
This follows the April 2026 pattern from Codex, Claude, and Copilot guidance: instruction files are automatically loaded context, so they should contain focused, non-obvious rules and route agents to repo-local evidence instead of becoming all-purpose docs.
---
## MkDocs Setup
### Installation
```bash
# Install MkDocs
pip install mkdocs
# Install Material theme (recommended)
pip install mkdocs-material
# Verify installation
mkdocs --version
```
### Project Initialization
```bash
# Create new MkDocs project
mkdocs new my-project
cd my-project
# Project structure
my-project/
├── mkdocs.yml # Configuration
└── docs/
└── index.md # Homepage
```
### Configuration (mkdocs.yml)
```yaml
site_name: My Project Documentation
site_url: https://docs.example.com
site_description: Comprehensive documentation for My Project
site_author: Your Name
# Theme configuration
theme:
name: material
palette:
# Light mode
- scheme: default
primary: indigo
accent: indigo
toggle:
icon: material/brightness-7
name: Switch to dark mode
# Dark mode
- scheme: slate
primary: indigo
accent: indigo
toggle:
icon: material/brightness-4
name: Switch to light mode
features:
- navigation.tabs
- navigation.tabs.sticky
- navigation.sections
- navigation.expand
- navigation.top
- search.suggest
- search.highlight
- content.code.copy
- content.code.annotate
# Navigation
nav:
- Home: index.md
- Getting Started:
- Installation: getting-started/installation.md
- Quick Start: getting-started/quick-start.md
- Configuration: getting-started/configuration.md
- API Reference:
- Authentication: api/authentication.md
- Endpoints: api/endpoints.md
- Webhooks: api/webhooks.md
- Guides:
- Deployment: guides/deployment.md
- Best Practices: guides/best-practices.md
- About:
- Changelog: about/changelog.md
- Contributing: about/contributing.md
- License: about/license.md
# Markdown extensions
markdown_extensions:
# Python Markdown
- abbr
- admonition
- attr_list
- def_list
- footnotes
- md_in_html
- tables
- toc:
permalink: true
# Python Markdown Extensions
- pymdownx.arithmatex:
generic: true
- pymdownx.betterem
- pymdownx.critic
- pymdownx.details
- pymdownx.emoji:
emoji_index: !!python/name:materialx.emoji.twemoji
emoji_generator: !!python/name:materialx.emoji.to_svg
- pymdownx.highlight:
anchor_linenums: true
line_spans: __span
pygments_lang_class: true
- pymdownx.inlinehilite
- pymdownx.keys
- pymdownx.mark
- pymdownx.smartsymbols
- pymdownx.snippets
- pymdownx.superfences:
custom_fences:
- name: mermaid
class: mermaid
format: !!python/name:pymdownx.superfences.fence_code_format
- pymdownx.tabbed:
alternate_style: true
- pymdownx.tasklist:
custom_checkbox: true
# Plugins
plugins:
- search:
lang: en
- git-revision-date-localized:
enable_creation_date: true
- minify:
minify_html: true
# Extra configuration
extra:
version:
provider: mike
social:
- icon: fontawesome/brands/github
link: https://github.com/username/repo
- icon: fontawesome/brands/twitter
link: https://twitter.com/username
- icon: fontawesome/brands/discord
link: https://discord.gg/invite
# Copyright
copyright: Copyright © 2025 Your Company Name
```
### Creating Documentation
**docs/index.md:**
```markdown
# Welcome to My Project
This is the homepage of your documentation.
## Quick Links
- [Installation Guide](getting-started/installation.md)
- [API Reference](api/endpoints.md)
- [Contributing](about/contributing.md)
## Features
- Feature 1
- Feature 2
- Feature 3
```
### Build and Preview
```bash
# Serve locally (with live reload)
mkdocs serve
# Build static site
mkdocs build
# Output to dist/
# dist/
# ├── index.html
# ├── getting-started/
# ├── api/
# └── assets/
```
### Deployment
**GitHub Pages:**
```bash
# Deploy to gh-pages branch
mkdocs gh-deploy
# With custom domain
mkdocs gh-deploy --force
```
---
## Docusaurus Setup
### Installation
```bash
# Create new Docusaurus site
npx create-docusaurus@latest my-website classic
cd my-website
# Project structure
my-website/
├── docs/ # Documentation files
├── blog/ # Blog posts (optional)
├── src/
│ ├── components/ # React components
│ └── pages/ # Custom pages
├── static/ # Static assets
└── docusaurus.config.js # Configuration
```
### Configuration (docusaurus.config.js)
```javascript
const config = {
title: 'My Project',
tagline: 'Awesome documentation for awesome project',
url: 'https://docs.example.com',
baseUrl: '/',
onBrokenLinks: 'throw',
onBrokenMarkdownLinks: 'warn',
favicon: 'img/favicon.ico',
// GitHub Pages deployment
organizationName: 'username',
projectName: 'repo',
i18n: {
defaultLocale: 'en',
locales: ['en'],
},
presets: [
[
'classic',
{
docs: {
sidebarPath: require.resolve('./sidebars.js'),
editUrl: 'https://github.com/username/repo/tree/main/',
showLastUpdateTime: true,
showLastUpdateAuthor: true,
},
blog: {
showReadingTime: true,
editUrl: 'https://github.com/username/repo/tree/main/',
},
theme: {
customCss: require.resolve('./src/css/custom.css'),
},
},
],
],
themeConfig: {
navbar: {
title: 'My Project',
logo: {
alt: 'My Project Logo',
src: 'img/logo.svg',
},
items: [
{
type: 'doc',
docId: 'intro',
position: 'left',
label: 'Docs',
},
{to: '/blog', label: 'Blog', position: 'left'},
{
href: 'https://github.com/username/repo',
label: 'GitHub',
position: 'right',
},
],
},
footer: {
style: 'dark',
links: [
{
title: 'Docs',
items: [
{
label: 'Getting Started',
to: '/docs/intro',
},
],
},
{
title: 'Community',
items: [
{
label: 'Discord',
href: 'https://discord.gg/invite',
},
{
label: 'Twitter',
href: 'https://twitter.com/username',
},
],
},
],
copyright: `Copyright © ${new Date().getFullYear()} My Project`,
},
prism: {
theme: require('prism-react-renderer/themes/github'),
darkTheme: require('prism-react-renderer/themes/dracula'),
},
algolia: {
appId: 'YOUR_APP_ID',
apiKey: 'YOUR_SEARCH_API_KEY',
indexName: 'YOUR_INDEX_NAME',
},
},
};
module.exports = config;
```
### Versioning
```bash
# Create version snapshot
npm run docusaurus docs:version 1.0.0
# Structure
versioned_docs/
├── version-1.0.0/
│ └── intro.md
└── version-2.0.0/
└── intro.md
versioned_sidebars/
└── version-1.0.0-sidebars.json
```
### Build and Deploy
```bash
# Build
npm run build
# Serve locally
npm run serve
# Deploy to GitHub Pages
GIT_USER=<username> npm run deploy
```
---
## CI/CD Integration
### GitHub Actions (MkDocs)
**.github/workflows/docs.yml:**
```yaml
name: Deploy Documentation
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/setup-python@v6
with:
python-version: '3.x'
- name: Install dependencies
run: |
pip install mkdocs-material
pip install mkdocs-git-revision-date-localized-plugin
pip install mkdocs-minify-plugin
- name: Build documentation
run: mkdocs build
- name: Deploy to GitHub Pages
if: github.ref == 'refs/heads/main'
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./site
```
### GitHub Actions (Docusaurus)
**.github/workflows/deploy.yml:**
```yaml
name: Deploy Docusaurus
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: actions/setup-node@v6
with:
node-version: 22
cache: npm
- name: Install dependencies
run: npm ci
- name: Build website
run: npm run build
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./build
```
### Netlify
**netlify.toml:**
```toml
[build]
command = "mkdocs build"
publish = "site"
[build.environment]
PYTHON_VERSION = "3.8"
[[redirects]]
from = "/*"
to = "/index.html"
status = 200
```
### Vercel
**vercel.json:**
```json
{
"buildCommand": "npm run build",
"outputDirectory": "build",
"framework": "docusaurus2"
}
```
---
## Best Practices
### 1. Keep Docs Near Code
```
project/
├── src/
├── tests/
└── docs/ # Documentation lives with code
├── api/
├── guides/
└── index.md
```
### 2. Review Docs in Pull Requests
**Benefits:**
- Catch outdated information
- Ensure docs match code changes
- Improve documentation quality
**GitHub PR template:**
```markdown
## Documentation
- [ ] Documentation updated for this change
- [ ] New features documented
- [ ] Breaking changes documented in migration guide
```
### 3. Automate Linting
```yaml
# .github/workflows/docs-lint.yml
name: Lint Documentation
on: [push, pull_request]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Lint Markdown
uses: nosborn/github-action-markdown-cli@v3.2.0
with:
files: docs/
- name: Check links
uses: gaurav-nelson/github-action-markdown-link-check@v1
```
### 4. Use Branch Deployments
**Preview PRs:**
- Deploy docs on every PR
- Review changes before merging
- Catch broken links early
**Netlify Deploy Previews:**
- Automatic PR previews
- Comment with preview URL
- No configuration needed
### 5. Track Analytics
**Google Analytics:**
```javascript
// docusaurus.config.js
module.exports = {
themeConfig: {
gtag: {
trackingID: 'G-XXXXXXXXXX',
},
},
};
```
**Plausible (privacy-friendly):**
```javascript
scripts: [
{
src: 'https://plausible.io/js/script.js',
'data-domain': 'docs.example.com',
defer: true,
},
],
```
---
## Resources
- [MkDocs Documentation](https://www.mkdocs.org/)
- [Material for MkDocs](https://squidfunk.github.io/mkdocs-material/)
- [Docusaurus Documentation](https://docusaurus.io/)
- [VitePress Documentation](https://vitepress.dev/)
- [VitePress llms.txt Guide](https://vitepress.dev/guide/llms)
- [Astro Starlight](https://starlight.astro.build/)
- [Write the Docs - Docs as Code](https://www.writethedocs.org/guide/docs-as-code/)
- [Diátaxis Framework](https://diataxis.fr/) - Documentation structure guide
references/documentation-metrics.md
# Documentation Metrics
How to measure documentation quality, coverage, and health across a codebase.
---
## Table of Contents
- [Core Metrics](#core-metrics)
- [Coverage Measurement](#coverage-measurement)
- [Count routes in source](#count-routes-in-source)
- [Count documented endpoints](#count-documented-endpoints)
- [Freshness Scoring](#freshness-scoring)
- [Days since last edit per doc file](#days-since-last-edit-per-doc-file)
- [Quality Indicators](#quality-indicators)
- [Dashboard Design](#dashboard-design)
- [Tooling](#tooling)
- [Benchmarks and Thresholds](#benchmarks-and-thresholds)
- [Anti-Patterns](#anti-patterns)
- [Related Resources](#related-resources)
## Core Metrics
Track four dimensions. Each serves a different decision.
| Metric | What It Answers | Signal Source |
|--------|----------------|---------------|
| **Coverage** | Is it documented at all? | Code-to-docs ratio |
| **Freshness** | Is it still current? | Git timestamps, page views |
| **Accuracy** | Does it match reality? | Broken examples, user reports |
| **Findability** | Can people locate it? | Search analytics, support tickets |
---
## Coverage Measurement
Coverage = documented items / total items. Measure per category.
**What to count:**
| Category | "Total" Source | "Documented" Source |
|----------|---------------|---------------------|
| API endpoints | OpenAPI spec or route files | API reference docs |
| Config options | Schema or `.env.example` | Configuration guide |
| Error codes | Error constants file | Troubleshooting docs |
| CLI commands | Command registry | CLI reference |
| Public functions | Exported symbols | JSDoc / docstrings |
**Script pattern (API endpoints):**
```bash
# Count routes in source
TOTAL=$(grep -rc "router\.\(get\|post\|put\|delete\)" src/routes/ | awk -F: '{s+=$2} END {print s}')
# Count documented endpoints
DOCUMENTED=$(grep -c "^### " docs/api-reference.md)
echo "Coverage: $DOCUMENTED / $TOTAL ($(( DOCUMENTED * 100 / TOTAL ))%)"
```
Set a coverage floor per category. 90% for API endpoints, 80% for config, 70% for error codes is a reasonable starting point.
---
## Freshness Scoring
Combine time-based and behavior-based signals.
**Time-based signals:**
```bash
# Days since last edit per doc file
for f in docs/**/*.md; do
days=$(( ($(date +%s) - $(git log -1 --format=%ct -- "$f")) / 86400 ))
echo "$days days: $f"
done | sort -rn
```
**Freshness tiers:**
| Tier | Age | Action |
|------|-----|--------|
| Fresh | < 90 days | No action |
| Aging | 90-180 days | Review next quarter |
| Stale | 180-365 days | Flag for rewrite or archive |
| Dead | > 365 days | Archive or delete |
**Behavior-based signals (stronger than timestamps):**
- Doc references a dependency version 2+ majors behind
- Code path documented has been deleted or renamed
- Page gets zero views for 90+ days (if analytics available)
- Related source file changed but doc file did not
---
## Quality Indicators
Track these as automated checks, not manual audits.
**Broken links:** Run `markdown-link-check` in CI. Zero tolerance -- every broken link is a bug.
**Outdated screenshots:** Flag images older than 6 months. No automated fix; add to quarterly review queue.
**Stale code examples:** Extract fenced code blocks, run them. Any non-zero exit is a doc bug.
**Readability drift:** Run `textstat` or Vale. Flag pages where Flesch-Kincaid grade exceeds 12.
**Terminology inconsistency:** Use Vale with a project vocab file. Flag mixed usage of the same concept (e.g., "log in" vs "sign in" vs "authenticate").
---
## Dashboard Design
**Weekly (automated, async):**
- Broken link count
- CI doc-test pass rate
- New pages created vs pages archived
**Monthly (team review):**
- Coverage percentages per category
- Freshness distribution (% fresh / aging / stale / dead)
- Top 10 stalest pages
- Support tickets traceable to missing docs
**Quarterly (planning input):**
- Coverage trend over time
- Time-to-resolution for doc-related support tickets
- Pages archived vs pages rewritten
- Docs NPS or CSAT if collected
---
## Tooling
| Need | Tool | Integration |
|------|------|-------------|
| Link checking | `markdown-link-check` | CI on every PR |
| Prose linting | Vale with Google/Microsoft style | CI on every PR |
| Spell check | cspell with project dictionary | CI on every PR |
| Code example testing | `markdown-code-runner` or custom extract-and-run | CI nightly |
| Freshness reporting | Custom git-log script | Cron, posts to Slack |
| Coverage reporting | Custom route-vs-docs diff | CI on release branches |
| Analytics | Plausible, PostHog, or Google Analytics | Docs site |
---
## Benchmarks and Thresholds
Decision guide for what to do when metrics cross a line.
| Metric | Green | Yellow | Red |
|--------|-------|--------|-----|
| API coverage | > 90% | 70-90% | < 70% |
| Config coverage | > 80% | 60-80% | < 60% |
| Broken links | 0 | 1-3 | > 3 |
| Stale pages (>180d) | < 10% | 10-25% | > 25% |
| Doc-test pass rate | 100% | > 90% | < 90% |
**When to flag:** Yellow metrics go on the next sprint backlog.
**When to rewrite:** Page is stale + low accuracy + still gets traffic. Rewrite from scratch rather than patching.
**When to archive:** Page is stale + zero traffic + referenced feature is deprecated. Move to an archive folder, remove from navigation.
---
## Anti-Patterns
- **Vanity dashboards.** Tracking total page count instead of coverage ratio. More pages is not better.
- **Manual-only audits.** If metrics require a human to compute them, they will not be computed. Automate or skip.
- **Measuring without acting.** A dashboard nobody reviews is waste. Assign owners to each metric threshold.
- **Precision theater.** Reporting coverage to two decimal places when the denominator is a rough estimate. Round to the nearest 5%.
- **Ignoring behavior signals.** A page edited yesterday can still be wrong. Combine timestamps with code-change correlation.
---
## Related Resources
- [documentation-testing.md](documentation-testing.md) - Automated quality checks
- [docs-as-code-setup.md](docs-as-code-setup.md) - CI/CD integration for docs
- [writing-best-practices.md](writing-best-practices.md) - Content quality standards
references/documentation-testing.md
# Documentation Testing Guide
Comprehensive guide for testing technical documentation quality, accuracy, and usability.
---
## Table of Contents
- [Why Test Documentation?](#why-test-documentation)
- [Testing Categories](#testing-categories)
- [1. Technical Accuracy Testing](#1-technical-accuracy-testing)
- [Extract code blocks from documentation](#extract-code-blocks-from-documentation)
- [Run extracted code](#run-extracted-code)
- [Automated example testing](#automated-example-testing)
- [Test API endpoints from docs](#test-api-endpoints-from-docs)
- [Expected: 200 OK with user list](#expected-200-ok-with-user-list)
- [Actual: [verify against documentation]](#actual-verify-against-documentation)
- [Fresh clone in isolated environment](#fresh-clone-in-isolated-environment)
- [Follow documentation step-by-step](#follow-documentation-step-by-step)
- [[Follow README.md installation steps...]](#follow-readmemd-installation-steps)
- [Document any failures or unclear steps](#document-any-failures-or-unclear-steps)
- [2. Automated Linting](#2-automated-linting)
- [Install](#install)
- [Run linter](#run-linter)
- [With configuration](#with-configuration)
- [Install Vale](#install-vale)
- [or download from https://vale.sh/](#or-download-from-httpsvalesh)
- [Initialize configuration](#initialize-configuration)
- [Create .vale.ini](#create-valeini)
- [Run Vale](#run-vale)
- [Output example:](#output-example)
- [docs/api.md](#docsapimd)
- [15:6 warning 'utilize' is wordy. Consider Vale.Wordiness](#156-warning-utilize-is-wordy-consider-valewordiness)
- [replacing with 'use'.](#replacing-with-use)
- [23:1 error Use 'API' instead of 'api'. Google.Acronyms](#231-error-use-api-instead-of-api-googleacronyms)
- [Install](#install)
- [Test documentation](#test-documentation)
- [Output:](#output)
- [README.md](#readmemd)
- [line 12: 'very' is wordy or unneeded](#line-12-very-is-wordy-or-unneeded)
- [line 23: 'basically' is wordy or unneeded](#line-23-basically-is-wordy-or-unneeded)
- [line 45: 'obviously' is a weasel word](#line-45-obviously-is-a-weasel-word)
- [Install](#install)
- [Check for insensitive language](#check-for-insensitive-language)
- [Output:](#output)
- [docs/README.md](#docsreadmemd)
- [12:5-12:9 warning 'guys' may be insensitive, use 'people' instead](#125-129-warning-guys-may-be-insensitive-use-people-instead)
- [3. Link Validation](#3-link-validation)
- [Install markdown-link-check](#install-markdown-link-check)
- [Check single file](#check-single-file)
- [Check all markdown files](#check-all-markdown-files)
- [.github/workflows/links.yml](#githubworkflowslinksyml)
- [4. Spelling and Grammar](#4-spelling-and-grammar)
- [Install](#install)
- [Check spelling](#check-spelling)
- [Custom dictionary (.cspell.json)](#custom-dictionary-cspelljson)
- [Using LanguageTool (requires Java)](#using-languagetool-requires-java)
- [Download from https://languagetool.org/](#download-from-httpslanguagetoolorg)
- [Check grammar](#check-grammar)
- [5. Accessibility Testing](#5-accessibility-testing)
- [Install textstat](#install-textstat)
- [Check readability (Python)](#check-readability-python)
- [Target: Grade 8-10 for technical docs](#target-grade-8-10-for-technical-docs)
- [Check for images without alt text](#check-for-images-without-alt-text)
- [Should return empty (all images should have alt text)](#should-return-empty-all-images-should-have-alt-text)
- [Verify proper heading hierarchy](#verify-proper-heading-hierarchy)
- [5a. WCAG 3.0 Preview (January 2026)](#5a-wcag-30-preview-january-2026)
- [WCAG 3.0 Documentation Checklist (Preview)](#wcag-30-documentation-checklist-preview)
- [Content Structure](#content-structure)
- [Cognitive Accessibility](#cognitive-accessibility)
- [Visual Accessibility](#visual-accessibility)
- [Interactive Elements](#interactive-elements)
- [5b. AI-Powered Documentation Linting (January 2026)](#5b-ai-powered-documentation-linting-january-2026)
- [Example AI linting rules in plain English](#example-ai-linting-rules-in-plain-english)
- [Mintlify automatically:](#mintlify-automatically)
- [- Checks for broken links](#checks-for-broken-links)
- [- Suggests content improvements](#suggests-content-improvements)
- [- Validates code examples](#validates-code-examples)
- [- Ensures consistent terminology](#ensures-consistent-terminology)
- [6. Completeness Testing](#6-completeness-testing)
- [Documentation Coverage Checklist](#documentation-coverage-checklist)
- [Code Coverage](#code-coverage)
- [Example Coverage](#example-coverage)
- [Process Coverage](#process-coverage)
- [Reference Coverage](#reference-coverage)
- [List all exported functions](#list-all-exported-functions)
- [List documented functions](#list-documented-functions)
- [Find undocumented functions (compare both lists)](#find-undocumented-functions-compare-both-lists)
- [7. Consistency Testing](#7-consistency-testing)
- [Check for inconsistent terms](#check-for-inconsistent-terms)
- [Bad: "log in" vs "login" vs "sign in"](#bad-log-in-vs-login-vs-sign-in)
- [Create a terminology guide](#create-a-terminology-guide)
- [Terminology Guide](#terminology-guide)
- [Check code block language tags](#check-code-block-language-tags)
- [All code blocks should have language specified](#all-code-blocks-should-have-language-specified)
- [8. Freshness Testing](#8-freshness-testing)
- [Find files not updated in 6+ months](#find-files-not-updated-in-6-months)
- [Version mentions (check if outdated)](#version-mentions-check-if-outdated)
- [Dates in documentation](#dates-in-documentation)
- [Check last commit date for each doc](#check-last-commit-date-for-each-doc)
- [CI/CD Integration](#cicd-integration)
- [GitHub Actions Workflow](#github-actions-workflow)
- [.github/workflows/docs-quality.yml](#githubworkflowsdocs-qualityyml)
- [Manual Testing Checklist](#manual-testing-checklist)
- [Pre-Release Documentation Review](#pre-release-documentation-review)
- [Documentation QA Checklist](#documentation-qa-checklist)
- [Technical Accuracy](#technical-accuracy)
- [Clarity and Usability](#clarity-and-usability)
- [Completeness](#completeness)
- [Quality](#quality)
- [Maintainability](#maintainability)
- [Testing Tools Summary](#testing-tools-summary)
- [Best Practices](#best-practices)
- [1. Test Documentation Like Code](#1-test-documentation-like-code)
- [Treat docs as first-class citizens](#treat-docs-as-first-class-citizens)
- [2. Document the "Why", Not Just the "What"](#2-document-the-why-not-just-the-what)
- [Configuration](#configuration)
- [Configuration](#configuration)
- [3. Keep Examples Testable](#3-keep-examples-testable)
- [4. Update Docs With Code Changes](#4-update-docs-with-code-changes)
- [Git hook to remind about docs](#git-hook-to-remind-about-docs)
- [.git/hooks/pre-commit](#githookspre-commit)
- [5. Version Documentation With Code](#5-version-documentation-with-code)
- [Tag docs with releases](#tag-docs-with-releases)
- [Maintain versioned docs (for breaking changes)](#maintain-versioned-docs-for-breaking-changes)
- [Metrics and Monitoring](#metrics-and-monitoring)
- [Documentation Health Dashboard](#documentation-health-dashboard)
- [Documentation Health Metrics](#documentation-health-metrics)
- [Freshness](#freshness)
- [Quality](#quality)
- [Coverage](#coverage)
- [Accuracy](#accuracy)
- [Common Issues and Fixes](#common-issues-and-fixes)
- [Issue: Code Examples Fail After Updates](#issue-code-examples-fail-after-updates)
- [Extract code blocks and test them](#extract-code-blocks-and-test-them)
- [Issue: Documentation Drift](#issue-documentation-drift)
- [Issue: Inconsistent Terminology](#issue-inconsistent-terminology)
- [styles/Vocab/accept.txt (Vale custom vocabulary)](#stylesvocabaccepttxt-vale-custom-vocabulary)
- [Resources](#resources)
- [Tools](#tools)
- [Style Guides](#style-guides)
- [Testing Frameworks](#testing-frameworks)
## Why Test Documentation?
Documentation testing ensures:
- **Accuracy** - Code examples work as shown
- **Completeness** - All features are documented
- **Clarity** - Users can follow instructions
- **Maintainability** - Docs stay in sync with code
- **Accessibility** - Content is usable by all readers
---
## Testing Categories
### 1. Technical Accuracy Testing
**Verify code examples actually work:**
```bash
# Extract code blocks from documentation
grep -A 10 '```javascript' README.md > examples.js
# Run extracted code
node examples.js
# Automated example testing
npm install -g markdown-code-runner
markdown-code-runner README.md
```
**API Documentation Testing:**
```bash
# Test API endpoints from docs
curl -X GET "https://api.example.com/v1/users" \
-H "Authorization: Bearer test-token"
# Expected: 200 OK with user list
# Actual: [verify against documentation]
```
**Setup Instructions Testing:**
```bash
# Fresh clone in isolated environment
docker run -it ubuntu:latest bash
# Follow documentation step-by-step
git clone https://github.com/username/repo.git
cd repo
# [Follow README.md installation steps...]
# Document any failures or unclear steps
```
---
### 2. Automated Linting
**Markdown Linting (markdownlint):**
```bash
# Install
npm install -g markdownlint-cli
# Run linter
markdownlint '**/*.md' --ignore node_modules
# With configuration
cat > .markdownlint.json << EOF
{
"default": true,
"MD013": { "line_length": 120 },
"MD024": { "siblings_only": true },
"MD033": false
}
EOF
markdownlint -c .markdownlint.json '**/*.md'
```
**Common Rules:**
- **MD001** - Header levels increment by 1
- **MD013** - Line length limit
- **MD024** - No duplicate headers
- **MD033** - No inline HTML
- **MD034** - No bare URLs
**Prose Linting (Vale):**
```bash
# Install Vale
brew install vale # macOS
# or download from https://vale.sh/
# Initialize configuration
vale sync
# Create .vale.ini
cat > .vale.ini << EOF
StylesPath = styles
MinAlertLevel = suggestion
[*.md]
BasedOnStyles = Vale, Google
EOF
# Run Vale
vale docs/
# Output example:
# docs/api.md
# 15:6 warning 'utilize' is wordy. Consider Vale.Wordiness
# replacing with 'use'.
# 23:1 error Use 'API' instead of 'api'. Google.Acronyms
```
**Vale Style Packs:**
- **Vale** - Built-in style rules
- **Google** - Google Developer Style Guide
- **Microsoft** - Microsoft Writing Style Guide
- **write-good** - General writing quality
**Language Quality (write-good):**
```bash
# Install
npm install -g write-good
# Test documentation
write-good README.md
# Output:
# README.md
# line 12: 'very' is wordy or unneeded
# line 23: 'basically' is wordy or unneeded
# line 45: 'obviously' is a weasel word
```
**Inclusive Language (alex):**
```bash
# Install
npm install -g alex
# Check for insensitive language
alex docs/
# Output:
# docs/README.md
# 12:5-12:9 warning 'guys' may be insensitive, use 'people' instead
```
---
### 3. Link Validation
**Check Broken Links:**
```bash
# Install markdown-link-check
npm install -g markdown-link-check
# Check single file
markdown-link-check README.md
# Check all markdown files
find . -name "*.md" -not -path "./node_modules/*" \
-exec markdown-link-check {} \;
```
**GitHub Action for Link Checking:**
```yaml
# .github/workflows/links.yml
name: Check Links
on:
push:
branches: [main]
pull_request:
paths:
- '**/*.md'
jobs:
markdown-link-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: gaurav-nelson/github-action-markdown-link-check@v1
with:
use-quiet-mode: 'yes'
use-verbose-mode: 'yes'
config-file: '.markdown-link-check.json'
```
**Link Check Configuration (.markdown-link-check.json):**
```json
{
"ignorePatterns": [
{
"pattern": "^http://localhost"
},
{
"pattern": "^https://example.com"
}
],
"timeout": "20s",
"retryOn429": true,
"retryCount": 3,
"fallbackRetryDelay": "30s"
}
```
---
### 4. Spelling and Grammar
**Spell Checking (cspell):**
```bash
# Install
npm install -g cspell
# Check spelling
cspell "docs/**/*.md"
# Custom dictionary (.cspell.json)
cat > .cspell.json << EOF
{
"version": "0.2",
"language": "en",
"words": [
"fastify",
"postgres",
"redis",
"webhook"
],
"ignoreRegExpList": [
"/```[\\s\\S]*?```/g",
"/`[^`]*`/g"
]
}
EOF
```
**Grammar Checking:**
```bash
# Using LanguageTool (requires Java)
# Download from https://languagetool.org/
# Check grammar
languagetool -l en-US README.md
```
---
### 5. Accessibility Testing
**Readability Scoring:**
```bash
# Install textstat
pip install textstat
# Check readability (Python)
python << EOF
import textstat
with open('README.md', 'r') as f:
text = f.read()
print(f"Flesch Reading Ease: {textstat.flesch_reading_ease(text)}")
print(f"Grade Level: {textstat.flesch_kincaid_grade(text)}")
# Target: Grade 8-10 for technical docs
EOF
```
**Flesch Reading Ease Scale:**
- 90-100: Very Easy (5th grade)
- 80-89: Easy (6th grade)
- 70-79: Fairly Easy (7th grade)
- 60-69: Standard (8th-9th grade) **Target for technical docs**
- 50-59: Fairly Difficult (10th-12th grade)
- 30-49: Difficult (College)
- 0-29: Very Difficult (Graduate)
**Alt Text Validation:**
```bash
# Check for images without alt text
grep -n "!\[" docs/**/*.md | grep "!\[\]"
# Should return empty (all images should have alt text)
```
**Heading Structure:**
```bash
# Verify proper heading hierarchy
grep -E "^#{1,6} " docs/README.md | sed 's/\(#*\).*/\1/' | cat -n
```
---
### 5a. WCAG 3.0 Preview (January 2026)
WCAG 3.0 is in Working Draft status (expected completion 2027-2028). Key changes relevant to documentation:
**From Pass/Fail to Outcome Scoring:**
WCAG 3.0 uses a 0-4 scale instead of binary pass/fail:
- **0**: Very poor (critical barrier)
- **1**: Poor (significant barrier)
- **2**: Fair (some barriers)
- **3**: Good (minor issues)
- **4**: Excellent (fully accessible)
**New Structure:**
```text
WCAG 2.x: Principles → Guidelines → Success Criteria
WCAG 3.0: Guidelines → Outcomes → Methods → How-To Guides
```
**Functional Categories:**
WCAG 3.0 expands disability coverage with functional categories:
- Vision (blindness, low vision, color blindness)
- Hearing (deafness, hard of hearing)
- Motor (limited fine motor, limited gross motor)
- Cognitive (memory, attention, language, learning)
- Speech (non-verbal, speech impairments)
**Documentation-Specific Considerations:**
```markdown
## WCAG 3.0 Documentation Checklist (Preview)
### Content Structure
- [ ] Logical heading hierarchy (supports screen readers)
- [ ] Table headers properly marked (scope attributes)
- [ ] Lists use semantic markup (ul/ol, not manual bullets)
- [ ] Code blocks have language identification
### Cognitive Accessibility
- [ ] Plain language used (avoid jargon without definitions)
- [ ] Consistent navigation patterns
- [ ] Clear error messages with recovery steps
- [ ] Chunked content (short paragraphs, bullet points)
### Visual Accessibility
- [ ] Sufficient color contrast (4.5:1 for text)
- [ ] Information not conveyed by color alone
- [ ] Alt text for all images and diagrams
- [ ] Responsive design for zoom/magnification
### Interactive Elements
- [ ] Keyboard accessible (all interactive elements)
- [ ] Focus indicators visible
- [ ] Skip links for navigation
```
**Current Recommendation:**
Continue using WCAG 2.2 as the baseline. Monitor WCAG 3.0 Working Drafts for planning.
**Resources:**
- WCAG 3.0 Working Draft: https://www.w3.org/TR/wcag-3.0/
- WCAG 3 Introduction: https://www.w3.org/WAI/standards-guidelines/wcag/wcag3-intro/
---
### 5b. AI-Powered Documentation Linting (January 2026)
AI tools now offer advanced documentation quality checks beyond traditional linting.
**AI Linting Capabilities:**
- Write rules in plain English (not regex)
- Context-aware suggestions
- Automated broken link detection
- Style guide enforcement with explanations
- Terminology consistency checking
**ReadMe.com AI Linting (January 2026):**
```yaml
# Example AI linting rules in plain English
rules:
- "Use active voice instead of passive voice"
- "Define technical terms on first use"
- "Include code examples for all API endpoints"
- "Keep sentences under 25 words"
- "Avoid jargon without explanation"
```
**Mintlify AI Features:**
```bash
# Mintlify automatically:
# - Checks for broken links
# - Suggests content improvements
# - Validates code examples
# - Ensures consistent terminology
mintlify check --ai-lint
```
**AI Docs Audit Workflow:**
```text
1. Run automated linting (markdownlint, Vale)
2. Run AI-powered audit (Mintlify, ReadMe)
3. Review AI suggestions
4. Apply improvements
5. Human final review
```
**Comparison: Traditional vs AI Linting:**
| Feature | Traditional (Vale) | AI-Powered |
|---------|-------------------|------------|
| Rule definition | Regex/YAML | Plain English |
| Context awareness | Limited | High |
| False positives | Common | Fewer |
| Custom rules | Complex | Simple |
| Learning | Static | Adaptive |
**Best Practices:**
- Use traditional linting for consistent, rule-based checks
- Use AI linting for context-aware suggestions
- Always human-review AI suggestions before applying
- Combine both for comprehensive coverage
---
### 6. Completeness Testing
**Coverage Checklist:**
```markdown
## Documentation Coverage Checklist
### Code Coverage
- [ ] All public APIs documented
- [ ] All configuration options explained
- [ ] All CLI commands documented
- [ ] All environment variables listed
### Example Coverage
- [ ] "Hello World" example provided
- [ ] Advanced usage examples included
- [ ] Error handling examples shown
- [ ] Edge cases documented
### Process Coverage
- [ ] Installation steps complete
- [ ] Development setup documented
- [ ] Deployment process explained
- [ ] Troubleshooting guide provided
### Reference Coverage
- [ ] API reference complete
- [ ] Configuration reference complete
- [ ] Error code reference available
- [ ] Changelog maintained
```
**API Documentation Audit:**
```bash
# List all exported functions
grep -r "export function" src/ | cut -d: -f2 | sort
# List documented functions
grep -r "^### " docs/api.md | sed 's/### //' | sort
# Find undocumented functions (compare both lists)
comm -23 <(grep -r "export function" src/ | cut -d: -f2 | sort) \
<(grep -r "^### " docs/api.md | sed 's/### //' | sort)
```
---
### 7. Consistency Testing
**Terminology Consistency:**
```bash
# Check for inconsistent terms
# Bad: "log in" vs "login" vs "sign in"
grep -rn "log in\|login\|sign in" docs/
# Create a terminology guide
cat > TERMINOLOGY.md << EOF
# Terminology Guide
- Use "log in" (verb) and "login" (noun/adjective)
- Use "API" not "api" or "Api"
- Use "JavaScript" not "Javascript" or "javascript"
EOF
```
**Style Consistency:**
```bash
# Check code block language tags
grep -n '```' README.md | grep -v '```bash\|```javascript\|```python'
# All code blocks should have language specified
```
---
### 8. Freshness Testing
**Check for Outdated Content:**
```bash
# Find files not updated in 6+ months
find docs/ -name "*.md" -type f -mtime +180 -ls
# Version mentions (check if outdated)
grep -rn "Node.js 14\|Node.js 16" docs/
# Dates in documentation
grep -rn "202[0-3]" docs/
```
**Update Frequency:**
```bash
# Check last commit date for each doc
for file in docs/**/*.md; do
last_update=$(git log -1 --format="%ai" -- "$file")
echo "$file: $last_update"
done
```
---
## CI/CD Integration
### GitHub Actions Workflow
```yaml
# .github/workflows/docs-quality.yml
name: Documentation Quality
on:
pull_request:
paths:
- 'docs/**'
- '*.md'
jobs:
lint-markdown:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Lint Markdown
uses: articulate/actions-markdownlint@v1
with:
config: .markdownlint.json
files: '**/*.md'
ignore: node_modules
check-links:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Check Links
uses: gaurav-nelson/github-action-markdown-link-check@v1
spell-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Spell Check
uses: streetsidesoftware/cspell-action@v2
with:
files: "**/*.md"
test-code-examples:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: '22'
- name: Extract and Test Code Examples
run: |
npm install -g markdown-code-runner
markdown-code-runner docs/**/*.md
```
---
## Manual Testing Checklist
### Pre-Release Documentation Review
```markdown
## Documentation QA Checklist
### Technical Accuracy
- [ ] All code examples compile/run
- [ ] All commands execute successfully
- [ ] All URLs are accessible
- [ ] All screenshots are current
- [ ] Version numbers are correct
### Clarity and Usability
- [ ] Prerequisites are clear
- [ ] Installation steps are complete
- [ ] First-time users can follow successfully
- [ ] Common questions are addressed
- [ ] Error messages are explained
### Completeness
- [ ] New features are documented
- [ ] Breaking changes are highlighted
- [ ] Migration guides provided (if needed)
- [ ] Changelog updated
- [ ] API reference is complete
### Quality
- [ ] No spelling errors
- [ ] No grammar errors
- [ ] Consistent terminology
- [ ] Proper heading hierarchy
- [ ] Alt text for all images
### Maintainability
- [ ] Docs are in version control
- [ ] Clear ownership documented
- [ ] Update process defined
- [ ] Automated tests pass
```
---
## Testing Tools Summary
| Tool | Purpose | Command |
|------|---------|---------|
| **markdownlint** | Markdown syntax/style | `markdownlint '**/*.md'` |
| **Vale** | Prose quality + style guides | `vale docs/` |
| **write-good** | Writing quality | `write-good README.md` |
| **alex** | Inclusive language | `alex docs/` |
| **cspell** | Spell checking | `cspell "docs/**/*.md"` |
| **markdown-link-check** | Broken links | `markdown-link-check README.md` |
| **textstat** | Readability scoring | Python library |
| **doctoc** | Table of contents | `doctoc README.md` |
---
## Best Practices
### 1. Test Documentation Like Code
```bash
# Treat docs as first-class citizens
.
├── .github/
│ └── workflows/
│ ├── tests.yml # Code tests
│ └── docs.yml # Doc tests [OK]
├── src/
├── tests/
└── docs/
└── tests/ # Documentation tests [OK]
├── test-examples.sh
└── verify-links.sh
```
### 2. Document the "Why", Not Just the "What"
```markdown
<!-- [FAIL] Bad - Only explains WHAT -->
## Configuration
Set `MAX_CONNECTIONS` to 100.
<!-- GOOD - Explains WHY -->
## Configuration
Set `MAX_CONNECTIONS` to 100.
**Why:** The default of 10 causes connection pool exhaustion under load.
Our production workload typically requires 50-80 concurrent connections,
so 100 provides a safety margin while avoiding resource waste.
```
### 3. Keep Examples Testable
```javascript
// BAD: Bad - Pseudo-code that won't run
const user = await fetchUser()
// ... handle result
// GOOD: Good - Complete, runnable example
const { Client } = require('@yourorg/sdk')
async function example() {
const client = new Client({ apiKey: process.env.API_KEY })
try {
const user = await client.users.fetch('123')
console.log('User:', user.email)
} catch (error) {
console.error('Failed to fetch user:', error.message)
process.exit(1)
}
}
example()
```
### 4. Update Docs With Code Changes
```bash
# Git hook to remind about docs
# .git/hooks/pre-commit
#!/bin/bash
if git diff --cached --name-only | grep -q "^src/"; then
if ! git diff --cached --name-only | grep -q "^docs/"; then
echo "[WARNING] Warning: You modified code but not documentation"
echo " Consider updating docs/ if needed"
echo ""
read -p "Continue anyway? (y/n) " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
exit 1
fi
fi
fi
```
### 5. Version Documentation With Code
```bash
# Tag docs with releases
git tag -a v1.0.0 -m "Release v1.0.0"
git push origin v1.0.0
# Maintain versioned docs (for breaking changes)
docs/
├── v1.0/
├── v2.0/
└── latest/ -> v2.0/
```
---
## Metrics and Monitoring
### Documentation Health Dashboard
Track these metrics:
```markdown
## Documentation Health Metrics
### Freshness
- **Last Updated**: [Date]
- **Files >6 months old**: 3 / 47 (6%)
- **Status**: [GREEN] Healthy
### Quality
- **Broken Links**: 0
- **Spelling Errors**: 2
- **Readability Score**: 65 (8th grade) [OK]
- **Status**: [GREEN] Healthy
### Coverage
- **Documented APIs**: 94 / 98 (96%)
- **Code Examples**: 89 / 98 (91%)
- **Status**: [YELLOW] Needs Improvement
### Accuracy
- **Failing Examples**: 0 / 45 (0%)
- **User-Reported Issues**: 2 open
- **Status**: [GREEN] Healthy
```
---
## Common Issues and Fixes
### Issue: Code Examples Fail After Updates
**Solution:** Add automated testing
```bash
# Extract code blocks and test them
cat > test-docs.sh << 'EOF'
#!/bin/bash
set -e
echo "Testing README examples..."
grep -A 20 '```bash' README.md | sed '/```/d' | bash
echo "Testing API docs..."
node test-api-examples.js
echo "[OK] All doc examples passed"
EOF
chmod +x test-docs.sh
./test-docs.sh
```
### Issue: Documentation Drift
**Solution:** CI checks that fail the build
```yaml
- name: Verify API Docs Match Code
run: |
npm run generate-api-docs
git diff --exit-code docs/api.md
```
### Issue: Inconsistent Terminology
**Solution:** Create terminology glossary + Vale rules
```yaml
# styles/Vocab/accept.txt (Vale custom vocabulary)
API
JavaScript
PostgreSQL
webhook
```
---
## Resources
### Tools
- **Vale**: https://vale.sh/
- **markdownlint**: https://github.com/DavidAnson/markdownlint
- **write-good**: https://github.com/btford/write-good
- **cspell**: https://github.com/streetsidesoftware/cspell
- **markdown-link-check**: https://github.com/tcort/markdown-link-check
### Style Guides
- **Google Developer Docs**: https://developers.google.com/style
- **Microsoft Style Guide**: https://learn.microsoft.com/en-us/style-guide/
- **Write the Docs**: https://www.writethedocs.org/guide/
### Testing Frameworks
- **Doctest (Python)**: https://docs.python.org/3/library/doctest.html
- **JSDoc + Jest**: https://jestjs.io/docs/configuration#testmatch-arraystring
---
> **Success Criteria:** Documentation is accurate, clear, complete, maintainable, and provides value to users with minimal confusion or support tickets.
references/markdown-style-guide.md
# Markdown Style Guide
Comprehensive guide to writing clear, consistent, and accessible Markdown documentation.
## Table of Contents
- [Basic Syntax](#basic-syntax)
- [Extended Syntax](#extended-syntax)
- [Best Practices](#best-practices)
- [Common Pitfalls](#common-pitfalls)
- [Accessibility](#accessibility)
- [Tools and Linters](#tools-and-linters)
---
## Basic Syntax
### Headings
Use ATX-style headings (# symbols) with a space after the #.
**Good:**
```markdown
# Heading 1
## Heading 2
### Heading 3
```
**Bad:**
```markdown
#Heading 1 # Missing space
##Heading 2 # Missing space
Heading 1 # Setext-style (inconsistent)
=========
```
**Rules:**
- Only one H1 per document
- Don't skip heading levels (H1 → H3)
- Use sentence case, not title case
- Don't put punctuation at the end
### Paragraphs
Separate paragraphs with a blank line.
**Good:**
```markdown
This is the first paragraph.
This is the second paragraph.
```
**Bad:**
```markdown
This is the first paragraph.
This is the second paragraph.
```
### Line Breaks
Use two trailing spaces or `<br>` for hard line breaks (avoid if possible).
**Soft wrap (preferred):**
```markdown
This is a long paragraph that will wrap automatically based on the viewer's window size.
```
**Hard break (only when needed):**
```markdown
Line 1
Line 2
```
### Emphasis
**Bold:**
```markdown
**bold text**
__also bold__
```
**Italic:**
```markdown
*italic text*
_also italic_
```
**Bold and italic:**
```markdown
***bold and italic***
___also bold and italic___
```
**Strikethrough (GitHub Flavored Markdown):**
```markdown
~~strikethrough~~
```
**Recommendation:** Use `**` for bold and `*` for italic (more widely supported).
### Lists
#### Unordered Lists
Use `-`, `*`, or `+` (be consistent).
**Good:**
```markdown
- Item 1
- Item 2
- Nested item 2.1
- Nested item 2.2
- Item 3
```
**Bad:**
```markdown
- Item 1
* Item 2 # Mixed markers
- Nested item
- Nested item # Incorrect indentation
```
**Rules:**
- Use 2 or 4 spaces for nesting (be consistent)
- Add blank lines before and after lists
- Use `-` as the default marker
#### Ordered Lists
Use numbers followed by a period.
**Good:**
```markdown
1. First item
2. Second item
3. Third item
```
**Also acceptable (lazy numbering):**
```markdown
1. First item
1. Second item
1. Third item
```
**Bad:**
```markdown
1) First item # Wrong delimiter
2) Second item
```
#### Task Lists (GitHub Flavored Markdown)
```markdown
- [ ] Unchecked task
- [x] Checked task
```
### Links
#### Inline Links
```markdown
[Link text](https://example.com)
[Link with title](https://example.com "Hover text")
```
#### Reference Links
```markdown
This is a [reference link][ref].
[ref]: https://example.com "Title"
```
#### Automatic Links
```markdown
<https://example.com>
<email@example.com>
```
**Best practices:**
- Use descriptive link text (not "click here")
- Add titles for additional context
- Use reference links for repeated URLs
### Images
```markdown


```
**With reference:**
```markdown
![Alt text][logo]
[logo]: /path/to/logo.png "Logo title"
```
**Best practices:**
- Always include alt text for accessibility
- Use descriptive file names
- Optimize image sizes
### Code
#### Inline Code
```markdown
Use `backticks` for inline code.
```
#### Code Blocks
**Fenced code blocks (preferred):**
````markdown
```javascript
function hello() {
console.log('Hello, world!');
}
```
````
**With syntax highlighting:**
````markdown
```python
def hello():
print("Hello, world!")
```
````
**Indented code blocks (avoid):**
```markdown
# Less clear
function hello() {
console.log('Hello');
}
```
**Best practices:**
- Always specify language for syntax highlighting
- Keep code examples concise and relevant
- Test code examples before publishing
### Blockquotes
```markdown
> This is a blockquote.
>
> It can span multiple paragraphs.
>
> > Nested blockquote
```
### Horizontal Rules
```markdown
---
***
___
```
**Recommendation:** Use `---` for consistency.
---
## Extended Syntax
### Tables
```markdown
| Header 1 | Header 2 | Header 3 |
|----------|----------|----------|
| Cell 1 | Cell 2 | Cell 3 |
| Cell 4 | Cell 5 | Cell 6 |
```
**With alignment:**
```markdown
| Left align | Center align | Right align |
|:-----------|:------------:|------------:|
| Left | Center | Right |
```
**Best practices:**
- Align pipes for readability
- Keep tables simple (use HTML for complex tables)
- Add blank lines before and after tables
### Footnotes
```markdown
Here's a sentence with a footnote[^1].
[^1]: This is the footnote text.
```
### Definition Lists
```markdown
Term 1
: Definition 1
Term 2
: Definition 2a
: Definition 2b
```
### Emoji (GitHub Flavored Markdown)
```markdown
:smile: :heart: :thumbsup:
```
**Recommendation:** Use sparingly in technical documentation.
### Admonitions (Some renderers)
```markdown
!!! note
This is a note.
!!! warning
This is a warning.
```
---
## Best Practices
### 1. Use Consistent Formatting
**Bad:**
```markdown
# Title
some text
##Another Heading
More text without spacing.
- list item
* different marker
```
**Good:**
```markdown
# Title
Some text with proper spacing.
## Another Heading
More text with consistent formatting.
- List item
- Same marker throughout
```
### 2. Keep Line Length Reasonable
**Recommendation:** 80-120 characters per line for readability.
**Good:**
```markdown
This is a reasonably short line that wraps naturally and is easy to read
in any editor or viewer.
```
**Bad:**
```markdown
This is an extremely long line that goes on and on and on and makes it difficult to read in narrow viewports or when viewing diffs and really should be broken up into smaller chunks for better readability.
```
### 3. Use Descriptive Link Text
**Bad:**
```markdown
Click [here](https://example.com) for more information.
```
**Good:**
```markdown
See the [installation guide](https://example.com/install) for setup instructions.
```
### 4. Add Blank Lines for Readability
**Bad:**
```markdown
# Heading
Text immediately after heading.
## Another Heading
More text without spacing.
- List item
- Another item
```
**Good:**
```markdown
# Heading
Text with proper spacing.
## Another Heading
More text with good visual separation.
- List item
- Another item
```
### 5. Use Semantic Headings
**Bad:**
```markdown
# Title
### Skipped H2
## Wrong Order
```
**Good:**
```markdown
# Title
## Section 1
### Subsection 1.1
## Section 2
```
### 6. Include Table of Contents for Long Documents
```markdown
## Table of Contents
- [Section 1](#section-1)
- [Section 2](#section-2)
- [Subsection 2.1](#subsection-21)
```
### 7. Use Code Blocks with Syntax Highlighting
**Bad:**
````markdown
```
function hello() {
console.log('Hello');
}
```
````
**Good:**
````markdown
```javascript
function hello() {
console.log('Hello');
}
```
````
### 8. Test Links Before Publishing
Use tools like `markdown-link-check`:
```bash
npx markdown-link-check README.md
```
---
## Common Pitfalls
### 1. Mixing Markdown Flavors
Different renderers support different features. Stick to CommonMark for maximum compatibility.
**Problematic:**
```markdown
==highlight== # Not widely supported
```
**Safe alternative:**
```markdown
**highlight** # Works everywhere
```
### 2. Incorrect List Indentation
**Wrong:**
```markdown
- Item 1
- Nested item # Only 1 space
- Deep nested # 3 spaces
```
**Correct:**
```markdown
- Item 1
- Nested item # 2 spaces
- Deep nested # 4 spaces
```
### 3. Missing Alt Text for Images
**Bad:**
```markdown

```
**Good:**
```markdown

```
### 4. Using HTML When Markdown Would Work
**Bad:**
```markdown
<strong>Bold text</strong>
<em>Italic text</em>
```
**Good:**
```markdown
**Bold text**
*Italic text*
```
**When to use HTML:** Complex tables, specific styling needs, embedding media.
---
## Accessibility
### 1. Use Descriptive Alt Text
```markdown
# Bad

# Good

```
### 2. Use Semantic Headings
- Only one H1 per document
- Don't skip levels (H1 → H3)
- Use headings for structure, not styling
### 3. Descriptive Link Text
```markdown
# Bad
[Click here](https://example.com)
# Good
[Read the installation guide](https://example.com/install)
```
### 4. Provide Text Alternatives for Diagrams
```markdown

**Text description:** The system consists of three layers: presentation (web UI),
application (API server), and data (PostgreSQL database).
```
### 5. Use Tables Appropriately
- Add header row
- Keep tables simple
- Provide alternative formats for complex data
---
## Tools and Linters
### markdownlint
```bash
# Install
npm install -g markdownlint-cli
# Lint files
markdownlint README.md
# Fix automatically
markdownlint --fix README.md
```
**Configuration (.markdownlint.json):**
```json
{
"default": true,
"MD013": false,
"MD033": false
}
```
### markdown-link-check
```bash
# Install
npm install -g markdown-link-check
# Check links
markdown-link-check README.md
```
### Vale
```bash
# Install
brew install vale
# Lint prose
vale README.md
```
### Prettier
```bash
# Install
npm install -g prettier
# Format Markdown
prettier --write "**/*.md"
```
---
## Quick Reference
### Headers
```markdown
# H1
## H2
### H3
```
### Emphasis
```markdown
**bold**
*italic*
***bold italic***
```
### Lists
```markdown
- Unordered item
- Another item
1. Ordered item
2. Another item
```
### Links and Images
```markdown
[Link text](https://example.com)

```
### Code
````markdown
`inline code`
```language
code block
```
````
### Blockquotes and Rules
```markdown
> Blockquote
---
```
### Tables
```markdown
| Header 1 | Header 2 |
|----------|----------|
| Cell 1 | Cell 2 |
```
---
## Resources
- [CommonMark Specification](https://commonmark.org/)
- [GitHub Flavored Markdown](https://github.github.com/gfm/)
- [Markdown Guide](https://www.markdownguide.org/)
- [markdownlint Rules](https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md)
- [Google Developer Documentation Style Guide](https://developers.google.com/style/markdown)
references/onboarding-documentation.md
# Onboarding Documentation
Patterns for developer onboarding docs that reduce time-to-productivity without duplicating existing content.
---
## Table of Contents
- [Onboarding Doc Types](#onboarding-doc-types)
- [Day 1 to Week 4 Structure](#day-1-to-week-4-structure)
- [What to Include vs What to Link](#what-to-include-vs-what-to-link)
- [Buddy and Mentor Documentation](#buddy-and-mentor-documentation)
- [Onboarding Buddy Notes — [New Hire Name]](#onboarding-buddy-notes-—-new-hire-name)
- [Key context to share early](#key-context-to-share-early)
- [Suggested first tickets](#suggested-first-tickets)
- [People to meet](#people-to-meet)
- [Notes from pairing sessions](#notes-from-pairing-sessions)
- [Measuring Effectiveness](#measuring-effectiveness)
- [Templates](#templates)
- [Quickstart Template](#quickstart-template)
- [Quickstart — Get a local build running in under 30 minutes.](#quickstart-—-get-a-local-build-running-in-under-30-minutes)
- [Prerequisites](#prerequisites)
- [Steps](#steps)
- [Troubleshooting](#troubleshooting)
- [Environment Setup Checklist](#environment-setup-checklist)
- [Anti-Patterns](#anti-patterns)
- [Related Resources](#related-resources)
## Onboarding Doc Types
Each type serves a different moment in the ramp-up.
| Doc Type | Purpose | When Used | Owner |
|----------|---------|-----------|-------|
| **Quickstart** | First working build in < 30 min | Day 1, hour 1 | Platform/DevEx team |
| **Environment setup** | Full local dev environment | Day 1-2 | Platform/DevEx team |
| **Architecture walkthrough** | System map and key decisions | Day 2-3 | Tech lead |
| **First PR guide** | End-to-end contribution flow | Day 3-5 | Onboarding buddy |
| **Service catalog** | What each service does, who owns it | Week 1-2 | Engineering org |
| **On-call guide** | Alerting, escalation, runbooks | Week 3-4 | SRE/platform team |
---
## Day 1 to Week 4 Structure
Organize the ramp-up as a checklist, not a wall of text.
**Day 1 -- Build and run:**
- [ ] Clone repo and run quickstart
- [ ] Verify local build passes tests
- [ ] Access Slack channels, Jira board, CI dashboard
- [ ] Meet onboarding buddy
**Day 2-3 -- Understand the system:**
- [ ] Read architecture walkthrough
- [ ] Walk through 2-3 recent PRs with buddy
- [ ] Identify the 3 services you will work in most
- [ ] Read ADRs for those services
**Week 1 -- First contribution:**
- [ ] Pick a `good-first-issue` ticket
- [ ] Follow the first PR guide end-to-end
- [ ] Get PR reviewed, address feedback, merge
- [ ] Attend team standup and retro
**Week 2-3 -- Deepen context:**
- [ ] Read on-call runbooks for your team's services
- [ ] Shadow an on-call shift or incident review
- [ ] Complete a medium-complexity ticket independently
**Week 4 -- Validate and close:**
- [ ] Buddy confirms independent ticket capability
- [ ] Give feedback on the onboarding docs themselves
---
## What to Include vs What to Link
Onboarding docs rot fast when they duplicate content maintained elsewhere. Use this decision guide.
**Include directly:** Steps unique to onboarding (account provisioning, first-day checklist), curated reading order, and context that does not exist elsewhere (team norms, unwritten conventions).
**Link to, never copy:** README setup instructions, ADRs, API reference, CI/CD pipeline docs, on-call runbooks.
**Rule:** If the source doc has its own owner and update cadence, link to it. If you copy it, it will diverge within one quarter.
---
## Buddy and Mentor Documentation
The buddy carries context that is hard to write down. Reduce the bus factor with lightweight handoff notes.
**Buddy handoff template:**
```markdown
## Onboarding Buddy Notes — [New Hire Name]
**Start date:** YYYY-MM-DD | **Buddy:** [Name] | **Team:** [Team]
### Key context to share early
- [Gotcha or unwritten rule #1]
- [Which Slack channels to watch]
### Suggested first tickets
- [JIRA-123] — Good scope, touches the main service
- [JIRA-456] — Small fix, good for learning the PR flow
### People to meet
- [Name] — Owns [service], good for architecture questions
### Notes from pairing sessions
- [Date]: [Topic]. [What they understood / what needs follow-up]
```
Keep these notes in a private doc (Notion, Google Doc), not in the repo. They contain names and are time-bound.
---
## Measuring Effectiveness
Track these to know if onboarding docs are working.
| Metric | Target | How to Measure |
|--------|--------|----------------|
| Time to first PR merged | < 5 business days | Git log: first commit by new hire |
| Self-service resolution rate | > 70% of setup questions | Survey or Slack thread analysis |
| Onboarding doc feedback score | > 4/5 | End-of-week-1 survey |
| Setup issues reported | < 2 per new hire | Slack #onboarding channel |
| Time to independent ticket completion | < 3 weeks | Jira data |
**Feedback loop:** Every new hire edits or flags at least one onboarding doc issue before week 4 ends. This keeps docs current and gives the new hire agency.
---
## Templates
### Quickstart Template
```markdown
# Quickstart — Get a local build running in under 30 minutes.
## Prerequisites
- [Language] [version]+
- [Tool] [version]+
- Access to [VPN / internal registry] (request via [link])
## Steps
1. Clone: `git clone [repo-url] && cd [repo-name]`
2. Install: `[install command]`
3. Configure: `cp .env.example .env` — see [config guide] for values
4. Run: `[run command]`
5. Verify: Open [URL]. You should see [expected result].
## Troubleshooting
- **[Common error]**: [Fix]
- Still stuck? Ask in #[slack-channel].
```
### Environment Setup Checklist
```markdown
- [ ] IDE installed and configured ([link to IDE settings])
- [ ] Git configured (name, email, GPG signing)
- [ ] SSH key added to GitHub
- [ ] VPN and internal package registry authenticated
- [ ] Docker Desktop running, local database seeded
- [ ] All tests pass locally
- [ ] CI dashboard accessible
- [ ] Slack channels joined: #[team], #[engineering], #[incidents]
```
---
## Anti-Patterns
- **Info dump.** A 50-page onboarding doc nobody reads. Break it into the checklist structure above. No single doc should exceed 2 pages of content the reader must act on.
- **Stale quickstart.** The most common onboarding failure. If the quickstart does not work on a clean machine, nothing else matters. Test it monthly.
- **Tribal knowledge gates.** "Ask Sarah, she knows how that works." If it is not written down, it does not scale. The buddy handoff template exists to capture this.
- **Duplicated setup instructions.** Quickstart copies the README, then both diverge. Link to the README. One source of truth.
- **No feedback loop.** New hires silently struggle. Require every new hire to file at least one doc improvement by week 4.
- **Onboarding docs owned by nobody.** Assign an explicit owner. Review quarterly. Stale onboarding docs are worse than no onboarding docs because they erode trust.
---
## Related Resources
- [readme-best-practices.md](readme-best-practices.md) - README standards to link from quickstart
- [contributing-guide-standards.md](contributing-guide-standards.md) - First PR workflow patterns
- [production-gotchas-guide.md](production-gotchas-guide.md) - Tribal knowledge documentation
references/production-gotchas-guide.md
# Production Gotchas Documentation Guide
How to document platform-specific issues, known limitations, and production quirks that developers need to know.
---
## Table of Contents
- [What Are Production Gotchas?](#what-are-production-gotchas)
- [Why Document Gotchas?](#why-document-gotchas)
- [Gotcha Documentation Template](#gotcha-documentation-template)
- [[Short Title]](#short-title)
- [The Problem](#the-problem)
- [Why It Happens](#why-it-happens)
- [The Fix / Workaround](#the-fix-workaround)
- [How to Detect](#how-to-detect)
- [References](#references)
- [Categories of Gotchas](#categories-of-gotchas)
- [1. Infrastructure Gotchas](#1-infrastructure-gotchas)
- [AWS RDS Connection Limits](#aws-rds-connection-limits)
- [The Problem](#the-problem)
- [The Fix](#the-fix)
- [How to Detect](#how-to-detect)
- [2. Third-Party API Gotchas](#2-third-party-api-gotchas)
- [Stripe Webhook Retry Behavior](#stripe-webhook-retry-behavior)
- [The Problem](#the-problem)
- [The Fix](#the-fix)
- [How to Detect](#how-to-detect)
- [3. Language/Framework Gotchas](#3-languageframework-gotchas)
- [Node.js Event Loop Blocking](#nodejs-event-loop-blocking)
- [The Problem](#the-problem)
- [The Fix](#the-fix)
- [How to Detect](#how-to-detect)
- [4. Database Gotchas](#4-database-gotchas)
- [PostgreSQL VACUUM Not Running](#postgresql-vacuum-not-running)
- [The Problem](#the-problem)
- [The Fix](#the-fix)
- [How to Detect](#how-to-detect)
- [5. Environment Gotchas](#5-environment-gotchas)
- [Docker DNS Resolution Delay](#docker-dns-resolution-delay)
- [The Problem](#the-problem)
- [The Fix](#the-fix)
- [How to Detect](#how-to-detect)
- [Where to Store Gotchas](#where-to-store-gotchas)
- [Option 1: Dedicated Gotchas File](#option-1-dedicated-gotchas-file)
- [Option 2: Inline with Related Docs](#option-2-inline-with-related-docs)
- [Payment Service](#payment-service)
- [API Reference](#api-reference)
- [Known Issues & Gotchas](#known-issues-&-gotchas)
- [Stripe Webhook Retries](#stripe-webhook-retries)
- [Currency Rounding](#currency-rounding)
- [Option 3: In CLAUDE.md](#option-3-in-claudemd)
- [Project CLAUDE.md](#project-claudemd)
- [Critical Gotchas](#critical-gotchas)
- [Gotcha Review Process](#gotcha-review-process)
- [When to Add](#when-to-add)
- [Review Checklist](#review-checklist)
- [Maintenance](#maintenance)
- [Integration with Incident Management](#integration-with-incident-management)
- [Post-Incident Template Addition](#post-incident-template-addition)
- [Incident Retro: [INC-123]](#incident-retro-inc-123)
- [Gotcha Documentation](#gotcha-documentation)
- [Link to Incidents](#link-to-incidents)
- [Memory Leak in Image Processing](#memory-leak-in-image-processing)
- [Anti-Patterns](#anti-patterns)
- [Don't Do This](#dont-do-this)
- [Database Issues](#database-issues)
- [Do This Instead](#do-this-instead)
- [PostgreSQL Slow Queries After Bulk Insert](#postgresql-slow-queries-after-bulk-insert)
- [The Problem](#the-problem)
- [The Fix](#the-fix)
- [How to Detect](#how-to-detect)
- [Related Resources](#related-resources)
## What Are Production Gotchas?
Production gotchas are:
- Platform-specific behaviors that differ from documentation
- Known limitations or edge cases
- Environment-specific configuration requirements
- "Tribal knowledge" that causes production incidents when forgotten
---
## Why Document Gotchas?
| Problem | Cost | Prevention |
|---------|------|------------|
| Repeated incidents | Hours of debugging | Document once, reference forever |
| Onboarding delays | Days of context-building | New devs find answers in docs |
| Knowledge silos | Single point of failure | Shared documentation |
| Post-incident amnesia | Same bugs recur | Permanent record |
---
## Gotcha Documentation Template
```markdown
## [Short Title]
**Severity**: Critical / High / Medium / Low
**Affects**: [service/component/environment]
**Last Verified**: YYYY-MM-DD
### The Problem
[Clear description of the unexpected behavior]
### Why It Happens
[Root cause explanation]
### The Fix / Workaround
[Step-by-step solution]
### How to Detect
[Symptoms, error messages, monitoring alerts]
### References
- [Link to related incident]
- [Link to upstream issue]
- [Link to documentation]
```
---
## Categories of Gotchas
### 1. Infrastructure Gotchas
```markdown
## AWS RDS Connection Limits
**Severity**: High
**Affects**: All services using RDS
### The Problem
RDS `db.t3.medium` has max 90 connections. With 3 replicas × 20 pool size = 60 connections per service. Two services = 120 connections → connection refused errors.
### The Fix
- Use `db.t3.large` (145 max connections) OR
- Reduce pool size to 15 per service OR
- Use RDS Proxy for connection pooling
### How to Detect
- Error: `FATAL: too many connections for role`
- CloudWatch: `DatabaseConnections` > 85
```
### 2. Third-Party API Gotchas
```markdown
## Stripe Webhook Retry Behavior
**Severity**: Medium
**Affects**: Payment processing
### The Problem
Stripe retries failed webhooks for up to 3 days with exponential backoff. If your endpoint returns 500 during deployment, you'll get duplicate events hours later.
### The Fix
1. Implement idempotency using `event.id`
2. Store processed event IDs in Redis (TTL: 72 hours)
3. Return 200 immediately, process async
### How to Detect
- Duplicate `payment_intent.succeeded` events
- Customer charged multiple times
```
### 3. Language/Framework Gotchas
```markdown
## Node.js Event Loop Blocking
**Severity**: High
**Affects**: API response times
### The Problem
Synchronous operations (JSON.parse on large payloads, crypto operations) block the event loop. A 50MB JSON parse blocks ALL requests for 200ms+.
### The Fix
- Stream large JSON with `JSONStream`
- Use worker threads for crypto
- Set payload limits: `express.json({ limit: '1mb' })`
### How to Detect
- P99 latency spikes
- Event loop lag > 100ms (measure with `perf_hooks`)
```
### 4. Database Gotchas
```markdown
## PostgreSQL VACUUM Not Running
**Severity**: Critical
**Affects**: Database performance
### The Problem
Autovacuum disabled on high-write tables causes table bloat. 10GB table becomes 100GB, queries slow 10x.
### The Fix
1. Enable autovacuum (never disable in prod)
2. Tune: `autovacuum_vacuum_scale_factor = 0.05`
3. Monitor: `pg_stat_user_tables.n_dead_tup`
### How to Detect
- Table size growing without data growth
- `SELECT pg_size_pretty(pg_total_relation_size('table_name'))`
```
### 5. Environment Gotchas
```markdown
## Docker DNS Resolution Delay
**Severity**: Medium
**Affects**: Container startup
### The Problem
First DNS lookup in container takes 5+ seconds if Docker's DNS isn't configured. Causes health check failures during deployment.
### The Fix
Add to `docker-compose.yml`:
```yaml
dns:
- 8.8.8.8
- 8.8.4.4
```
Or in Dockerfile:
```dockerfile
RUN echo "nameserver 8.8.8.8" > /etc/resolv.conf
```
### How to Detect
- Health checks fail on first attempt only
- `dig` shows 5+ second response times
```
---
## Where to Store Gotchas
### Option 1: Dedicated Gotchas File
```text
docs/
└── gotchas/
├── README.md # Index of all gotchas
├── infrastructure.md # AWS, GCP, infra gotchas
├── third-party.md # API integrations
├── database.md # DB-specific issues
└── deployment.md # CI/CD, container gotchas
```
### Option 2: Inline with Related Docs
```markdown
# Payment Service
## API Reference
...
## Known Issues & Gotchas
### Stripe Webhook Retries
[gotcha content]
### Currency Rounding
[gotcha content]
```
### Option 3: In CLAUDE.md
For critical gotchas that affect daily development:
```markdown
# Project CLAUDE.md
## Critical Gotchas
1. **RDS Connections**: Max 90 on t3.medium. Don't exceed 15 pool size.
2. **Stripe Webhooks**: Always idempotent. Check Redis before processing.
3. **Large JSON**: Never parse >1MB synchronously.
```
---
## Gotcha Review Process
### When to Add
- After every production incident
- When onboarding reveals undocumented behavior
- When code review catches a gotcha
### Review Checklist
- [ ] Clear, specific title
- [ ] Severity assigned
- [ ] Root cause explained
- [ ] Solution provided
- [ ] Detection method documented
- [ ] Last verified date set
### Maintenance
- Review quarterly: Are gotchas still relevant?
- Remove fixed issues (but keep in git history)
- Update when workarounds become permanent fixes
---
## Integration with Incident Management
### Post-Incident Template Addition
```markdown
## Incident Retro: [INC-123]
### Gotcha Documentation
**Should this be documented?** Yes / No
If yes:
- **Category**: Infrastructure / API / Framework / Database / Environment
- **Severity**: Critical / High / Medium / Low
- **Owner**: [who will write it]
- **Deadline**: [when]
```
### Link to Incidents
```markdown
## Memory Leak in Image Processing
**Related Incidents**:
- INC-456 (2024-03-15) - Initial discovery
- INC-489 (2024-04-02) - Recurrence, fix verified
```
---
## Anti-Patterns
### Don't Do This
```markdown
## Database Issues
Sometimes the database is slow. Check connections.
```
### Do This Instead
```markdown
## PostgreSQL Slow Queries After Bulk Insert
**Severity**: Medium
**Affects**: Reporting queries after ETL
### The Problem
After inserting 100K+ rows, queries using indexes on that table run 10x slower until autovacuum runs (can take hours).
### The Fix
Run `ANALYZE table_name` immediately after bulk insert:
```sql
INSERT INTO events SELECT ... FROM staging_events;
ANALYZE events;
```
### How to Detect
- Query times spike after ETL jobs
- `EXPLAIN ANALYZE` shows index scan with high row estimates
```
---
## Related Resources
- [writing-best-practices.md](writing-best-practices.md) - General documentation standards
- [changelog-best-practices.md](changelog-best-practices.md) - Tracking changes
- [adr-writing-guide.md](adr-writing-guide.md) - Architecture decisions
references/readme-best-practices.md
# README Best Practices
Comprehensive guide for creating effective README files that enable users to understand, install, and use your project quickly.
## Table of Contents
- [Essential README Structure](#essential-readme-structure)
- [1. Project Name + One-line Description](#1-project-name-one-line-description)
- [Project Name](#project-name)
- [2. Badges (Optional)](#2-badges-optional)
- [3. Features](#3-features)
- [Features](#features)
- [4. Prerequisites](#4-prerequisites)
- [Prerequisites](#prerequisites)
- [5. Installation](#5-installation)
- [Installation](#installation)
- [6. Configuration](#6-configuration)
- [Configuration](#configuration)
- [7. Usage](#7-usage)
- [Usage](#usage)
- [Basic Usage](#basic-usage)
- [Advanced Usage](#advanced-usage)
- [8. API Documentation](#8-api-documentation)
- [API Documentation](#api-documentation)
- [9. Testing](#9-testing)
- [Testing](#testing)
- [10. Troubleshooting](#10-troubleshooting)
- [Troubleshooting](#troubleshooting)
- [Database connection fails](#database-connection-fails)
- [macOS](#macos)
- [Linux](#linux)
- [Port already in use](#port-already-in-use)
- [Tests failing](#tests-failing)
- [11. Contributing](#11-contributing)
- [Contributing](#contributing)
- [12. License](#12-license)
- [License](#license)
- [13. Support](#13-support)
- [Support](#support)
- [README Anti-Patterns](#readme-anti-patterns)
- [Avoid These Common Mistakes](#avoid-these-common-mistakes)
- [Advanced README Patterns](#advanced-readme-patterns)
- [Table of Contents (Long READMEs)](#table-of-contents-long-readmes)
- [Badges Section](#badges-section)
- [Demo Section](#demo-section)
- [Demo](#demo)
- [Architecture Diagram](#architecture-diagram)
- [Architecture](#architecture)
- [README Templates by Project Type](#readme-templates-by-project-type)
- [Library/Package README](#librarypackage-readme)
- [CLI Tool README](#cli-tool-readme)
- [Web Application README](#web-application-readme)
- [API Service README](#api-service-readme)
- [Maintenance Checklist](#maintenance-checklist)
- [Tools for README Quality](#tools-for-readme-quality)
- [Check markdown syntax](#check-markdown-syntax)
- [Validate links](#validate-links)
- [Spell check](#spell-check)
- [Examples of Great READMEs](#examples-of-great-readmes)
- [README Success Criteria](#readme-success-criteria)
## Essential README Structure
Every README should include these core sections in this order:
### 1. Project Name + One-line Description
**Purpose**: Immediately communicate what the project does.
**Format**:
```markdown
# Project Name
Brief one-line description of what this project does.
```
**Examples**:
- `# FastAPI Starter - Production-ready FastAPI template with auth, database, and testing`
- `# React Dashboard - Modern analytics dashboard built with React 19 and TypeScript`
### 2. Badges (Optional)
**Purpose**: Show project status at a glance.
**Common badges**:
- Build status (CI/CD)
- Test coverage
- Version
- License
- Downloads
**Example**:
```markdown



```
### 3. Features
**Purpose**: Highlight key capabilities (3-5 bullet points).
**Format**:
```markdown
## Features
- OAuth2 authentication with JWT tokens
- PostgreSQL database with TypeORM
- Real-time WebSocket notifications
- Automated testing with 90%+ coverage
- Docker-based deployment
```
**Best practices**:
- Lead with most important features
- Be specific (not "Authentication" but "OAuth2 authentication with JWT")
- Include technical stack highlights
### 4. Prerequisites
**Purpose**: List required software with versions.
**Format**:
```markdown
## Prerequisites
- Node.js 20+ ([download](https://nodejs.org/))
- PostgreSQL 14+ ([download](https://www.postgresql.org/download/))
- Redis 7+ (optional, for caching)
```
**Best practices**:
- Include version requirements (avoid "latest")
- Add download links for major dependencies
- Mark optional dependencies clearly
### 5. Installation
**Purpose**: Provide copy-paste ready setup commands.
**Format**:
````markdown
## Installation
1. Clone the repository:
```bash
git clone https://github.com/username/project.git
cd project
```
2. Install dependencies:
```bash
npm install
```
3. Set up environment variables:
```bash
cp .env.example .env
# Edit .env with your configuration
```
4. Initialize the database:
```bash
npm run db:migrate
npm run db:seed
```
5. Start the development server:
```bash
npm run dev
```
The server should now be running at `http://localhost:3000`.
````
**Best practices**:
- Number each step
- Make commands copy-paste ready
- Include expected output or confirmation
- Mention where the app runs (localhost:3000)
### 6. Configuration
**Purpose**: Document environment variables and configuration options.
**Format**: Use a table for clarity.
```markdown
## Configuration
| Variable | Description | Required | Default |
|----------|-------------|----------|---------|
| `PORT` | Server port | No | `3000` |
| `DATABASE_URL` | PostgreSQL connection string | Yes | - |
| `REDIS_URL` | Redis connection string | No | `redis://localhost:6379` |
| `JWT_SECRET` | Secret key for JWT signing | Yes | - |
| `LOG_LEVEL` | Logging level (debug, info, warn, error) | No | `info` |
```
**Best practices**:
- Use table format for multiple variables
- Mark required vs optional clearly
- Include defaults
- Add format examples for complex values
### 7. Usage
**Purpose**: Show basic and advanced usage examples.
**Format**:
````markdown
## Usage
### Basic Usage
```javascript
const { Client } = require('@yourorg/package');
const client = new Client({
apiKey: process.env.API_KEY
});
const result = await client.getData();
console.log(result);
```
### Advanced Usage
```javascript
// With custom configuration
const client = new Client({
apiKey: process.env.API_KEY,
timeout: 5000,
retries: 3
});
// Using callbacks
client.getData((err, data) => {
if (err) console.error(err);
else console.log(data);
});
```
````
**Best practices**:
- Start with simplest example
- Show real working code
- Include imports/setup
- Demonstrate common use cases
### 8. API Documentation
**Purpose**: Link to detailed API reference.
**Format**:
```markdown
## API Documentation
See `docs/api.md` for complete endpoint reference.
**Quick Examples**:
- Authentication: `docs/api.md#authentication`
- Users API: `docs/api.md#users`
- Webhooks: `docs/api.md#webhooks`
```
**Best practices**:
- Don't duplicate full API docs in README
- Link to separate API documentation
- Include quick navigation links
### 9. Testing
**Purpose**: Explain how to run tests.
**Format**:
````markdown
## Testing
Run all tests:
```bash
npm test
```
Run with coverage:
```bash
npm run test:coverage
```
Run E2E tests:
```bash
npm run test:e2e
```
**Coverage requirements**: Maintain 80%+ overall coverage.
````
**Best practices**:
- Show different test modes (unit, integration, E2E)
- Include coverage command
- Mention coverage requirements
### 10. Troubleshooting
**Purpose**: Address common issues proactively.
**Format**:
````markdown
## Troubleshooting
### Database connection fails
**Error**: `ECONNREFUSED 127.0.0.1:5432`
**Solution**: Ensure PostgreSQL is running:
```bash
# macOS
brew services start postgresql
# Linux
sudo systemctl start postgresql
```
### Port already in use
**Error**: `Port 3000 is already in use`
**Solution**: Change port in `.env`:
```
PORT=3001
```
### Tests failing
Check Node.js version:
```bash
node --version # Should be 20+
```
````
**Best practices**:
- Include actual error messages users will see
- Provide diagnostic commands
- Keep solutions concise
### 11. Contributing
**Purpose**: Guide contributors.
**Format**:
```markdown
## Contributing
We welcome contributions! Please see [CONTRIBUTING.md](../../../../../../CONTRIBUTING.md) for:
- Development setup
- Commit message guidelines
- Pull request process
- Code style standards
**Quick start for contributors**:
1. Fork the repository
2. Create a feature branch: `git checkout -b feature/your-feature`
3. Make changes and test
4. Commit: `git commit -m "feat: your feature"`
5. Push: `git push origin feature/your-feature`
6. Open a pull request
```
**Best practices**:
- Link to detailed CONTRIBUTING.md
- Include quick workflow summary
- Mention commit message format
### 12. License
**Purpose**: Specify legal terms.
**Format**:
```markdown
## License
This project is licensed under the MIT License - see the [LICENSE](../../../../../../LICENSE) file for details.
```
### 13. Support
**Purpose**: Tell users where to get help.
**Format**:
```markdown
## Support
- **Issues**: [GitHub Issues](https://github.com/username/project/issues)
- **Discussions**: [GitHub Discussions](https://github.com/username/project/discussions)
- **Email**: support@example.com
- **Discord**: [Join our Discord](https://discord.gg/example)
```
## README Anti-Patterns
### Avoid These Common Mistakes
**BAD: No installation instructions**
- Users shouldn't have to guess how to get started
**BAD: Outdated screenshots**
- Screenshots showing old UI confuse users
**BAD: Missing prerequisites**
- Hidden dependencies lead to failed installations
**BAD: No usage examples**
- Users need to see how to use your code
**BAD: Broken links**
- Test all links before publishing
**BAD: "Coming soon" sections**
- Don't document features that don't exist yet
**BAD: Wall of text**
- Use headers, lists, code blocks for structure
**BAD: No table of contents for long READMEs**
- Add TOC if README exceeds 200 lines
## Advanced README Patterns
### Table of Contents (Long READMEs)
For READMEs longer than 200 lines:
```markdown
## Table of Contents
- [Features](#features)
- [Prerequisites](#prerequisites)
- [Installation](#installation)
- [Configuration](#configuration)
- [Usage](#usage)
- [API Documentation](#api-documentation)
- [Testing](#testing)
- [Contributing](#contributing)
- [License](#license)
```
### Badges Section
```markdown





```
### Demo Section
```markdown
## Demo

Try it online: [Live Demo](https://demo.example.com)
```
### Architecture Diagram
````markdown
## Architecture
```
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ Client │─────▶│ API Server │─────▶│ Database │
│ (React) │ │ (Node.js) │ │ (PostgreSQL)│
└─────────────┘ └──────────────┘ └─────────────┘
│
▼
┌──────────────┐
│ Redis │
│ (Cache) │
└──────────────┘
```
See `docs/architecture.md` for details.
````
## README Templates by Project Type
### Library/Package README
Focus on:
- Installation via package manager
- Import syntax
- API reference
- Examples for common use cases
### CLI Tool README
Focus on:
- Installation (global vs local)
- Command syntax
- Command options table
- Usage examples for each command
### Web Application README
Focus on:
- Deployment instructions
- Environment configuration
- Database setup
- Frontend + backend setup
### API Service README
Focus on:
- API endpoints overview
- Authentication setup
- Request/response examples
- Rate limiting
## Maintenance Checklist
**When updating README**:
- [ ] Verify all installation commands work
- [ ] Test all code examples
- [ ] Check all links (use link checker)
- [ ] Update screenshots if UI changed
- [ ] Update version numbers
- [ ] Verify prerequisites are current
- [ ] Check configuration table is complete
- [ ] Ensure examples use latest syntax
## Tools for README Quality
**Linters**:
- `markdownlint` - Markdown syntax checking
- `markdown-link-check` - Find broken links
- `cspell` - Spell checking
**Generators**:
- `readme-md-generator` - Interactive README creation
- `standard-readme` - README standard compliance
**Testing**:
```bash
# Check markdown syntax
npx markdownlint README.md
# Validate links
npx markdown-link-check README.md
# Spell check
npx cspell README.md
```
## Examples of Great READMEs
- **Next.js**: https://github.com/vercel/next.js/blob/canary/readme.md
- **React**: https://github.com/facebook/react/blob/main/README.md
- **FastAPI**: https://github.com/tiangolo/fastapi/blob/master/README.md
- **Nest**: https://github.com/nestjs/nest/blob/master/README.md
## README Success Criteria
**A great README enables users to**:
1. [OK] Understand what the project does in 10 seconds
2. [OK] Install and run it in 5 minutes
3. [OK] Find examples for common use cases
4. [OK] Locate detailed documentation
5. [OK] Know how to contribute
6. [OK] Get help when stuck
**Quality metrics**:
- Time to first successful run: < 5 minutes
- Questions in issues about setup: < 10%
- Documentation completeness: All sections present
- Link validity: 100% working links
references/runbook-writing-guide.md
# Runbook Writing Guide
How to write operational runbooks that work at 3 AM under pressure.
---
## Table of Contents
- [Runbook Types](#runbook-types)
- [Standard Structure](#standard-structure)
- [[Runbook Title]](#runbook-title)
- [Prerequisites](#prerequisites)
- [Steps](#steps)
- [1. [Action verb] — [What this accomplishes]](#1-action-verb-—-what-this-accomplishes)
- [2. [Next step] ...](#2-next-step)
- [Verification](#verification)
- [Rollback](#rollback)
- [Escalation](#escalation)
- [Writing for 3 AM](#writing-for-3-am)
- [Runbook Testing](#runbook-testing)
- [Ownership and Review Cadence](#ownership-and-review-cadence)
- [Integration with Incident Management](#integration-with-incident-management)
- [Runbook Quality Checklist](#runbook-quality-checklist)
- [Anti-Patterns](#anti-patterns)
- [Related Resources](#related-resources)
## Runbook Types
| Type | Trigger | Example |
|------|---------|---------|
| **Incident response** | Alert fires or user report | "Database replication lag > 30s" |
| **Deployment** | Scheduled release | "Deploy payments-service to production" |
| **Maintenance** | Scheduled window | "Rotate TLS certificates" |
| **Rollback** | Failed deployment or regression | "Rollback payments-service to previous version" |
| **Disaster recovery** | Major outage or data loss | "Restore database from backup" |
Every alert in your monitoring system should link to a runbook. If an alert has no runbook, either write one or delete the alert.
---
## Standard Structure
Every runbook follows the same skeleton. Consistency matters more than cleverness.
```markdown
# [Runbook Title]
**Last tested:** YYYY-MM-DD | **Owner:** [Team] | **Duration:** [X min] | **Severity:** [Critical/High/Medium]
## Prerequisites
- [ ] Access to [system/tool]
- [ ] Permissions: [specific role or group]
## Steps
### 1. [Action verb] — [What this accomplishes]
[exact command]
**Expected:** [output]
**If this fails:** [recovery action or escalation]
### 2. [Next step] ...
## Verification
- [ ] [Check 1]
- [ ] [Check 2]
## Rollback
[How to undo if the procedure made things worse]
## Escalation
| Condition | Contact | Channel |
|-----------|---------|---------|
| [condition] | [name/team] | [Slack/phone/PagerDuty] |
```
---
## Writing for 3 AM
The reader is tired, stressed, and possibly unfamiliar with this system. Write accordingly.
**Do:**
- Number every step. No prose between steps unless it is a decision point.
- Use exact commands. Copy-pasteable, with placeholders clearly marked: `[CLUSTER_NAME]`.
- State expected output after every command. The reader needs to know they are on the right track.
- Provide "if this fails" after every step. Do not assume the happy path.
- Use bold for decision points: **If the output shows X, go to step 5. Otherwise, continue.**
**Avoid:**
- Background explanations. Link to architecture docs instead.
- Ambiguous language: "you may need to", "consider", "it depends".
- Multiple options without a recommendation. Pick the default path.
- Jargon without definition. The on-call engineer may be from a different team.
**Placeholder convention:** Use `[ALL_CAPS_WITH_UNDERSCORES]` for values the reader must fill in (e.g., `kubectl rollout restart deployment/[SERVICE_NAME] -n [NAMESPACE]`). List all placeholders and their sources in Prerequisites.
---
## Runbook Testing
An untested runbook is a guess, not a procedure.
**Testing methods:**
| Method | Frequency | Purpose |
|--------|-----------|---------|
| **Dry run** | After every edit | Walk through steps without executing destructive commands |
| **Game day** | Quarterly | Execute the full runbook in a staging environment |
| **Tabletop exercise** | Monthly | Team talks through the runbook verbally, identifies gaps |
| **Chaos engineering** | Quarterly | Inject the failure, execute the runbook for real |
**Dry run checklist:**
- [ ] Every command is syntactically valid
- [ ] Every placeholder has a documented source
- [ ] Every "expected output" matches current system behavior
- [ ] Every escalation contact is still correct
- [ ] Rollback steps have been reviewed
**After each test, update the "Last tested" date at the top of the runbook.**
---
## Ownership and Review Cadence
| Event | Action |
|-------|--------|
| Runbook created | Assign owner (team, not individual) |
| Every incident that uses a runbook | Update with lessons learned within 48 hours |
| Quarterly review | Owner verifies all steps, contacts, and outputs are current |
| Team member leaves | Transfer ownership explicitly; do not leave orphaned runbooks |
| Service architecture changes | Review all runbooks for affected service |
**Ownership rule:** If no team claims a runbook, escalate to engineering management. Orphaned runbooks are a reliability risk.
---
## Integration with Incident Management
Link runbooks directly into alerting and incident tools. Add the runbook URL to every alert's `runbook_url` field (PagerDuty, OpsGenie, Grafana).
**Example alert config:**
```yaml
alerts:
- name: "Database replication lag > 30s"
severity: critical
runbook_url: "https://wiki.internal/runbooks/db-replication-lag"
escalation_policy: "database-team"
```
**Incident channel first message:** Post severity, runbook link, and on-call name within 2 minutes. Do not make responders search for the runbook.
---
## Runbook Quality Checklist
Use before publishing or during quarterly review.
- [ ] Title is specific; last tested date is within 90 days
- [ ] Owner assigned; estimated duration stated
- [ ] Prerequisites and required access listed
- [ ] Every step numbered, starts with action verb, has copy-pasteable command
- [ ] Placeholders marked with `[ALL_CAPS]` and documented in prerequisites
- [ ] Expected output follows every command
- [ ] "If this fails" present for each step
- [ ] Rollback section exists and is tested
- [ ] Escalation contacts are current
- [ ] No credentials or secrets hardcoded
- [ ] Linked from the corresponding alert
- [ ] Reviewed after every incident that used it
---
## Anti-Patterns
- **Untested runbooks.** A runbook that has never been executed may contain wrong commands or stale outputs. Test or delete.
- **Wall of prose.** Runbooks are step-by-step procedures, not documentation. Remove paragraphs that do not guide the next action.
- **Missing rollback.** Every procedure that changes production state needs an undo path. If impossible, state that and document the blast radius.
- **Stale escalation contacts.** A disconnected phone number during an incident wastes critical minutes. Verify quarterly.
- **Credentials in the runbook.** Never hardcode secrets. Reference a vault path instead.
- **One runbook for everything.** Split into one runbook per alert or procedure. Keep each focused.
- **No link from the alert.** Every alert must include a `runbook_url`. Do not make responders search.
---
## Related Resources
- [production-gotchas-guide.md](production-gotchas-guide.md) - Documenting known operational issues
- [documentation-testing.md](documentation-testing.md) - Automated verification of doc accuracy
- [contributing-guide-standards.md](contributing-guide-standards.md) - Review and ownership patterns
references/writing-best-practices.md
# Technical Writing Best Practices
Comprehensive guide to writing clear, effective technical documentation.
## Table of Contents
- [Core Principles](#core-principles)
- [Writing for Your Audience](#writing-for-your-audience)
- [Structure and Organization](#structure-and-organization)
- [Language and Style](#language-and-style)
- [Code Examples](#code-examples)
- [Visual Elements](#visual-elements)
- [Editing and Review](#editing-and-review)
- [AI-Writing Tells: Recognition and Fixes](#ai-writing-tells-recognition-and-fixes)
---
## Core Principles
### 1. Know Your Purpose
Every piece of documentation should have a clear purpose:
- **Tutorial:** Teach a specific skill (learning-oriented)
- **How-to guide:** Solve a specific problem (task-oriented)
- **Reference:** Provide detailed information (information-oriented)
- **Explanation:** Clarify and deepen understanding (understanding-oriented)
**Example:**
```markdown
# Bad: Mixed purposes
"Understanding and Installing PostgreSQL"
# Good: Clear purpose
"Installing PostgreSQL" (How-to guide)
"PostgreSQL Architecture Overview" (Explanation)
```
### 2. Write for Scanning
Most readers scan rather than read word-for-word.
**Techniques:**
- Use descriptive headings
- Keep paragraphs short (3-5 sentences)
- Use bullet points and numbered lists
- Highlight key information
- Add visual breaks
**Example:**
```markdown
# Bad
PostgreSQL is a powerful, open source object-relational database system that uses and extends the SQL language combined with many features that safely store and scale complicated data workloads. It has been actively developed for over 30 years and has earned a strong reputation for reliability, feature robustness, and performance.
# Good
PostgreSQL is an open-source relational database with these key features:
- SQL support with advanced extensions
- ACID compliance for data integrity
- Horizontal scaling capabilities
- 30+ years of active development
- Strong reputation for reliability and performance
```
### 3. Be Consistent
Consistency reduces cognitive load and builds trust.
**Maintain consistency in:**
- Terminology (choose one term and stick with it)
- Formatting (headings, code blocks, lists)
- Voice and tone
- Document structure
**Example:**
```markdown
# Bad: Inconsistent terminology
"Click the submit button"
"Press the save control"
"Select the confirm option"
# Good: Consistent terminology
"Click the Submit button"
"Click the Save button"
"Click the Confirm button"
```
---
## Writing for Your Audience
### 1. Identify Your Audience
Know who you're writing for:
- **Beginners:** Need more context, step-by-step instructions, explanations
- **Intermediate:** Want practical examples, common patterns, best practices
- **Advanced:** Need technical details, edge cases, performance considerations
### 2. Adjust Technical Level
**For beginners:**
```markdown
# Installing Node.js
Node.js is a JavaScript runtime that lets you run JavaScript outside the browser.
**Prerequisites:** None (we'll guide you through everything)
**Step 1: Download Node.js**
1. Go to https://nodejs.org
2. Click the green "LTS" button
3. Wait for the download to complete
```
**For advanced users:**
```markdown
# Node.js Installation
```bash
# Via nvm (recommended for version management)
nvm install --lts
nvm use --lts
# Verify installation
node --version
npm --version
```
```
### 3. Define Jargon and Acronyms
**First use:**
```markdown
API (Application Programming Interface) - a set of rules that allows programs to talk to each other
```
**Thereafter:**
```markdown
The API returns JSON data...
```
---
## Structure and Organization
### 1. Start with Context
Every document should answer:
- What is this?
- Why should I care?
- What will I learn/accomplish?
**Example:**
```markdown
# User Authentication Guide
This guide explains how to implement user authentication in your application.
**You will learn:**
- Setting up OAuth2 with Google and GitHub
- Managing user sessions securely
- Implementing password reset flows
**Prerequisites:**
- Node.js 20+ installed
- Basic understanding of Express.js
- A registered OAuth application
```
### 2. Use the Inverted Pyramid
Put the most important information first.
**Good structure:**
1. **What** - Quick description and main point
2. **Why** - Context and benefits
3. **How** - Detailed instructions
4. **Advanced** - Edge cases and optimizations
**Example:**
```markdown
## Caching with Redis
**What:** Redis is an in-memory data store used for caching frequently accessed data.
**Why:** Reduces database load and improves response times by up to 10x.
**How:**
1. Install Redis: `npm install redis`
2. Connect to Redis...
3. Cache database queries...
**Advanced:**
- Cache invalidation strategies
- Redis cluster setup
- Monitoring and debugging
```
### 3. Create a Logical Flow
**For tutorials:**
1. Learning objectives
2. Prerequisites
3. Step-by-step instructions
4. Verification/testing
5. Next steps
**For reference docs:**
1. Overview
2. Quick start
3. Detailed reference (alphabetical or by category)
4. Examples
5. Related resources
---
## Language and Style
### 1. Use Active Voice
**Passive (weak):**
```markdown
The database is queried by the API.
The error was encountered during deployment.
```
**Active (strong):**
```markdown
The API queries the database.
We encountered an error during deployment.
```
### 2. Use Imperative Mood for Instructions
**Wrong:**
```markdown
You should install the dependencies.
You can run the tests.
```
**Correct:**
```markdown
Install the dependencies.
Run the tests.
```
### 3. Keep Sentences Short and Simple
**Complex:**
```markdown
In order to facilitate the establishment of a connection to the database,
it is necessary to configure the environment variables.
```
**Simple:**
```markdown
Configure environment variables to connect to the database.
```
**Rule of thumb:** Aim for 15-20 words per sentence.
### 4. Use Concrete, Specific Language
**Vague:**
```markdown
The application might be slow if there are many users.
```
**Specific:**
```markdown
Response times increase to 2-3 seconds when handling 1000+ concurrent users.
```
### 5. Avoid Filler Words
**Wordy:**
```markdown
It is important to note that you should basically make sure to always
validate user input in order to prevent security vulnerabilities.
```
**Concise:**
```markdown
Validate user input to prevent security vulnerabilities.
```
**Common filler words to avoid:**
- basically
- actually
- really
- very
- quite
- just
- simply
- in order to
- it is important to note that
### 6. Use Second Person
**Good:**
```markdown
You can install the package with npm.
Run your tests to verify the installation.
```
**Avoid:**
```markdown
One can install the package...
Users should run their tests...
```
---
## Code Examples
### 1. Make Examples Complete and Runnable
**Bad (incomplete):**
```javascript
user.save();
```
**Good (complete):**
```javascript
const user = new User({
email: 'user@example.com',
name: 'John Doe'
});
await user.save();
console.log('User saved successfully');
```
### 2. Explain What the Code Does
**Template:**
```markdown
**Example: [What this example demonstrates]**
[Brief explanation of what this code does and why]
```language
[Code]
```
**Output:**
```
[Expected output]
```
```
**Real example:**
```markdown
**Example: Create a new user with validation**
This example shows how to create a user with email validation and error handling.
```javascript
async function createUser(email, name) {
if (!isValidEmail(email)) {
throw new Error('Invalid email address');
}
const user = new User({ email, name });
await user.save();
return user;
}
```
**Output:**
```
User { id: '123', email: 'user@example.com', name: 'John Doe' }
```
```
### 3. Use Syntax Highlighting
Always specify the language:
````markdown
```javascript
console.log('Hello, world!');
```
```bash
npm install express
```
```json
{
"name": "my-app",
"version": "1.0.0"
}
```
````
### 4. Show Error Cases
Don't just show the happy path.
```javascript
// Good: Shows both success and error cases
try {
const user = await getUser(id);
console.log(user.name);
} catch (error) {
if (error.code === 'USER_NOT_FOUND') {
console.error('User not found');
} else {
console.error('Unexpected error:', error);
}
}
```
---
## Visual Elements
### 1. Use Diagrams for Complex Concepts
```markdown
# Database Architecture
```
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Client │─────▶│ API Server │─────▶│ Database │
└─────────────┘ └─────────────┘ └─────────────┘
```
```
Or use Mermaid for interactive diagrams:
````markdown
```mermaid
sequenceDiagram
Client->>API: POST /users
API->>Database: INSERT user
Database-->>API: Success
API-->>Client: 201 Created
```
````
### 2. Use Tables for Comparisons
```markdown
| Feature | Option A | Option B |
|---------|----------|----------|
| Performance | Fast | Moderate |
| Ease of use | Complex | Simple |
| Cost | High | Low |
```
### 3. Use Screenshots Strategically
**When to use screenshots:**
- UI workflows
- Visual verification steps
- Complex interfaces
**Best practices:**
- Annotate screenshots with arrows/highlights
- Keep screenshots up-to-date
- Provide alt text for accessibility
- Optimize image size
---
## Editing and Review
### 1. Self-Editing Checklist
**Content:**
- [ ] Purpose is clear
- [ ] Audience level is appropriate
- [ ] Information is accurate and up-to-date
- [ ] All steps are tested and work
- [ ] Examples are complete and runnable
**Structure:**
- [ ] Logical flow from beginning to end
- [ ] Headings are descriptive and hierarchical
- [ ] Paragraphs are short and focused
- [ ] Lists are used appropriately
**Language:**
- [ ] Active voice used
- [ ] Imperative mood for instructions
- [ ] No jargon without explanation
- [ ] No filler words
- [ ] Consistent terminology
**Code:**
- [ ] Syntax highlighting specified
- [ ] Code is complete and runnable
- [ ] Code is explained
- [ ] Error cases shown
**Formatting:**
- [ ] Consistent style
- [ ] No broken links
- [ ] Images have alt text
- [ ] Table of contents (for long docs)
### 2. Read It Aloud
Reading aloud helps catch:
- Awkward phrasing
- Run-on sentences
- Missing words
- Confusing logic
### 3. Test Your Instructions
**Critical:** Follow your own documentation step-by-step to verify it works.
### 4. Get Feedback
Ask someone else to review:
- Technical accuracy
- Clarity
- Completeness
- Tone
---
## Common Mistakes to Avoid
### 1. Assuming Knowledge
**Bad:**
```markdown
Simply configure the OAuth2 flow.
```
**Good:**
```markdown
Configure OAuth2 authentication:
1. Register your application at https://console.cloud.google.com
2. Copy your Client ID and Client Secret
3. Set the redirect URI to http://localhost:3000/auth/callback
```
### 2. Using Vague Pronouns
**Bad:**
```markdown
When the server connects to the database, it sends a query.
This might fail if this is not configured correctly.
```
**Good:**
```markdown
When the server connects to the database, the server sends a query.
The connection might fail if the database credentials are not configured correctly.
```
### 3. Overusing "Should"
**Weak:**
```markdown
You should install Node.js.
You should run the tests.
```
**Strong:**
```markdown
Install Node.js.
Run the tests.
```
### 4. Burying the Lead
**Bad:**
```markdown
## Database Configuration
PostgreSQL is a powerful database that has been around for 30 years...
[3 paragraphs of history]
...
To configure PostgreSQL, set DATABASE_URL=...
```
**Good:**
```markdown
## Database Configuration
Set the `DATABASE_URL` environment variable:
```bash
DATABASE_URL=postgresql://user:pass@localhost:5432/dbname
```
PostgreSQL is a powerful... [background information follows]
```
---
## Writing for Different Document Types
### README Files
**Must include:**
1. One-line description
2. Key features
3. Installation instructions
4. Basic usage example
5. Links to detailed docs
**Keep it short:** 200-400 lines max.
### API Documentation
**For each endpoint:**
1. HTTP method and path
2. Description
3. Authentication requirements
4. Request parameters (query, path, body)
5. Response format with example
6. Status codes
7. cURL example
### Tutorials
**Structure:**
1. What you'll build
2. Prerequisites
3. Step-by-step instructions
4. Verification/testing
5. Next steps
**Voice:** Friendly, encouraging, educational.
### Reference Documentation
**Structure:**
1. Alphabetical or categorical organization
2. Consistent format for each entry
3. Complete parameter/return documentation
4. Examples for each entry
**Voice:** Concise, precise, neutral.
---
## AI-Writing Tells: Recognition and Fixes
**Scope: this section governs authored documentation prose** (READMEs, guides, ADRs, runbooks, reference docs) — the same axis as every other section in this file. **It does not govern agent conversational output** (what an agent says in chat while doing a task); that is a different axis and this library currently has no dedicated guidance for it (see [Residual Gap](#residual-gap) below). Where a tell shows up differently in the two contexts, the table notes it.
These patterns exist because LLM text generation has predictable statistical habits: it reaches for the same intensifiers, the same three-item lists, the same hedges, more often than a human writer would. None of them prove a document was AI-written on their own — flag **clusters** of tells, not one isolated hit, and never gut a sentence that happens to use one flagged word in a legitimate way. A single "however" or one em dash is not a defect.
| Tell | Why it reads as AI-generated | Fix |
|------|------------------------------|-----|
| **Inflated significance** — "stands as a testament to," "marks a pivotal moment," "underscores its importance," "represents a shift" | Puffs up an ordinary fact by claiming it symbolizes something larger, without evidence for the larger claim. | State the fact plainly. Cut the claim about broader significance unless a source supports it. |
| **AI-vocabulary words** — delve, crucial, intricate, tapestry, testament, underscore (verb), pivotal, landscape (abstract noun), foster, garner, showcase, leverage (verb) | These words spike sharply in frequency in post-2023 text and cluster together. | Replace with the plain word: "use" not "leverage," "detailed" not "intricate," "show" not "showcase." |
| **Copula avoidance** — "serves as," "stands as," "boasts," "features [a]," "offers [a]" in place of "is"/"are"/"has" | Elaborate constructions substituted for simple statements of fact. | Use "is," "are," or "has" directly: "the tool is X," not "the tool serves as X." |
| **Negative parallelisms / tailing negations** — "It's not just X, it's Y," or a clause tacked on as "no guessing," "no wasted effort" | An overused rhetorical shape that reads as templated rather than considered. | Write the plain positive statement, or turn the tailing fragment into a real clause: "so the user doesn't have to guess." |
| **Rule-of-three overuse** — forcing every list or claim into exactly three items ("faster, safer, and more reliable") | Real requirements rarely come in even groups of three; the pattern signals a filled-in template rather than an observed fact. | List however many items are actually true. Two is fine. Five is fine. |
| **Elegant variation** — cycling synonyms for the same referent across sentences ("the function," "this method," "the routine," "said logic") | Avoids repeating a word at the cost of clarity — a reader has to work out these all mean the same thing. | Repeat the exact term. In technical docs, consistent terminology (already required above, see [Be Consistent](#3-be-consistent)) beats variety. |
| **False ranges** — "from X to Y" where X and Y are not points on a real scale ("from the smallest bug fix to the grandest architectural vision") | Manufactures a sense of comprehensive scope without the range being meaningful or measurable. | Name the actual set of things covered, without the borrowed structure of a scale. |
| **Em dash / en dash overuse** — leaning on `—` or `–` as a universal connector | One of the most statistically reliable single-token AI tells; overuse also just makes prose harder to parse (was that an aside, a list break, or a new clause?). | Replace with a period, comma, colon, or parentheses depending on the relationship. A single em dash for a genuine aside is fine; several per paragraph is the tell. |
| **Boldface overuse** — bolding phrases mechanically throughout a paragraph, not just true key terms | Turns emphasis into noise; if everything is bold, nothing is. | Bold only the term being defined or the one thing a scanning reader must not miss. |
| **Inline-header vertical lists** — `- **Term:** sentence restating the term` repeated down a list | A templated shape, not a description of an actual capability list. | Either drop the bold lead-in and let the sentence stand, or convert to prose if the items relate to each other. |
| **Emojis as bullet/heading decoration** | Decorative emojis on every bullet or heading read as autogenerated formatting rather than an intentional signal. | Remove unless the emoji itself carries meaning the reader needs (e.g., a status icon in a table). |
| **Knowledge-cutoff disclaimers and speculative gap-filling** — "as of [date]," "while specific details are limited," followed by invented plausible-sounding filler | Two related tells: stale training-cutoff caveats left in text, and confident-sounding guesses dressed up as fact when a source is missing. | State plainly that the information is not available, or cut the sentence. Never fill an unknown with a plausible-sounding guess. |
| **Hyphenated word pair overuse** — hyphenating compounds like "high-quality," "data-driven," "real-time" even in predicate position ("the report is high-quality") | Humans hyphenate attributive compounds ("a high-quality report") but usually drop the hyphen in predicate position ("the report is high quality"). AI applies the hyphen uniformly. | Keep the hyphen only when the compound sits before the noun it modifies. Drop it when the compound follows the noun. |
| **Persuasive authority tropes** — "the real question is," "at its core," "what really matters," "fundamentally" | Signals a manufactured pivot to a "deeper truth" that the following sentence usually doesn't deliver — it just restates an ordinary point with more ceremony. | Cut the framing phrase and state the point directly. |
| **Signposting and announcements** — "Let's dive in," "here's what you need to know," "let's break this down," in explanatory prose | Announces what the text is about to do instead of doing it; reads as a tutorial-script narrator rather than the documentation itself. | Delete the announcement and start with the content. |
| **Fragmented headers** — a heading immediately followed by a one-line paragraph that just restates the heading before real content starts | A rhetorical warm-up that adds a sentence without adding information. | Delete the throwaway line; start the section with the first substantive sentence. |
| **Diff-anchored writing** — documentation phrased as narrating a change ("this replaces the old approach of...") rather than describing the current state | Forces a reader to reconstruct history to understand what the code does today. Correct in changelogs and migration guides, wrong everywhere else. | Describe the thing as it is now. Save "replaces X" framing for changelog and migration-guide entries, where it's the point. |
| **Aphorism formulas** — "X is the language of Y," "X becomes a trap," "the architecture of Z" | Turns an ordinary claim into a reusable-sounding aphorism that feels profound but adds no precision. | Replace with the concrete claim the aphorism is gesturing at. |
| **Conversational rhetorical openers** — "Honestly?," "Here's the thing," "Look," used as a theatrical pause before an ordinary point | Manufactures fake candor before delivering a routine statement — the tell is the pause-and-reveal structure, not the word itself. | State the point without the staged lead-in. |
| **Curly quotation marks** in plain-text contexts (code comments, config, CLI examples) | Straight quotes are required where curly quotes break parsing; curly quotes appearing there usually means text was pasted from a chat UI without adjustment. | Use straight quotes (`"`) in anything that might be parsed. This is a mechanical check, not a style judgment — curly quotes in prose alone are not a tell (most editors auto-curl by default). |
| **Sycophantic/servile tone** — "Great question!," "You're absolutely right," "That's an excellent point" | People-pleasing filler that has no place in reference material and, in agent conversation, reads as flattery rather than a genuine assessment. | In docs: delete outright. In agent speech: give the direct assessment without the preamble. |
| **Collaborative-communication artifacts** — "I hope this helps!," "Let me know if you'd like me to expand," "Would you like examples?" | Text written as chatbot correspondence, pasted into content that has no reader to address this way. | Delete. Documentation has no back-and-forth to refer to. |
### Already covered elsewhere in this guide
Three tells from the source taxonomy overlap with sections earlier in this file. Rather than duplicate them, this section defers to the existing guidance:
- **Passive voice and subjectless fragments** ("No configuration file needed") — see [Use Active Voice](#1-use-active-voice).
- **Filler phrases** ("in order to," "it is important to note that") and **excessive hedging** ("could potentially possibly") — see [Avoid Filler Words](#5-avoid-filler-words).
- **Overusing "should"** as a substitute for imperative instructions — see [Overusing "Should"](#3-overusing-should).
### Docs prose vs. agent speech
Most tells above read as defects in both axes — inflated significance, copula avoidance, false ranges, and the vocabulary list are just as wrong in a chat response as in a README. A few apply asymmetrically:
- **Signposting** ("Let's dive in") and **conversational rhetorical openers** ("Honestly?") are near-universal complaints about agent chat replies, but appear far less often in already-written docs, since nobody drafts a README by narrating their own process.
- **Collaborative-communication artifacts** ("I hope this helps!") and **sycophantic tone** ("Great question!") are almost exclusively an agent-speech problem — they leak into docs only when a chat transcript gets pasted into a file without cleanup.
- **Diff-anchored writing** and **fragmented headers** are near-exclusively a docs problem; they describe a written artifact's structure, not a conversational turn.
### Attribution
This taxonomy is adapted, in this file's own voice and condensed, from [blader/humanizer](https://github.com/blader/humanizer) at commit `523374dee72d67c7b2b5f858ea0094ffda49c3ac` (MIT license), extracted 2026-08-09. The source project itself derives its taxonomy from Wikipedia's [Signs of AI writing](https://en.wikipedia.org/wiki/Wikipedia:Signs_of_AI_writing) guide (WikiProject AI Cleanup).
Of the source's 33 patterns: **22** are reproduced above as distinct table rows; **3** are covered by cross-reference to this file's existing sections (passive voice, filler phrases, excessive hedging — see [Already covered elsewhere in this guide](#already-covered-elsewhere-in-this-guide)); **8** were cut:
- Too narrow to Wikipedia-style encyclopedic or travel-article prose, with little application to technical docs: undue emphasis on media coverage/notability, promotional heritage-article language ("nestled," "breathtaking"), vague sourcing attributions ("experts believe"), formulaic "Challenges and Future Prospects" sections, generic upbeat closing paragraphs.
- Too subjective to check by reading a single paragraph, requiring a broader read of the whole document's rhythm: manufactured-punchline / staccato-drama pacing, superficial "-ing"-ending analysis treated as a category distinct from inflated significance (folded into that row instead).
- **Title case in headings** was cut deliberately, not as noise: it is a genuine style choice, not a reliable AI tell. Sentence case vs. title case is a house-style decision (this file already uses sentence case in its own H2/H3 headings, which is worth noting as the convention here, but that's a style pick, not evidence of AI authorship either way).
### Residual gap
This section governs written documentation only. **Agent conversational output — how an agent talks while doing a task, in chat, in commit messages, in PR descriptions — remains otherwise ungoverned in this library.** Several of the tells above (signposting, sycophantic tone, collaborative-communication artifacts, conversational rhetorical openers) were originally flagged as an agent-speech problem, not a docs-prose problem, and this file does not close that gap; it only borrows the taxonomy for the axis it already owns. A dedicated agent-speech style contract, if one gets built, belongs in a different file (likely alongside `.claude/rules/coding-behavior.md` or an agent-persona reference), not here.
---
## Resources
- [Google Developer Documentation Style Guide](https://developers.google.com/style)
- [Microsoft Writing Style Guide](https://learn.microsoft.com/en-us/style-guide/)
- [Write the Docs](https://www.writethedocs.org/)
- [Hemingway Editor](https://hemingwayapp.com/) - Readability tool
- [Grammarly](https://www.grammarly.com/) - Grammar and style checker
SKILL.md
---
name: docs-codebase
description: Writes and reorganizes docs-as-code for software repos. Use when updating READMEs, runbooks, onboarding docs, API references, or agent instruction files.
compatibility: Portable core. Works on Claude Code and Codex.
version: "1.1"
last_validated: 2026-07-11
---
# Technical Documentation
Use this skill to write, restructure, and verify software-repo documentation: READMEs, runbooks, API references, changelogs, onboarding docs, instruction files, and canonical docs libraries for humans and coding agents.
The goal is durable docs, not document sprawl. Keep one canonical doc per subject, wire in ownership and review cadence, and verify filesystem-backed claims before publishing summary docs.
## Quick Reference
| Documentation Type | Template | Notes |
|-------------------|----------|-------|
| project README | [assets/project-management/readme-template.md](assets/project-management/readme-template.md) | onboarding and project navigation |
| ADR or architecture note | [assets/architecture/adr-template.md](assets/architecture/adr-template.md) | decision record |
| gap analysis or migration assessment | [assets/architecture/gap-analysis-template.md](assets/architecture/gap-analysis-template.md) | architecture and readiness work |
| API reference | [assets/api-reference/api-docs-template.md](assets/api-reference/api-docs-template.md) | REST, GraphQL, gRPC, AsyncAPI |
| changelog | [assets/project-management/changelog-template.md](assets/project-management/changelog-template.md) | release history |
| contributing guide | [assets/project-management/contributing-template.md](assets/project-management/contributing-template.md) | team and OSS contribution |
| docs IA or consolidation plan | [assets/docs-as-code/docs-structure-template.md](assets/docs-as-code/docs-structure-template.md) | large doc sets |
| ownership and review model | [assets/docs-as-code/ownership-model.md](assets/docs-as-code/ownership-model.md) | runbooks and critical docs |
| doc sync checklist | [assets/project-management/template-doc-sync-checklist.md](assets/project-management/template-doc-sync-checklist.md) | status and path integrity |
| operational runbook | [assets/operational/runbook-template.md](assets/operational/runbook-template.md) | SLO, alerts → response, rollback, escalation, postmortems; use `{{PLACEHOLDER}}` format |
| CI markdownlint config | [assets/ci/.markdownlint.yaml](assets/ci/.markdownlint.yaml) | drop into repo root; MD013 off, MD024 siblings_only, sensible defaults |
| CI Vale prose config | [assets/ci/.vale.ini](assets/ci/.vale.ini) | Microsoft style base; passive voice as suggestion; per-rule overrides documented |
| CI docs quality workflow | [assets/ci/docs-quality.yml](assets/ci/docs-quality.yml) | GitHub Actions: markdownlint + markdown-link-check + vale on docs/ PRs |
## When to Use This Skill
Use this skill when the main task is:
- writing or refactoring canonical technical docs
- consolidating messy `docs/` folders
- adding or fixing README, onboarding, runbook, changelog, or API docs
- keeping instruction files and canonical docs aligned
- publishing AI-readable documentation with stable navigation
Route elsewhere when the main task is:
- auditing docs freshness or coverage rather than rewriting docs
- deciding product requirements, specs, or PRD structure
## Defaults
- one subject, one canonical doc
- update an existing canonical doc before creating a new Markdown file
- owners and review cadence on critical docs
- doc updates in the same delivery cycle as the feature or change
- summary docs may not claim complete inventory unless counts and paths were re-verified from the repo
- temporary reports are lifecycle-managed, not permanent sources of truth
- thin platform entry files are better than duplicated giant instruction files
## Markdown Creation Gate
Before creating any new `*.md` file, prove all of these:
- no existing canonical doc owns the subject
- the target path has a clear doc type: README/navigation, runbook, reference, explanation, ADR/spec, report, or generated context
- the file has an owner, review cadence, and lifecycle state if it can go stale
- the file is linked from the right index, README, nav, or context hub
- generated outputs are under a generated artifact root such as `docs/context/` and have a rebuild path
If any item fails, update an existing doc, add a small section to a canonical page, or keep the answer in chat. Do not create per-session notes, one-off summaries, or root-level Markdown reports unless the user explicitly asks for that artifact.
## Docs vs Agent Operations
- `AGENTS.md` / `CLAUDE.md`: hot execution policy, exact commands, constraints, and pointers. Not a codebase catalog, report archive, or general docs folder.
- `README.md`: human and agent navigation. Not a deep handbook.
- `docs/`: durable product, technical, operational, API, ADR, and onboarding docs.
- `docs/operations/` or `docs/runbooks/`: operational procedures with owners and verification steps.
- `docs/reports/`: temporary evidence or analysis with `pending-integration`, `integrated`, or `superseded` status.
- `docs/context/` or `context/`: generated or compiled LLM context artifacts. Prefer rebuild scripts and structured inputs; do not hand-edit generated pages as canonical truth.
- `.archive/`: historical material excluded from normal search and context unless explicitly requested.
## Workflow
1. Identify the document type and audience.
2. Inspect the repo’s current conventions and existing canonical docs.
3. Run the Markdown Creation Gate before adding a new file.
4. Start from the closest template in `assets/` only when a new or replacement doc is justified.
5. Consolidate duplicates into one canonical page per topic.
6. Add ownership, review cadence, and publishing expectations where the doc matters operationally.
7. Run documentation QA and integrity checks before handoff.
## ASCII Flow
```text
Docs request
|
v
Classify document type + audience
|-- README / onboarding ------> project-management templates
|-- runbook / operations -----> operational templates
|-- API reference ------------> api-reference templates
|-- ADR / architecture -------> architecture templates
|-- docs IA / cleanup --------> docs-as-code templates
|
v
Inspect existing canonical docs
|
v
Markdown Creation Gate
|-- existing owner found -----> update canonical doc
|-- no owner, justified ------> create linked doc with owner + cadence
|-- temporary evidence -------> docs/reports with lifecycle state
|
v
Verify paths, links, counts, commands, and status claims
|
v
Publish through README / index / context hub
```
## Revamp Mode for Large or Messy Docs Folders
Use this mode when a repo has too many overlapping or LLM-generated docs:
1. inventory every file and classify it by doc type
2. pick the canonical doc for each subject
3. move durable facts into the canonical doc
4. mark temporary reports as `pending-integration`, `integrated`, or `superseded`
5. remove integrated drafts instead of preserving duplicate mirrors
6. re-check links, counts, moved paths, and canonical references before publishing a summary
## AI-Readable Documentation Rules
- keep `README.md` as the navigation anchor
- keep `AGENTS.md` and `CLAUDE.md` thin when possible, with shared guidance factored into canonical docs
- keep LLM operational files as routers to canonical docs, not mirrors of those docs
- publish stable URLs, stable headings, and `last_verified` markers for volatile pages
- prefer concise task-oriented docs over prose-heavy essays
- treat stale docs as execution bugs for humans and agents alike
- keep generated context hubs rebuildable from source artifacts rather than manually patched markdown
## Judgment Calls: Docs Rot, Agent Consumers, and Ownership That Sticks
Rot detection beyond "old timestamp":
- A doc edited yesterday can still be wrong. Correlate the doc's git history against the git history of the code path it describes; a code file that moved on without a matching doc commit is a stronger rot signal than age alone.
- Treat "the doc still reads fine" as a false negative test. Verify referenced commands, flags, paths, and dependency versions actually run or exist — prose can read smoothly while describing a system that no longer exists.
- A doc that names people ("ask Sarah"), specific tickets, or an org chart is a rot magnet. Move time-bound references into buddy notes or dated reports, not canonical docs.
- Treat a deprecated-but-undeleted doc as more dangerous than a missing one: readers and agents trust what they find, and a wrong doc actively misleads where a gap only leaves a question.
Agents and humans read the same doc differently; serve both:
- Agents execute instructions literally and immediately — a stale command in `AGENTS.md` or `CLAUDE.md` gets run, not questioned, the way a human skimming a wiki might self-correct. Hold instruction files to a higher freshness bar than narrative docs.
- Agents need stable anchors (headings, IDs, paths) they can cite and re-fetch; humans tolerate prose that moves around. Do not casually reshuffle a canonical doc's headings once tooling or agent memory links into it.
- An agent cannot tell an example from a prescription unless the doc says so. Label illustrative code, counts, and inventories explicitly, or an unlabeled example becomes ground truth for the next agent that reads it.
- Humans need the "why" (rationale, trade-offs, links to ADRs); agents mostly need the "what" and the exact command. Keep both, but do not let one crowd out the other in the same file — narrative belongs in `docs/`, execution policy belongs in the thin instruction file.
Ownership models fail in predictable ways:
- A named team with no allocated review time is ownership theater; the doc drifts regardless of who is listed as DRI.
- Ownership tied only to a calendar cadence misses the trigger that actually causes rot: the underlying system changed. Pair calendar review with an event trigger (schema change, deploy, incident) for anything used under pressure, such as runbooks or on-call docs.
- When a team is renamed, merged, or a person leaves, transfer ownership explicitly and date the transfer. An orphaned doc with a listed-but-gone owner is worse than an admittedly unowned doc — it signals false confidence.
## Integrity and Anti-Fluff Gates
Before merging:
- verify file paths, moved-path references, and template paths exist
- verify counts and `complete list` claims against the filesystem
- mark examples as examples instead of presenting them as exhaustive truth
- remove duplicate narrative, vague future-idea prose, and unsupported claims
- keep status in one canonical source and link to it from secondary docs
- reject new Markdown files that lack a placement, owner, lifecycle, and index link
## Navigation
**Core references**
- [references/readme-best-practices.md](references/readme-best-practices.md)
- [references/adr-writing-guide.md](references/adr-writing-guide.md)
- [references/api-documentation-standards.md](references/api-documentation-standards.md)
- [references/runbook-writing-guide.md](references/runbook-writing-guide.md)
- [references/docs-as-code-setup.md](references/docs-as-code-setup.md)
- [references/documentation-testing.md](references/documentation-testing.md)
**Craft and style**
- [references/writing-best-practices.md](references/writing-best-practices.md) — load when drafting new docs; covers audience-first framing, Diátaxis doc types, and prose style
- [references/markdown-style-guide.md](references/markdown-style-guide.md) — load when enforcing Markdown conventions; ATX headings, tables, code blocks, common linter pitfalls
- [references/code-commenting-guide.md](references/code-commenting-guide.md) — load when improving inline comments or docstrings; covers JSDoc, TSDoc, Google-style Python, Go godoc, and anti-patterns
- [references/changelog-best-practices.md](references/changelog-best-practices.md) — load when writing or restructuring changelogs; Keep-a-Changelog format and semantic versioning categories
- [references/contributing-guide-standards.md](references/contributing-guide-standards.md) — load when creating or updating CONTRIBUTING.md; structure, dev-setup, workflow, and OSS contribution norms
- [references/onboarding-documentation.md](references/onboarding-documentation.md) — load when writing developer onboarding docs; Day 1→Week 4 structure, quickstart templates, anti-patterns, and effectiveness measures
**Advanced and AI-aware**
- [references/ai-documentation-tools.md](references/ai-documentation-tools.md)
- [references/backlog-status-sync-pattern.md](references/backlog-status-sync-pattern.md)
- [references/code-graph-documentation-patterns.md](references/code-graph-documentation-patterns.md)
- [references/documentation-metrics.md](references/documentation-metrics.md)
- [references/production-gotchas-guide.md](references/production-gotchas-guide.md)
- [data/sources.json](data/sources.json)
## Boundary: docs-codebase vs docs-ai-prd
- `docs-codebase` owns technical documentation quality, structure, and canonicalization
- `docs-ai-prd` owns requirements, specs, acceptance criteria, and what context an implementation agent needs
If you are writing or cleaning docs, stay here. If you are deciding feature requirements or context strategy, use `docs-ai-prd`.
## Related Skills
- [../qa-docs-coverage/SKILL.md](../qa-docs-coverage/SKILL.md)
- [../dev-api-design/SKILL.md](../dev-api-design/SKILL.md)
- [../dev-context-engineering/SKILL.md](../dev-context-engineering/SKILL.md)
- [../dev-git-workflow/SKILL.md](../dev-git-workflow/SKILL.md)
- [../docs-ai-prd/SKILL.md](../docs-ai-prd/SKILL.md)
## Verification Gate
Before delivering output, verify:
- every local file path and template path exists
- any counts or inventory claims were re-checked against the filesystem
- commands and code blocks either match repo reality or are marked as examples
- the output matches the intended doc type and calls out any follow-up review or publishing step
## Fact-Checking
- Verify volatile external facts, platform behavior, and version-sensitive guidance before final advice.
- Prefer primary docs over summaries.
- If live verification is unavailable, mark external claims as unverified.
## Learnings Loop
Before applying this skill on a non-trivial task, read `learnings.consolidated.md` in this directory (and `learnings.md` if present).
After applying it, if you encountered a pattern worth remembering, a mistake worth preventing, or a domain fact that surprised you, append one dated bullet to `learnings.md` via `agents-skills-feedback-loop/scripts/append_learning.py`. Do not modify `SKILL.md` itself.