MODULE 3 · EVERYDAY WORKFLOWS / 20 MIN Free NOVEMBER 2026 EDITION · CLAUDE CODE 2.1.318
Documentation and legacy code
Use Claude to write useful docs, explain old code, and add tests to code nobody dares to touch.
Updated 5 November 2026 · Reviewed 5 November 2026
What you’ll be able to do
Produce documentation that people actually read and can trust, and start safely improving legacy code: old code with no tests, no documentation, and nobody left who remembers why it works the way it does.
Why this matters
Two kinds of work tend to get postponed forever: writing documentation, and touching scary old code. Both are tasks Claude Code is genuinely good at, because both mostly involve reading a lot of code carefully and explaining it.
There’s a catch in both cases. Generated documentation can sound authoritative while being wrong: a setup command that no longer exists, a guessed explanation presented as fact. And legacy code often has behaviour that looks like a bug but that other systems rely on. This lesson focuses on getting the benefits while avoiding those traps.
Documentation that earns its place
The difference between documentation people use and documentation people ignore is usually focus. Always tell Claude who the docs are for and what they need to be able to do, and insist that factual claims are checked:
Write a README section "Local development" for a new engineer on Windows
or macOS. Cover prerequisites, setup, running tests and common errors.
Check every command against package.json and the scripts folder, and don't
include any command you couldn't verify.
Look at what this prompt does: it names a reader (a new engineer), a task (getting set up), the scope (four topics), and a verification rule (every command checked against the project). The last part is what stops invented commands from creeping in.
Other high-value documents:
- Architecture overview: “One page, with a Mermaid diagram, for engineers joining the team.” The overview from lesson 3.1, written down.
- ADR (Architecture Decision Record): a short document recording a decision, its context, the options considered and why one was chosen. “Write an ADR for why we chose Postgres over DynamoDB, based on @docs/notes/db-discussion.md.”
- API reference: “Generate reference docs for the public functions in @src/sdk/ from their types and JSDoc comments.”
- Changelog: “Summarise the commits since v1.4.0 into a user-facing changelog.” Written for users, not developers.
Working with legacy code
Legacy code is risky to change because you don’t know what depends on its current behaviour. Work through four steps, in this order:
1. Map it. Understand before you touch.
Map @src/billing/invoice.js: its responsibilities, inputs and outputs, side
effects (database, network, files), and the three riskiest areas to change.
Mark anything you're unsure about as UNCERTAIN.
What you’ll see: a structured summary of what the file does and where the danger is. Lines marked UNCERTAIN are where the code doesn’t explain itself, which is exactly where you should ask a colleague or dig deeper.
2. Pin it with tests.
Write characterization tests for calculateInvoice() that capture its current
behaviour, including the odd cases. If behaviour looks like a bug, keep the
test asserting the current behaviour but add a comment "suspected bug".
These are the characterization tests from lesson 3.4: they record what the code does today. Note the instruction about suspected bugs. Don’t let Claude “fix” odd behaviour while writing tests. Something else may depend on it, and a test-writing session is the wrong place to decide. Record it, and decide separately.
3. Document intent.
Add a short header comment to each major function explaining what it does
and why, based on the code and git history. Keep the UNCERTAIN notes.
4. Improve in small steps, using the refactoring workflow from lesson 3.4, with the characterization tests as your safety net.
Exercise
Pick the oldest, most intimidating file in a project you know, or a file in an older open-source project:
- Map it with UNCERTAIN markers. What you’ll see: a summary plus a handful of UNCERTAIN items. Check one of them yourself.
- Pin its main function with characterization tests, and run them against the unchanged code. What you’ll see: passing tests, possibly with “suspected bug” comments worth investigating later.
- Write a “How this works” doc for the next person who opens the file. Name that reader in your prompt (for example, “a developer who has never seen our billing code”), and ask Claude to verify every factual claim against the code.
Common mistakes
- Docs without a reader in mind. “Document this project” produces long, generic text. Name the reader and their task.
- Publishing unverified docs. Check commands and claims before others rely on them.
- “Fixing” legacy quirks while writing tests. Record suspected bugs; decide about them separately.
- Changing legacy code before pinning its behaviour. Map, then test, then change.
Verify it worked
- You have a map of the file that clearly marks what’s uncertain
- Characterization tests pass against the unchanged code
- You wrote a doc for a named reader, and its factual claims were checked against the code
You’ve finished the free Foundations level. You can now use Claude Code confidently every day. The full course takes you through Control, Extend and Automate: hooks and permissions, MCP servers, Obsidian, skills, plugins and subagents, CI, the Agent SDK, and a capstone project.
Knowledge check
3 QUESTIONS · PASS MARK 80%Tip: select the text that's wrong before clicking, and it's quoted in your report.