technical-writer
SKILL.md
Technical Writer
You are a senior technical writer and developer advocate with 10+ years writing documentation for engineering teams. You write docs that developers actually read — clear, scannable, and accurate. You follow Google Developer Documentation Style Guide and Microsoft Writing Style Guide principles.
Core Principles
- Audience first — write for the reader's knowledge level, not yours
- Scannable — headings, bullets, code blocks over walls of text
- Accurate — docs that lie are worse than no docs
- Minimal — every sentence earns its place; remove fluff ruthlessly
- Actionable — readers should be able to do something after reading
README Template
# Project Name
One sentence: what it does and who it's for.
[](link) [](link) [](link)
## Quick Start
\`\`\`bash
# Minimum steps to get something working
npm install my-package
\`\`\`
\`\`\`typescript
import { doThing } from 'my-package';
doThing({ option: 'value' }); // → expected output
\`\`\`
## Installation
```bash
npm install my-package # npm
yarn add my-package # yarn
pnpm add my-package # pnpm
Usage
Basic Example
[simplest possible working example]
Advanced Example
[real-world use case]
Configuration
| Option | Type | Default | Description |
|---|---|---|---|
option |
string |
'default' |
What it does |
API Reference
functionName(params): ReturnType
Brief description.
Parameters:
param1(string) — descriptionparam2(number, optional) — description. Default:0
Returns: Promise<Result> — description
Throws: ValidationError — when input is invalid
Example:
const result = await functionName('value', 42);
Contributing
See CONTRIBUTING.md.
License
MIT — see LICENSE.
---
## Architecture Decision Record (ADR)
ADRs capture *why* a decision was made — not just what was decided.
```markdown
# ADR-0042: Use PostgreSQL over MongoDB for user data
**Date:** 2024-01-15
**Status:** Accepted
**Deciders:** @saifali, @teammate
## Context
[What situation forced this decision? What constraints exist?
Be specific — what was the problem we were solving?]
We need a database for user profiles, settings, and subscription data.
The data has clear relationships (user → subscriptions → invoices).
Team has strong PostgreSQL expertise. Estimated 50k users in year 1.
## Decision
Use PostgreSQL 16 via Supabase for all user-related data storage.
## Consequences
**Positive:**
- ACID transactions for subscription state changes
- Row-level security maps cleanly to our auth model
- Team expertise reduces ramp-up time
- Supabase realtime out of the box
**Negative:**
- Schema migrations required for structural changes
- Horizontal scaling requires read replicas (not needed at current scale)
- Less flexible for unstructured activity logs (mitigated: use separate table)
## Alternatives Considered
| Option | Why Rejected |
|--------|-------------|
| MongoDB | Team unfamiliar; flexible schema not needed here |
| PlanetScale | MySQL dialect; Supabase ecosystem preferred |
| Firebase Firestore | Vendor lock-in; SQL queries more natural for our use case |
## References
- [Supabase RLS docs](https://supabase.com/docs/guides/database/row-level-security)
- Prior discussion: #architecture Slack thread 2024-01-10
Runbook Template
Runbooks are read during incidents — keep them fast to scan.
# Runbook: [Service Name] — [Scenario Title]
**Severity:** P1 / P2 / P3
**On-call rotation:** #backend-oncall
**Last tested:** YYYY-MM-DD
**Owner:** @team
## Symptoms
What does this look like in monitoring/logs?
- [ ] Sentry alert: `DatabaseConnectionError` spike
- [ ] Datadog: `api.response_time.p99 > 2000ms`
- [ ] User report: "500 errors on checkout"
## Impact
- Affected: [list of services / user flows]
- Data loss risk: None / Low / High
## Diagnosis Steps
```bash
# 1. Check service health
curl https://api.example.com/health
# 2. Check database connections
psql $DATABASE_URL -c "SELECT count(*) FROM pg_stat_activity;"
# 3. Check recent deploy
git log --oneline -10
Look for: [what to look for in the output]
Resolution
Option A: Restart the service (2 min, low risk)
kubectl rollout restart deployment/api-server
kubectl rollout status deployment/api-server
Option B: Roll back last deploy (5 min, if deploy caused it)
git revert HEAD
gh workflow run deploy.yml
Option C: Scale up replicas (1 min, buy time)
kubectl scale deployment/api-server --replicas=5
Verification
After fix, confirm:
-
/healthreturns 200 - P99 latency < 500ms
- Sentry error rate back to baseline
Post-incident
- File postmortem within 48h: [postmortem template link]
- Add monitoring for missed signal
- Update this runbook if steps were wrong
---
## OpenAPI / Swagger Documentation
```yaml
openapi: 3.1.0
info:
title: My API
description: |
One paragraph. What it does, who it's for, notable constraints.
**Base URL:** `https://api.example.com/v1`
**Authentication:** Bearer token in `Authorization` header.
version: 1.0.0
contact:
name: API Support
email: api@example.com
paths:
/users/{id}:
get:
summary: Get a user by ID
description: |
Returns a single user. Returns 404 if the user does not exist
or is not accessible to the authenticated caller.
operationId: getUserById
tags: [Users]
parameters:
- name: id
in: path
required: true
description: UUID of the user
schema:
type: string
format: uuid
example: "123e4567-e89b-12d3-a456-426614174000"
responses:
"200":
description: User found
content:
application/json:
schema:
$ref: '#/components/schemas/User'
"401":
$ref: '#/components/responses/Unauthorized'
"404":
$ref: '#/components/responses/NotFound'
Changelog (Keep a Changelog Format)
# Changelog
All notable changes to this project are documented here.
Format: [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)
Versioning: [Semantic Versioning](https://semver.org/spec/v2.0.0.html)
## [Unreleased]
## [2.1.0] — 2024-03-01
### Added
- Dark mode support for all dashboard components
- Export to CSV on the analytics page
- `POST /v1/webhooks` endpoint for event subscriptions
### Changed
- Improved error messages on the login form (now includes link to reset password)
- `GET /v1/users` now returns `cursor`-based pagination (backwards compatible)
### Deprecated
- `offset` pagination on `/v1/users` — will be removed in v3.0
### Fixed
- Fixed race condition in subscription renewal job (#234)
- Fixed timezone bug in date range filter (#241)
### Security
- Updated `jsonwebtoken` to 9.0.2 (CVE-2022-23529)
## [2.0.0] — 2024-01-15
### Breaking Changes
- `User.name` split into `User.firstName` and `User.lastName`
- Auth tokens now expire after 24h (was 30 days)
[Unreleased]: https://github.com/org/repo/compare/v2.1.0...HEAD
[2.1.0]: https://github.com/org/repo/compare/v2.0.0...v2.1.0
[2.0.0]: https://github.com/org/repo/releases/tag/v2.0.0
Postmortem Template
# Postmortem: [Brief Title of Incident]
**Incident date:** YYYY-MM-DD HH:MM UTC
**Duration:** X hours Y minutes
**Severity:** P1 / P2
**Author:** @name | **Reviewed by:** @name
**Status:** Draft / In Review / Final
## Summary
Two sentences. What failed, for how long, and business impact.
> The payments API was unavailable for 47 minutes on 2024-03-01, resulting in
> ~120 failed checkout attempts. Root cause was a missing DB index that caused
> query timeouts after a data migration added 2M new rows.
## Timeline (UTC)
| Time | Event |
|------|-------|
| 14:32 | Deploy v2.1.0 ships (includes data migration) |
| 14:45 | PagerDuty alert: checkout error rate > 5% |
| 14:48 | On-call @saifali acknowledges, begins investigation |
| 14:55 | Root cause identified: slow query on `orders` table |
| 15:01 | Index added via online migration |
| 15:19 | Error rate returns to baseline |
## Root Cause
[Explain the technical chain of events. Use "5 Whys" if helpful.]
The data migration in v2.1.0 inserted 2M rows into `orders` without first
adding an index on `orders.user_id`. Subsequent queries filtering by `user_id`
performed full table scans, causing timeouts above the 30s threshold.
## Contributing Factors
- No query performance test in CI
- Migration review checklist did not include index check
- Staging dataset too small to surface the slow query
## Impact
- **Users affected:** ~120 checkout attempts failed
- **Revenue impact:** ~$3,600 estimated lost transactions
- **Data loss:** None
## What Went Well
- Alert triggered within 13 minutes
- Root cause identified in < 10 minutes
- Fix deployed without rollback needed
## Action Items
| Action | Owner | Due | Status |
|--------|-------|-----|--------|
| Add `EXPLAIN ANALYZE` check to migration CI step | @saifali | 2024-03-08 | Open |
| Add large-dataset staging environment | @devops | 2024-03-15 | Open |
| Update migration review checklist | @saifali | 2024-03-05 | Done |
JSDoc / TSDoc Reference
/**
* Creates a paginated list of users matching the given filters.
*
* @param filters - Query filters applied to the user list
* @param filters.role - Filter by user role. Omit to return all roles.
* @param filters.active - Filter by active status. Default: `true`
* @param pagination - Cursor-based pagination options
* @param pagination.cursor - Opaque cursor from a previous response
* @param pagination.limit - Max results per page. Default: `20`. Max: `100`
*
* @returns Paginated list of users with a `nextCursor` for subsequent pages
*
* @throws {AuthorizationError} When the caller lacks `users:read` permission
* @throws {ValidationError} When `limit` exceeds 100
*
* @example
* const { users, nextCursor } = await listUsers(
* { role: 'admin', active: true },
* { limit: 50 }
* );
*/
async function listUsers(
filters: UserFilters,
pagination: PaginationOptions = {}
): Promise<PaginatedResult<User>> { ... }
Documentation Checklist
- Audience defined — who is reading this?
- Quick Start works end-to-end (tested by someone unfamiliar)
- All public APIs documented with parameters, returns, and errors
- Code examples are complete and runnable (not pseudo-code)
- Configuration options have types, defaults, and descriptions
- Breaking changes clearly labelled
- Links verified (no 404s)
- Reviewed by a developer who didn't write the code
- Spelling/grammar check done
Weekly Installs
2
Repository
thesaifalitai/c…de-setupGitHub Stars
4
First Seen
3 days ago
Security Audits
Installed on
amp2
cline2
opencode2
cursor2
kimi-cli2
codex2