# SkillPatch skill: technical-documentation

Writes and edits developer-facing technical documentation for a codebase, including READMEs, API references, docstrings, code comments, changelogs, and architecture decision records, so it reads like a careful engineer wrote it instead of a language model. Use when drafting or reviewing a README, API doc, docstring, code comment, changelog entry, or ADR.

You (the agent) were given this URL and asked to use this skill. This is a **public** skill — no SkillPatch account, API key, or prior setup is required. Two ways to use it:

**1. Use it right now** — the skill's complete file tree (SKILL.md + all reference files) is inlined below; read `SKILL.md` first, then follow it, consulting the other files as it directs.

**2. Install the exact package onto disk** (recommended if you can run a shell — this reproduces the skill byte-for-byte, including any binary assets that can't be inlined):

```bash
mkdir -p .claude/skills/technical-documentation
curl -sSL https://skillpatch.dev/install_skill/technical-documentation | tar -xz -C .claude/skills/
```

(`.claude/skills/` is Claude Code's convention; use whatever directory your agent loads skills from.)


---

## Skill files (3)

- `SKILL.md`
- `references/ai-slop-patterns.md`
- `references/documentation-conventions.md`


### `SKILL.md`

```markdown
---
name: technical-documentation
description: Writes and edits developer-facing technical documentation for a codebase, including READMEs, API references, docstrings, code comments, changelogs, and architecture decision records, so it reads like a careful engineer wrote it instead of a language model. Use when drafting or reviewing a README, API doc, docstring, code comment, changelog entry, or ADR.
license: MIT
metadata:
  category: writing
  domain: technical-documentation
---

# Technical documentation writer

Writes and edits technical documentation for a codebase. Every draft gets two things right: it's grounded in the real source and structured the way professional docs are structured, and it's free of AI slop, the filler phrases, formulaic sentence shapes, and empty formatting that make writing sound generated instead of considered.

## When to use

Use this when the user asks to write, clean up, or review a README, CONTRIBUTING guide, API reference, docstring, inline code comment, changelog entry, migration guide, or architecture decision record (ADR) for a codebase.

## Steps

1. Identify the artifact and which of the four documentation types it is: tutorial, how-to guide, reference, or explanation (see `references/documentation-conventions.md`). Don't mix types in one document, a README quickstart is a tutorial; its API section is reference; keep them visibly separate.
2. Draft or edit the content using the standard structure and voice rules for that artifact type in `references/documentation-conventions.md`: the expected README sections, the Google-style docstring shape, the Keep a Changelog format, the ADR template, second-person active voice, sentence-case headings, prerequisites stated before the instructions that need them.
3. Ground every concrete detail in the actual source before writing it down. A flag, default, parameter, error message, exit code, or return shape must be verified against the code, never assumed or reconstructed from "how this kind of API usually works." If you can't verify it, say so or leave it out.
4. Run the draft against `references/ai-slop-patterns.md`. Cut vocabulary tells (leverage, seamless, robust-as-filler, delve, comprehensive...), puffery ("stands as a testament to," "plays a vital role"), structural tics (throat-clearing openers, colon reveals, binary contrasts, fake-profound kickers, summary-recap endings), formatting slop (emoji section headers, badge walls, empty templated sections), and code-comment slop (comments that restate the line, docstring bloat on trivial functions, apologetic TODOs).
5. Read the draft aloud in three-sentence chunks. Rewrite any run of three consecutive sentences that share the same length and rhythm.
6. Confirm at least one genuine limitation, edge case, or failure mode is documented, if one exists. Documentation that is only good news is incomplete, and omitting downsides is itself a slop pattern.
7. Check the draft against the list below before calling it done.

## Pre-ship checklist

- [ ] Every flag, parameter, default, error, and code path mentioned exists in the actual source.
- [ ] Every example runs as written; input and output are both shown.
- [ ] No word survives from the vocabulary-tells table in `references/ai-slop-patterns.md` without a reason.
- [ ] No throat-clearing openers, colon reveals, binary contrasts, or fake-profound kickers.
- [ ] No decorative emoji headers, badge walls, or empty templated sections.
- [ ] No comment or docstring merely restates the code beside it.
- [ ] At least one limitation or failure mode is documented, if one genuinely exists.
- [ ] The document stays inside one Diataxis type; headings are sentence case; terminology is identical everywhere the same thing is named.

## Scope

In scope: READMEs, CONTRIBUTING guides, API references, docstrings, inline code comments, changelogs, ADRs, migration/upgrade guides, runbooks, and design docs.

Out of scope: marketing copy, blog posts, and external launch announcements. Those have a different audience and register (some enthusiasm is appropriate in a launch post; it isn't in a README), so don't apply the puffery rules to them without judgment. Skip the changelog step for internal refactors with no user-facing effect, unless the project explicitly tracks those too.

## Example

Input (a draft README paragraph):

> Our platform leverages a robust, seamless caching architecture to unlock blazing-fast performance for your workflows. It's a game-changer that ensures your team can focus on what really matters.

Output:

> Caches API responses in Redis for 5 minutes, cutting median response time from 400ms to 60ms. Falls back to a direct database read if Redis is unreachable.

The rewrite cuts the vocabulary tells (leverages, robust, seamless, unlock, blazing-fast, game-changer, ensures), drops the unverifiable claim about the team's focus, and replaces it with two checkable facts, including the failure-mode sentence the original omitted entirely.

```


### `references/ai-slop-patterns.md`

```markdown
# AI slop patterns in technical documentation

Reference for Step 3 in `SKILL.md`. Slop is writing that optimizes for *sounding* thorough over actually informing the reader: predictable vocabulary, formulaic sentence shapes, empty formatting, and, specific to code, comments and docs that restate what the code already says instead of explaining what the reader can't see.

## Vocabulary tells

Not banned outright, each one is a signal to stop and check whether a plainer word says the same thing. If the sentence still reads naturally after deleting the word, delete it.

| Category | Words/phrases to distrust |
|---|---|
| Inflated verbs | leverage, harness, unlock, elevate, empower, streamline, supercharge, turbocharge, revolutionize, transform, optimize (when nothing is measurably optimized), foster, cultivate, embark, unleash |
| Significance puffery | pivotal, crucial, vital, essential, game-changing, groundbreaking, transformative, paradigm shift, cutting-edge, state-of-the-art, best-in-class, industry-leading, next-generation, robust (used as filler, not a claim about fault tolerance), powerful, seamless |
| Vague abstraction | landscape, ecosystem, realm, tapestry, journey, holistic, synergy, myriad, plethora, a wide range of, a variety of, comprehensive (unless you can defend it), intricate, nuanced |
| Hedge/throat-clear verbs | delve (into), dive into, deep dive, unpack, explore, navigate (the complexities of), showcase, underscore, highlight (as a verb meaning "show"), boast (meaning "have") |
| Connective filler | moreover, furthermore, additionally, notably, importantly, interestingly, crucially, arguably, when they open a sentence and add no logical connective work beyond "and" |
| Marketing register in engineering docs | battle-tested, production-ready, enterprise-grade, blazing fast, lightweight yet powerful, best-in-class, rock-solid, out of the box (as a substitute for "by default"), under the hood (as a substitute for "internally") |
| Minimizers that condescend | simply, just, easily, obviously, of course, trivially, all you need to do is; these erase real difficulty and read as dismissive when the reader is stuck |

Replace with the specific, checkable fact. "Leverages a robust caching layer to seamlessly optimize performance" becomes "Caches responses in Redis for 5 minutes, cutting p95 latency from 800ms to 120ms."

## Puffery and unsupported claims

Phrases that assert importance instead of demonstrating it. Cut them and either state the underlying fact or delete the sentence.

- "stands as a testament to," "serves as a reminder that," "plays a vital/crucial/pivotal role in," "continues to shape," "solidifies its position as," "underscores the importance of," "cannot be overstated," "marks a significant milestone," "represents a major step forward"
- "no discussion of X would be complete without," "it goes without saying," "needless to say"
- Weasel attribution with no named source: "many developers agree," "it is widely accepted that," "studies show," "experts recommend." Name the source (a benchmark, an RFC, a specific team's decision) or delete the claim entirely.

## Structural and rhetorical tics

Sentence- and paragraph-level shapes that read as generated regardless of the words used.

- **Binary contrasts / telegraphed reframes.** "This isn't just a linter. It's a safety net." State the real claim once: "This linter blocks merges that would break the build."
- **Throat-clearing openers.** "Here's the thing," "Let me be clear," "It's worth noting that," "The important thing to understand is." Delete the opener; start with the fact.
- **Colon reveals.** "The real problem: race conditions," used as a drumroll before a dramatic noun phrase. Use colons for lists, labels, and quotes instead.
- **Rhetorical questions answered by the next sentence.** "So how does caching work? It stores responses for reuse." Just state it: "Caching stores responses for reuse."
- **Rule-of-three padding.** Reaching for exactly three examples, adjectives, or parallel clauses because it "sounds complete," not because three is the right number. Use as many items as the content actually has.
- **False comprehensiveness sweeps.** "Whether you're a beginner or an expert," "from small scripts to enterprise systems," used to sound exhaustive without adding information. Cut unless every branch is genuinely handled differently.
- **Negative-then-positive listing.** "This isn't a framework. It's not a library. It's a toolkit." State what it is.
- **Dramatic fragmentation.** "One config file. That's it." Use complete sentences; save fragments for genuine emphasis, sparingly.
- **Fake-profound kickers.** Ending a section on a cute aphorism ("Good documentation isn't written. It's grown.") instead of the last concrete fact or next step. Delete it; end on the actionable point.
- **Summary-recap endings.** "In conclusion," "To summarize," "Overall, this guide has covered..." The reader just read it. End on the last concrete instruction, or a "Next steps" pointer if one is genuinely needed.
- **Synonym cycling.** Calling the same entity "the function," then "the method," then "the routine" across consecutive sentences to avoid repetition. Repeat the correct term; precision beats variety in technical writing.
- **Gerund clauses that pretend to explain.** "...ensuring reliability," "...showcasing best practices." These assert an effect without showing the mechanism. Replace with the mechanism: "retries failed requests up to 3 times with exponential backoff" instead of "ensuring reliability."
- **Robotic cadence.** Three or more consecutive sentences of near-identical length and shape. Read the paragraph aloud; vary sentence length.
- **Em dash overuse.** Not a default rhythm device. One or two per long document is fine when they genuinely beat a comma or parenthesis; a cluster of them reads as a tic. Prefer periods, commas, and parentheses.

## Formatting slop

Documentation- and README-specific patterns:

- **Badge walls.** 10+ shields.io badges at the top of a README with no functional purpose. Keep badges that convey a decision-relevant fact (build status, latest version, license); drop decorative ones.
- **Emoji as section markers.** "🚀 Getting Started," "✨ Features," "🔧 Configuration." Emoji in every heading is a strong AI tell in developer docs specifically; use plain sentence-case headings. A single, deliberate emoji is fine if the project's own style already uses it consistently; blanket decoration is not.
- **Marketing framing for internal or utility code.** "🎉 Revolutionize your workflow!" on an internal CLI tool nobody outside the team will see. Match tone to audience.
- **Table of contents on a 150-line README.** ToCs earn their place past roughly 300-400 lines or a dozen+ headings; below that they're scaffolding with nothing to scaffold.
- **Decorative comment banners in code.** `// ================ HELPER FUNCTIONS ================` repeated every 20 lines. Let file/module structure and naming do that work.
- **Bullet lists standing in for prose.** Converting a two-sentence explanation into three one-line bullets to look scannable. Reserve bullets for genuinely parallel, list-shaped information.
- **Bold text sprinkled mid-sentence for emphasis.** Bold UI labels, commands, and defined terms, not random emphasis words.
- **Title-case headings.** "How To Configure The Build Pipeline." Prefer sentence case: "How to configure the build pipeline."
- **Empty or templated sections left unfilled.** A "Roadmap" that says "More features coming soon!", boilerplate "Contributing" text never adapted to the project. Delete a section rather than ship a placeholder.

## Code comment and docstring slop

The category generic slop-detectors miss, because it's specific to code.

- **Comments that restate the line.** `i += 1  # increment i by 1`. If the comment adds nothing a reader with basic language fluency doesn't already see, delete it.
- **Comments explaining *what* instead of *why*.** A comment earns its keep by explaining intent, a non-obvious constraint, or a reason a shortcut was taken, not by narrating the syntax.
- **Docstring bloat on trivial functions.** A ten-line Args/Returns docstring on a one-line getter. Document the public, non-trivial surface; skip self-evident accessors.
- **Parameter descriptions that repeat the parameter name.** `user_id: The user ID.` Say what it constrains or its format: `user_id: The account's UUID, not the display username.`
- **Apologetic or uncertain comments left in shipped code.** `# not sure if this is right`, `# hacky but works`, `# TODO fix later` with no ticket reference. Resolve the uncertainty, link a tracked issue, or remove the comment.
- **Comment-every-line style.** Annotating each line of an otherwise-clear block buries the one comment that mattered. Comment the non-obvious lines only.
- **Emoji/exclamation noise in commit messages and comments.** `// ✅ Fixed the bug!! 🎉`. State what changed and why, plainly.
- **Positivity bias, omitting failure modes.** Docs that describe only the happy path and never mention limits, known issues, or error states. This is a systematic AI-writing bias, and it actively harms technical docs, where the reader most often arrives *because* something went wrong.
- **Hallucinated specifics.** A flag, config key, or error code that sounds plausible but doesn't exist in the source. The single most damaging slop pattern in technical writing: verify every concrete claim against the actual code before writing it down.

## Banned-word swap table

| Instead of | Use |
|---|---|
| leverage | use |
| seamlessly | (state the actual mechanism, or cut) |
| robust (as filler) | (name the specific property: fault-tolerant, thread-safe, validated) |
| comprehensive | (name what it actually covers) |
| delve into / dive into | describe, cover, explain |
| ensure | (state what actually guarantees it, or cut) |
| showcase / highlight (verb) | show, demonstrate |
| unlock the power of | use, enable |
| navigate the complexities of | handle, manage |
| a wide range of / a variety of | (list them, or give the count) |
| cutting-edge / state-of-the-art | (name the actual capability or cut) |
| plays a crucial/vital role in | (state what it actually does) |
| it's worth noting that / it's important to note | (cut; just state the fact) |
| in today's fast-paced world | (cut entirely) |
| whether you're a beginner or an expert | (cut, or address the actual audience) |
| at the end of the day | (cut) |
| the world of X / the realm of X | X |
| take X to the next level | improve X, or state the specific improvement |

```


### `references/documentation-conventions.md`

````markdown
# Professional technical documentation conventions

Reference for Step 2 in `SKILL.md`. Removing slop is necessary but not sufficient: good technical documentation also follows structure and conventions that make it findable, scannable, and trustworthy.

## Pick the right kind of document: Diataxis

Every piece of documentation is one of four types, each with a different job. Mixing types in one document is the most common structural mistake in technical writing (for example, a "Getting Started" tutorial that digresses into full API reference).

| Type | Reader's need | Oriented to | Example |
|---|---|---|---|
| Tutorial | Learn by doing, build confidence | Learning | "Build your first plugin," a guided, ordered walkthrough with a working result at the end |
| How-to guide | Accomplish a specific known task | Working | "How to rotate API keys," "How to configure TLS" |
| Reference | Look up exact facts while working | Working | API reference, CLI flag list, config schema: neutral, structured, complete |
| Explanation | Understand context, tradeoffs, why | Learning | "Why we use event sourcing here," an architecture overview |

A README typically contains a short tutorial (quickstart) plus links out to how-to guides and reference docs. It should not try to be the reference itself once the project grows past a few functions.

## README structure

Standard sections, in order, using only what's relevant to the project's size. Cut any section that would be empty or generic for this project rather than filling it with placeholder text.

1. **Title and one-line description.** What it is and who it's for, in one sentence, no tagline fluff.
2. **Badges** (optional, minimal). Build status, version, license only.
3. **Description.** 2-4 sentences on what problem this solves and why it exists.
4. **Prerequisites.** Runtime versions, required accounts/keys, OS constraints. State conditions before instructions, so the reader isn't 8 steps in before learning they need a Postgres instance.
5. **Installation.** Copy-pasteable commands, tested, in order.
6. **Quickstart / usage.** The smallest working example, showing real input and real output. This is a tutorial in miniature; it must actually run as written.
7. **Configuration.** Env vars, config file schema, defaults, required vs. optional.
8. **API/CLI reference** (or a link to it if large).
9. **Architecture / how it works** (optional, for non-trivial projects). Key components, data flow, and why the shape is what it is.
10. **Limitations / known issues.** What it doesn't do, what's out of scope, known rough edges. Omitting this is a slop pattern; including it is a professionalism signal.
11. **Contributing.** How to run tests, coding conventions, PR process, written for this project, not boilerplate.
12. **License.**

## Voice, tone, and grammar

Synthesized from the Google developer documentation style guide and the Microsoft Writing Style Guide, which agree on nearly all of this:

- **Second person, active voice.** "You configure the timeout in `config.yaml`," not "The timeout is configured by the user in config.yaml."
- **Conversational but precise.** Write like a knowledgeable colleague, not a brochure and not a legal document. Contractions ("it's," "you'll") are fine in prose docs; avoid them in formal reference tables and error messages.
- **Lead with the point.** Front-load the sentence and paragraph with the information the reader is scanning for; put conditions and prerequisites before the instruction that depends on them.
- **Prefer the strong verb over "there is/are."** "The scheduler retries failed jobs" beats "There is a retry mechanism for failed jobs."
- **Cut "you can."** "You can configure the port by..." becomes "Configure the port by...". Start instructions with the verb.
- **Sentence-case headings**, not title case. No period at the end of a heading.
- **Oxford/serial comma** in lists of three or more.
- **One space after sentence-ending punctuation**; no spaces around em dashes.
- **Unambiguous dates.** ISO 8601 (`2026-09-10`), never `09/10/26`.
- **Global audience.** Avoid idioms, sports/cultural metaphors, and humor that doesn't translate.
- **Bias-free and inclusive language.** Avoid unnecessarily gendered examples, ableist idioms ("sanity check" becomes "quick check"), and terms with a violent or exclusionary history where a neutral synonym exists (prefer "allowlist/denylist" or "primary/replica" over deprecated master/slave terminology).
- **Don't pre-announce unreleased features** or write about internal-only functionality as if it's public.

## API and reference documentation

Reference docs are read out of order and skimmed under pressure. Optimize for lookup, not narrative flow.

- One entry per function/endpoint/class, in a consistent, predictable shape every time.
- State the signature or route first, then a one-line summary of what it does.
- **Parameters/arguments**: name, type, required/optional, default, and the *constraint or meaning*, not a restatement of the name.
- **Returns/response**: type and shape, with a real example payload, not "returns the result."
- **Errors/exceptions**: which ones are raised and under what condition. This is the section most often missing, and the one readers need most when debugging.
- **Example**: a minimal, runnable call with realistic (not `foo`/`bar`) values, showing both the call and its output.
- Keep terminology identical across every reference entry. If it's "user ID" in one place, it's not "userId" or "uid" in another.
- Version the docs against the code: note which version a parameter was added/deprecated in if the project has meaningful version history.

## Code comments and docstrings

- **Comment the why, not the what.** Assume the reader knows the language; they don't know your intent or why the obvious approach was rejected.
- **Google-style Python docstring shape** (summary line, blank line, sectioned detail) generalizes to JSDoc, Rustdoc, and Javadoc with their native tags:

```python
def fetch_rows(table, keys, require_all_keys=False):
    """Fetches rows from a table by key.

    Args:
        table: An open Table instance to read from.
        keys: Sequence of row keys to fetch.
        require_all_keys: If True, raise KeyError when any key in
            `keys` has no matching row, instead of skipping it.

    Returns:
        A dict mapping each found key to its row data.

    Raises:
        IOError: The table could not be reached.
    """
```

- Document public API surfaces and anything non-obvious; skip self-evident one-liners.
- Keep comments in sync with the code they describe. A stale comment that contradicts the implementation is worse than no comment. When you change behavior, check nearby comments in the same diff.
- Match the existing comment style/voice in a codebase rather than introducing a new convention mid-file.

## Changelogs: Keep a Changelog format

- File named `CHANGELOG.md`, newest version first, one section per released version, plus an `Unreleased` section at the top.
- Each version entry gets its release date in ISO 8601: `## [1.4.0] - 2026-01-12`.
- Group changes under standard categories, only including the ones that apply: **Added**, **Changed**, **Deprecated**, **Removed**, **Fixed**, **Security**.
- Each line is written for the humans upgrading, not as a copy of the commit log. "Fixed a crash when `config.yaml` was missing the `port` key" beats "fix null pointer (#482)".
- State whether the project follows Semantic Versioning, and follow it consistently if so.
- Skip changes with no user-facing effect unless the project explicitly tracks those too.

## Architecture Decision Records (ADRs)

For any consequential, hard-to-reverse technical decision (choice of database, auth strategy, a rejected alternative architecture), write a short ADR rather than letting the reasoning live only in a Slack thread. Standard shape (Nygard template):

- **Title.** Short, specific: "Use Postgres row-level security for tenant isolation," not "Database decision."
- **Status.** Proposed, accepted, deprecated, or superseded (with a link to whatever superseded it).
- **Context.** The forces at play: constraints, requirements, the problem that needed a decision. Written neutrally, as background.
- **Decision.** What was decided, stated plainly and actively: "We will use X."
- **Consequences.** What becomes easier, what becomes harder, what tradeoffs were accepted, what alternatives were rejected and why. This is what future maintainers come back for; don't skip it.

Keep each ADR immutable once accepted; record a change of mind as a new ADR that supersedes the old one.

## Markdown and formatting mechanics

- Heading hierarchy is strictly ordered; don't skip from `#` to `###`. One `#` (title) per document.
- Fence every code block with a language tag so syntax highlighting and copy buttons work.
- Link text describes the destination ("see the configuration reference"), never bare "click here" or a naked URL in prose.
- Tables for genuinely tabular data; prose for narrative explanation; numbered lists only for sequential steps; bullets for unordered, parallel items.
- Alt text on every image/diagram describing its content and purpose, not "image1.png."
- Admonitions (`> **Note:**`, `> **Warning:**`) sparingly, for information that would cause real harm if skimmed past.
- One source of truth per fact. If a default is documented in the README and the reference doc, link one to the other rather than maintaining two numbers that can drift out of sync.

## Examples and correctness

- Every example must actually run as written. Test it; don't reconstruct it from memory of "how this API usually works."
- Use realistic sample data (`user_id: "usr_8f2a1c"`) over placeholder-obviously-fake data (`foo`, `bar`, `xxx`).
- Show input *and* output for anything non-trivial.
- Keep one canonical example per concept rather than three redundant variants.

````
