Prompting for Technical Documentation
Documentation Types Have Different Jobs Technical documentation includes everything that helps people build, run, use, and maintain software: README files, setup guides, architecture overviews, runbooks, decision records, and reference pages. Each type serves a different reader with a different goal, and a single "write documentation for this project" prompt usually produces a mix that serves no one well.
A widely used way to separate documentation types is the Diátaxis framework, created by Daniele Procida. It distinguishes four kinds of documentation:
Type Reader's Need Example Tutorial "Teach me, step by step, as a beginner" Build your first API endpoint in this project How-to guide "Help me complete a specific task" How to add a new payment method Reference "Give me precise facts to look up" Environment variables, API endpoints, settings Explanation "Help me understand why" Why we use background jobs for emails Mixing these types, for example by adding long explanations to a reference table or reference details to a tutorial, makes documents harder to use. The prompts in this lesson each target one type and one reader.
This lesson covers project documentation. API documentation is covered in Lesson 96, and code explanation in Lesson 92.
The Accuracy Problem in Documentation Documentation errors are especially costly because readers follow them: they run the commands, set the variables, and trust the descriptions. Generated documentation commonly contains:
Commands that do not work, such as a wrong file name or an outdated tool Paths and files that do not exist Configuration options the project does not have Descriptions of how the system should work, rather than how it does work The recipes below generate documentation from real project information, and the final section shows code that checks commands and file paths automatically.
Recipe 1: README Use it when: creating or improving a project's main README, the first document most developers read.
Prompt Write a README.md for the project described by the files in .
Sections:
- Project name and a one-sentence description
- Features: 3 to 6 bullet points, based only on the code
- Requirements: language and tool versions found in the project files
- Setup: exact commands, in order, from a fresh clone to a running application
- Configuration: environment variables found in the code or .env.example, in a table
- Running tests: the exact command
- Project structure: the main folders and what each contains
Use only information present in . For anything missing, such as a license, write "TODO: " instead of inventing it.
{file_tree} {requirements_txt} {env_example} {settings_excerpt} {key_files} Why It Works The file tree, requirements, and environment example provide facts the README needs: versions, dependencies, and configuration. "Exact commands, in order, from a fresh clone" produces setup instructions that can be tested. TODO markers make missing information visible instead of filling it with plausible content such as an invented license. Recipe 2: How-To Guide Use it when: documenting a recurring task, such as adding a course type, deploying, or creating an admin user.
Prompt Write a how-to guide: "How to {task}" for developers on this project.
Audience: developers who know Django and already have the project running.
Format:
- Goal: one sentence
- Prerequisites: a short list
- Steps: numbered; each step has one action, with the exact file path or command
- Verification: how to confirm the task succeeded
- Troubleshooting: the 2 or 3 most likely problems and their fixes
Base the steps on the code and notes in . Do not include background explanation beyond one sentence per step.
{relevant_code_and_notes} Why It Works A specific audience avoids explaining basics that readers already know. One action per step with exact paths and commands makes the guide easy to follow. Verification tells readers how to know they succeeded, which is often missing from how-to guides. "No background explanation" keeps the guide focused, following the Diátaxis separation between how-to guides and explanations. Recipe 3: Architecture Overview Use it when: helping new team members understand how the system fits together.
Prompt Write an architecture overview for the project in , for a developer joining the team.
Include:
- The main components (for example: web app, database, background workers, external services) and what each is responsible for
- How a typical request flows through the components, using enrollment as the example
- Where data is stored, and which component owns it
- External services and what happens if each is unavailable
- A text diagram of the components and their connections
Describe only components present in . Mark anything you infer, rather than read directly, as "(inferred)".
{settings_excerpt} {file_tree} {docker_compose_or_deployment_files} {key_modules} Example Text Diagram Browser ──HTTPS──> Nginx ──> Django (Gunicorn) ──> PostgreSQL │ ├──> Redis ──> Celery worker ──> Email service └──> Payment gateway API Why It Works One example flow (enrollment) makes abstract components concrete. "What happens if a service is unavailable" is information developers need during incidents and is rarely written down. "(inferred)" markers separate facts from the model's interpretation, so reviewers know what to check. Recipe 4: Runbook A runbook is a step-by-step guide for handling a specific operational situation, such as a failed deployment, a full disk, or a payment service outage. Runbooks are read under pressure, so they must be clear and precise.
Use it when: documenting how to respond to a known operational problem.
Prompt Write a runbook for: {situation}
Audience: the on-call developer, who may be working under time pressure.
Sections:
- Symptoms: how to recognize this situation (alerts, errors, user reports)
- Impact: who is affected
- Immediate actions: numbered steps to reduce impact, each with the exact command
- Diagnosis: how to find the cause, with commands and what to look for
- Resolution: steps to fix the most common causes
- Escalation: when and whom to contact
- Afterwards: what to record for the incident review
Use only commands, services, and paths present in . Mark any step that changes production data or restarts services with "⚠ Impact:" and describe the impact.
{infrastructure_notes_and_commands} Why It Works Immediate actions before diagnosis reflects real incident priorities: reduce harm first, then understand. "⚠ Impact" warnings protect the reader from running a risky command without realizing its effect. Escalation criteria prevent people from struggling alone with a problem they should hand over. Warning: Every command in a runbook must be tested in a safe environment before the runbook is relied on. A wrong command in an incident can make the situation worse.
Recipe 5: Architecture Decision Record An Architecture Decision Record (ADR) is a short document that records an important technical decision: what was decided, why, and what the consequences are. A widely used format, introduced by Michael Nygard, has sections for title, status, context, decision, and consequences.
Use it when: recording a decision, such as choosing a database, adopting a framework, or changing an architecture.
Prompt Write an Architecture Decision Record from the discussion notes in .
Format:
ADR {number}: {short title}
Status: {Proposed | Accepted | Superseded} Context: the problem and the forces involved, including constraints Decision: what was decided, in one or two sentences Alternatives considered: each option with the main reason it was not chosen Consequences: positive and negative effects, including new work or risks
Use only arguments present in the notes. If the notes do not explain why an alternative was rejected, write "Reason not recorded".
{discussion_notes} Why It Works ADRs capture the "why", which code and commit messages rarely contain. Future developers can understand a decision before changing it (Lesson 92, design reasoning). Negative consequences are recorded honestly, which makes ADRs more useful than one-sided justifications. "Reason not recorded" prevents invented justifications. Recipe 6: Documentation From Notes Use it when: turning rough notes, chat messages, or meeting outcomes into a proper document.
Prompt Turn the notes in into a {doc_type} for {audience}.
- Use every relevant point from the notes.
- Organize them into clear sections with headings.
- Do not add facts, commands, or decisions not present in the notes.
- Where information is missing, insert "TODO: ".
- At the end, list questions the notes leave unanswered.
{notes} Why It Works Notes often contain gaps. TODO markers and a list of open questions make the gaps visible to the document's owner, who can fill them before publishing, instead of the model filling them with assumptions (Lesson 85, Recipe 5).
Checking Documentation Automatically Two simple checks catch many documentation errors: extracting shell commands so they can be reviewed or tested, and checking that referenced files exist.
import re from pathlib import Path
README = '''# Course Platform
Setup
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
python manage.py migrate
python manage.py runserver
Configuration lives in config/settings.py and environment variables in .env.example. '''
def shell_commands(markdown: str) -> list[str]: """Return every non-comment line from bash, sh, or shell code blocks.""" blocks = re.findall(r"(?:bash|sh|shell)\s*\n(.*?)", markdown, re.DOTALL) return [ line.strip() for block in blocks for line in block.splitlines() if line.strip() and not line.strip().startswith("#") ]
def missing_paths(markdown: str, root: str = ".") -> list[str]: """Return referenced file paths that do not exist in the project.""" candidates = set(re.findall(r"([\w./-]+0(?:py|txt|toml|cfg|example|md|json|yml|yaml))", markdown)) candidates |= set(re.findall(r"-r\s+([\w./-]+)", markdown)) return sorted(path for path in candidates if not (Path(root) / path).exists())
print(shell_commands(README)) print(missing_paths(README)) Output (in a project that has requirements.txt and config/settings.py, but no .env.example):
['python -m venv .venv', 'source .venv/bin/activate', 'pip install -r requirements.txt', 'python manage.py migrate', 'python manage.py runserver'] ['.env.example'] Code Explanation shell_commands()
Finds code blocks marked as bash, sh, or shell. Returns each non-empty line that is not a comment. These are the commands a reader will run. The list can be reviewed or run in a clean test environment, such as a fresh container in continuous integration, to confirm the setup instructions actually work. missing_paths()
Finds file paths written in backticks with common file extensions, and files referenced by pip install -r. Checks whether each exists relative to the project root. In this example, the README mentions .env.example, which the project does not contain, so new developers following the README would be confused. Running Commands Safely Never run documentation commands automatically on your own machine or a server. Run them in an isolated, disposable environment, such as a container created for the test, so that a wrong or destructive command cannot cause damage.
Keeping Documentation Current Practice How Generate from current project files Re-run prompts when files change Check commands and paths in CI Run the checks above on every pull request Update docs with code changes Make documentation part of the pull request checklist Date and own documents Each document has an owner and a "last reviewed" date Prefer linking to reference over copying it Fewer copies means fewer outdated versions Common Mistakes Mistake 1: One Document for Every Purpose What it is: A single long document mixing tutorial steps, reference tables, and explanations.
Why it happens: "Documentation" is treated as one task.
What it causes: Readers cannot find what they need.
How to fix it: Choose a documentation type and audience for each document.
Mistake 2: Untested Commands What it is: Publishing setup or runbook commands that were never run.
Why it happens: Generated commands look correct.
What it causes: Failed setups and dangerous mistakes during incidents.
How to fix it: Extract commands and test them in a clean, isolated environment.
Mistake 3: Invented Details What it is: Documentation describing settings, services, or licenses that do not exist.
Why it happens: The model fills sections with plausible content.
What it causes: Readers lose trust in all documentation.
How to fix it: Provide real project files, require TODO for missing information, and mark inferences.
Mistake 4: Documentation That Never Changes What it is: Generated documentation that is not updated with the code.
Why it happens: Documentation is treated as a one-time task.
What it causes: Gradual drift until the documentation misleads.
How to fix it: Automate checks and include documentation in every relevant change.
Best Practices Choose the documentation type and audience first. Tutorial, how-to guide, reference, or explanation.
Generate from real project files. Trees, requirements, settings, configuration, and code.
Make gaps and inferences visible. Use TODO and "(inferred)" markers.
Mark risky steps in runbooks. Describe the impact of every command that changes production.
Record decisions with ADRs. Preserve the "why" for future developers.
Check commands and paths automatically, and test commands in isolation. Documentation must work when followed.
Try It Yourself Exercise 1: README From Project Files Use Recipe 1 with the file tree, requirements, environment example, and settings excerpt of one of your projects. Run shell_commands() and missing_paths() on the result. Then follow the setup steps in a fresh environment, such as a new virtual environment or container, and record any step that fails.
Exercise 2: Write a Runbook Choose a realistic problem for one of your deployed applications, such as "the site returns 502 errors" on a server running Nginx and Gunicorn. Use Recipe 4 with your actual infrastructure notes. Check that every risky step is marked with its impact, and test the diagnosis commands on a staging server.
Exercise 3: Record a Decision Think of a technical decision you made recently, such as choosing a hosting platform or database. Write rough notes about the options and reasons, then use Recipe 5 to produce an ADR. Check whether the model invented any reasons that were not in your notes.