Module 1: Onboarding with AI — 5-10x Faster
Documenting Findings with Claude Code
Documenting Findings with Claude Code
Capsule description
You explored the codebase. You built your mental model. You know the project has 3 layers, that order_service.py is the central hub, and that there's a circular dependency between notification and order_service. Excellent. Now close the terminal, go to sleep, and come back tomorrow. How much of that do you remember precisely? The honest answer: less than 50%.
Knowledge that lives only in your head is ephemeral. It degrades over time, gets distorted by new experiences, and is impossible to share. The real result of onboarding isn't "now I understand it" — it's a document that captures your understanding precisely, in an organized and useful way for others. A well-made onboarding doc is the most valuable artifact you can produce in your first hours with a new codebase: it reduces the next developer's onboarding from weeks to hours.
In this capsule you're going to learn to use Claude Code to generate each section of a professional onboarding doc: structure overview, key patterns, gotchas, entry points, and data flows. You're not going to write the document from scratch — you're going to guide Claude Code with specific prompts so it generates drafts that you edit, correct, and complete. The result is a document you could hand to a new colleague that would save them weeks of exploration.
Why Documentation Is THE Output of Onboarding
The "I already get it" problem
There are two types of comprehension:
Ephemeral comprehension:
──────────────────────
"I already read the code, I understand how it works."
→ 24 hours later: "Wait, what was the relationship between orders and payments?"
→ 1 week later: "I need to re-read everything from scratch."
→ Value for the team: ZERO (only you "understood" it and you already forgot)
Documented comprehension:
───────────────────────────
"Here's the onboarding doc. Section 2 explains the architecture,
section 4 has the gotchas I discovered, section 5 shows the data flow."
→ 24 hours later: you open the doc and remember instantly
→ 1 week later: the doc is still there, updated
→ Value for the team: HIGH (anyone can read it)
The ROI of documenting
| Scenario | Without onboarding doc | With onboarding doc |
|---|---|---|
| You, 2 weeks later | You re-explore parts you forgot (~2-4 hrs) | You open the doc (~5 min) |
| A new developer joins | Repeats your whole process (~2-4 weeks) | Reads your doc + explores gaps (~2-3 days) |
| Code review of another module | "I don't know how that part works" | Consults the relevant doc section |
| Production incident | Look for who knows how X works | Open the doc, go to the data flow section |
| 5 new developers in 1 year | 5 x 2-4 weeks = 10-20 weeks lost | 5 x 2-3 days = 10-15 days |
The math is clear: 2-3 hours documenting saves 10-20 weeks of lost productivity per year in a growing team.
What makes an onboarding doc good
A good onboarding doc has these characteristics:
- ✅ Structured: clear sections, navigable, you can go straight to what you need
- ✅ Precise: reflects the current code, not an idealized version
- ✅ Opinionated: includes observations, gotchas, and "things that surprised me"
- ✅ Actionable: a developer can read it and start contributing
- ✅ Maintainable: easy to update when the code changes
- ❌ It's not exhaustive: it doesn't document every function. It documents what matters.
- ❌ It's not a tutorial: it doesn't explain Python or FastAPI. It assumes the reader knows how to program.
Structure of the Onboarding Doc
A professional onboarding doc has 6 sections. Each one answers a critical question a new developer has when they arrive at the project.
Section 1: Project Overview
Question it answers: "What does this project do and why does it exist?"
## Project Overview
**What it is:** [1-2 sentences describing the project]
**Who it's for:** [Users/clients of the system]
**Stack:** [Language, framework, DB, external services]
**Size:** [~X files, ~Y lines of code, Z dependencies]
**Status:** [Active/maintenance/legacy. Last commit: date]
How to generate it with Claude Code:
claude "Generate a Project Overview of this project in markdown format.
Include: what it does, who it's for, tech stack, approximate size
(files and lines of code), and project status
(look at the git history to determine recent activity)."
Expected output:
## Project Overview
**What it is:** REST API for e-commerce order management.
Handles users, products, orders, payments (via Stripe),
and notifications (via SendGrid).
**Who it's for:** The e-commerce web frontend and mobile app.
Consumed by ~3 clients: web app (React), mobile app (React Native),
and admin dashboard (internal).
**Stack:** Python 3.11, FastAPI, SQLAlchemy 2.0, PostgreSQL 15,
Redis (cache), Stripe API, SendGrid.
**Size:** 47 Python files, ~8,200 lines of code,
23 direct dependencies.
**Status:** Active. Last commit: 3 days ago.
~15 commits/week. 4 active contributors.
Section 2: Architecture Overview
Question it answers: "How is the code organized?"
This section takes your Level 1 mental model and turns it into permanent documentation.
claude "Generate an 'Architecture Overview' section for an onboarding doc.
Include:
1. Layer diagram (ASCII or Mermaid)
2. Which directory corresponds to each layer
3. The dependency rule between layers
4. The system's entry points
5. External dependencies and what each one is used for"
Expected output:
## Architecture Overview
### Layers
The project follows a 3-layer architecture with a strict
dependency rule: Layer N only calls Layer N+1.
Presentation (api/) → Receives HTTP requests, validates input │ ▼ Business (services/) → Business logic, orchestration │ ▼ Data (repositories/) → DB queries, models, persistence
### Directory Structure
project/ ├── api/ │ ├── v1/routes/ # Endpoints by domain │ ├── middleware/ # Auth, CORS, logging │ └── dependencies/ # Dependency injection ├── services/ # Business logic ├── repositories/ # DB access ├── models/ # SQLAlchemy models ├── core/ # Config, security, utils ├── tests/ # Tests by module └── main.py # Entry point (FastAPI app)
### Entry Points
- `main.py` — HTTP server (FastAPI, uvicorn)
- `cli/manage.py` — Admin commands (seed DB, migrations)
- `worker.py` — Background jobs (Celery)
### External Dependencies
| Dependency | What for |
|-------------|----------|
| PostgreSQL | Main database |
| Redis | Session cache and rate limiting |
| Stripe | Payment processing |
| SendGrid | Sending transactional emails |
| Celery | Asynchronous background jobs |
Section 3: Key Patterns
Question it answers: "What conventions and patterns should I follow?"
claude "Analyze this project and identify the patterns and conventions
that are used consistently. Document:
1. Architectural patterns (repository pattern, service layer, etc.)
2. Naming conventions (files, classes, functions, variables)
3. Error handling patterns
4. Testing patterns
5. Any custom or unusual pattern"
Expected output:
## Key Patterns
### Repository Pattern
Each model has its repository in `repositories/`.
Repositories are NEVER called directly from routes —
always through a service.
```python
# CORRECT
# routes/orders.py
order = order_service.create_order(user_id, items)
# INCORRECT (violates the pattern)
# routes/orders.py
order = order_repo.create(user_id=user_id, items=items)
Service Layer Pattern
Business logic lives in services/. A service can call
other services and repositories, but never routes.
Error Handling
All business errors inherit from core/exceptions.py:AppError.
Routes catch them with a global exception handler in main.py.
# Error pattern
class OrderNotFoundError(AppError):
status_code = 404
message = "Order not found"
Naming Conventions
- Files: snake_case (
order_service.py) - Classes: PascalCase (
OrderService) - Functions: snake_case (
create_order) - Constants: UPPER_SNAKE (
MAX_RETRY_COUNT) - Tests:
test_prefix (test_create_order_success)
Testing Pattern
- One test file per module:
tests/test_order_service.py - Fixtures in
tests/conftest.py - Mocks for external APIs (Stripe, SendGrid)
- Factories to create test data (
tests/factories/)
### Section 4: Gotchas and Traps
**Question it answers:** "What's going to surprise me or bite me if I don't know it?"
This is the most valuable section of the onboarding doc. No README has it. Only someone who explored the codebase can write it.
```bash
claude "Identify the 'gotchas' of this project — things that
would surprise a new developer or could cause bugs
if not known. Look for:
1. Circular dependencies
2. Non-obvious side effects
3. Undocumented configuration
4. Code that looks like one thing but does another
5. Critical TODOs or FIXMEs
6. Inconsistencies in style or patterns"
Expected output:
## Gotchas
### ⚠️ Circular dependency notification ↔ order_service
`notification.py` imports `order_service` to get the order
data when sending emails. This creates a circular import that
is resolved with a lazy import inside the function. If you move
imports to the top-level, it breaks.
### ⚠️ create_order() has no atomic transaction
If the Stripe payment is charged but the order creation in the DB
fails, the user is left charged with no order. There's a TODO on line 147
but it hasn't been resolved.
### ⚠️ Redis is mandatory (not optional)
Although it looks like cache, the rate limiter depends on Redis.
If Redis isn't running, ALL requests fail with 500.
There's no fallback.
### ⚠️ The tests use SQLite, production uses PostgreSQL
There are queries with PostgreSQL-specific functions (jsonb_extract_path)
that aren't really tested. The tests pass but the code
could fail in production.
### ⚠️ Undocumented environment variables
12 env vars are needed to run the project.
Only 5 are in the README. The other 7 are scattered
in core/config.py and you have to read it to discover them.
Section 5: Data Flows
Question it answers: "How does data flow through the system?"
claude "Document the 3 main data flows of this project.
For each one:
1. Trigger (what starts it)
2. Step by step (what modules it touches, in order)
3. Side effects (DB writes, API calls, emails)
4. Final result
Use text format with arrows, not diagrams."
Expected output:
## Data Flows
### Flow 1: Create an Order
POST /api/v1/orders {user_id, items} → routes/orders.py: validates input (Pydantic) → services/order_service.py: create_order() → repositories/user_repo.py: verify user exists → repositories/product_repo.py: verify stock (for each item) → Computes total + tax → services/payment_service.py: charge() → core/stripe_client.py: Stripe API call → repositories/payment_repo.py: save transaction → repositories/order_repo.py: create order in DB → repositories/product_repo.py: decrement stock → services/notification.py: send confirmation email → SendGrid API call (async, non-blocking) ← Response: {order_id, status: "confirmed", total}
Side effects: DB write (3 tables), Stripe charge, email
### Flow 2: Authentication
POST /api/v1/auth/login {email, password} → routes/auth.py: validates input → services/auth_service.py: authenticate() → repositories/user_repo.py: look up by email → core/security.py: verify_password(hash, plain) → core/security.py: create_jwt_token(user_id) ← Response: {access_token, token_type: "bearer"}
Side effects: none (read-only + token generation)
### Flow 3: Stripe Webhook
POST /api/v1/payments/webhook {stripe_event} → middleware/stripe_webhook.py: verify signature → routes/payments.py: handle_webhook() → services/payment_service.py: process_webhook() → If event == "charge.refunded": → repositories/order_repo.py: update status to "refunded" → services/notification.py: send refund email ← Response: 200 OK (Stripe requires a fast response)
Side effects: DB write (if refund), email (if refund)
Section 6: Entry Points and Getting Started
Question it answers: "Where do I start if I want to make a change?"
claude "Generate a 'How to start contributing' section for an onboarding doc.
Include:
1. How to run the project locally (step by step)
2. How to run the tests
3. Where to start if you want to add a new endpoint
4. Where to start if you want to fix a bug
5. Files you should read first (top 5)"
Expected output:
## Getting Started
### Local Setup
```bash
git clone <repo-url>
cd project
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
cp .env.example .env # Edit with your credentials
docker-compose up -d # PostgreSQL + Redis
alembic upgrade head # Migrations
python cli/manage.py seed # Test data
uvicorn main:app --reload
Run Tests
pytest # All tests
pytest tests/test_orders.py # One module
pytest -x # Stop on first failure
pytest --cov # With coverage
Add a New Endpoint
- Create route in
api/v1/routes/<domain>.py - Create (or extend) service in
services/<domain>_service.py - Create (or extend) repository in
repositories/<domain>_repo.py - Add model if it's new in
models/<domain>.py - Create migration:
alembic revision --autogenerate -m "add X" - Add tests in
tests/test_<domain>_service.py
Files You Should Read First
main.py— Understand how the server startsapi/v1/routes/orders.py— Example of a complete routeservices/order_service.py— Example of a complete servicecore/config.py— All the project's configurationtests/conftest.py— Fixtures and test setup
---
## Generate the Complete Onboarding Doc with Claude Code
### Strategy: section by section, not all at once
The most common mistake is asking Claude Code to "generate an onboarding doc for the whole project" in a single prompt. The result will be superficial and imprecise. The correct strategy is to generate section by section, validate each one, and then assemble.
```bash
# Step 1: Project Overview (5 min)
claude "Generate the Project Overview section of an onboarding doc
for this project. Markdown format. Include: what it does, stack,
size, status, who it's for."
# Step 2: Architecture Overview (10 min)
claude "Generate the Architecture Overview section. Include: layer
diagram, directory structure, entry points, external
dependencies."
# Step 3: Key Patterns (10 min)
claude "Generate the Key Patterns section. Analyze the code and identify:
architectural patterns, naming conventions, error handling patterns,
testing patterns."
# Step 4: Gotchas (15 min — the most valuable section)
claude "Identify the project's gotchas. Look for: circular dependencies,
non-obvious side effects, undocumented configuration, inconsistencies,
critical TODOs, confusing code."
# Step 5: Data Flows (10 min)
claude "Document the 3 main data flows. For each one: trigger,
step by step with modules, side effects, final result."
# Step 6: Getting Started (5 min)
claude "Generate the 'Getting Started' section: local setup, run tests,
how to add an endpoint, files to read first."
# Step 7: Assemble
claude "I have these 6 sections of an onboarding doc. Assemble them
into a single coherent markdown document. Add a table of
contents at the beginning and check that there are no inconsistencies between
sections."
Total time: ~55-60 minutes for a professional onboarding doc of a 5K-10K-line codebase.
Review and refine
After Claude Code generates each section, your job is to:
- Verify precision: Does the layer diagram reflect reality?
- Add opinion: Claude Code is neutral. You add "this looks risky to me" or "this is confusing."
- Add context: Claude Code doesn't know why certain decisions were made. If you found out (git blame, asking the team), add it.
- Remove noise: If a section has obvious or irrelevant information, remove it.
# Refine a specific section
claude "The Gotchas section you generated mentions 'the tests use
SQLite but production uses PostgreSQL'. Add a concrete example:
which specific query could fail because of this difference?"
Complete Example: Onboarding Doc
So you can see what the final product looks like, here's a complete onboarding doc for a sample project:
# Onboarding Doc: E-Commerce API
**Generated:** 2026-04-01
**Author:** [Your name] (with assistance from Claude Code)
**Project:** E-Commerce REST API
**Onboarding time:** 1.5 hours
---
## Table of Contents
1. Project Overview
2. Architecture Overview
3. Key Patterns
4. Gotchas
5. Data Flows
6. Getting Started
---
## 1. Project Overview
REST API for e-commerce management. Handles users,
products, orders, payments (Stripe), and notifications (SendGrid).
- **Stack:** Python 3.11, FastAPI, SQLAlchemy 2.0, PostgreSQL, Redis
- **Size:** 47 files, ~8,200 LOC, 23 dependencies
- **Status:** Active (~15 commits/week, 4 contributors)
- **Consumers:** Web app (React), Mobile (React Native), Admin dashboard
## 2. Architecture Overview
3 layers with unidirectional dependency:
api/ (Presentation) → services/ (Business) → repositories/ (Data)
Entry points: main.py (HTTP), cli/manage.py (admin), worker.py (jobs)
## 3. Key Patterns
- Repository pattern for DB access
- Service layer for business logic
- Exception hierarchy from core/exceptions.py:AppError
- Factories for test data
- Pydantic models for input validation in routes
## 4. Gotchas
⚠️ create_order() is not atomic (Stripe charge + DB write not transactional)
⚠️ Redis is MANDATORY (rate limiter requires it, there's no fallback)
⚠️ Tests with SQLite ≠ Production with PostgreSQL (jsonb queries untested)
⚠️ Circular import notification ↔ order_service (lazy import hack)
⚠️ 7 of 12 env vars aren't documented in the README
## 5. Data Flows
Main flow (create order):
POST /orders → validate → check stock → charge Stripe
→ create in DB → decrease stock → send email → 201 Created
## 6. Getting Started
1. Clone + venv + pip install
2. docker-compose up (PostgreSQL + Redis)
3. alembic upgrade head + seed
4. uvicorn main:app --reload
5. Read: main.py → routes/orders.py → services/order_service.py
This is a condensed example. Your complete version will be 3-5 pages with more detail in each section.
Making the Documentation Useful For Others
Principle: write for the developer who arrives tomorrow
You're not writing for yourself. You're writing for someone who:
- ✅ Knows how to program in Python
- ✅ Knows FastAPI (or can learn it quickly)
- ❌ Has never seen this codebase
- ❌ Doesn't know why certain decisions were made
- ❌ Doesn't know where the traps are
Practical tips
1. Use direct language, not corporate:
❌ "The system utilizes an architecture based on the repository
pattern to abstract the persistence layer."
✅ "The DB queries are in repositories/. Never do queries
directly from a route — always go through a service
that calls the repository."
2. Include the "whys", not just the "whats":
❌ "Redis is a project dependency."
✅ "Redis is MANDATORY — the rate limiter uses it and there's no fallback.
If Redis isn't running, all requests return 500."
3. Add code examples when they're useful:
❌ "Errors are handled with custom exceptions."
✅ "Errors inherit from AppError:
class OrderNotFoundError(AppError):
status_code = 404
message = 'Order not found'
The global handler in main.py catches them automatically."
4. Keep it up to date:
# Every time you make a significant change to the codebase,
# ask Claude Code to update the onboarding doc:
claude "I just added a new service (services/shipping_service.py)
that handles shipping calculation. Update the Architecture
Overview section of the onboarding doc to include this new module."
Comparison: Documentation with Claude Code vs Manual
| Criterion | Manual Documentation | Documentation with Claude Code |
|---|---|---|
| Time | 4-8 hours for a complete doc | 1-2 hours for a complete doc |
| Precision | Depends on your comprehension | Verified against the real code |
| Coverage | You skip what you didn't see | Claude Code analyzes the whole project |
| Gotchas | Only the ones you discovered | Claude Code finds patterns systematically |
| Updating | Rewrite sections manually | Prompt to update a specific section |
| Consistency | Variable (depends on the day) | Consistent (same structure always) |
| Bias | Documents what seemed interesting to you | Documents what matters objectively |
When manual documentation is better:
- ✅ When you need to capture human context: "we did it this way because the CEO asked for this feature in 2 days"
- ✅ When you need subjective opinion: "this part of the code is a disaster and should be refactored"
- ✅ When the codebase is so legacy that Claude Code can't parse it well
When Claude Code is better:
- ✅ For 80% of the onboarding doc (structure, patterns, data flows)
- ✅ To keep the doc updated as the code changes
- ✅ To discover gotchas a human might overlook
- ✅ To be exhaustive without being tedious
Trade-off: The best documentation combines both: Claude Code generates 80% (structure, precision, coverage) and you add 20% (context, opinion, prioritization).
Connection with the Project
In the Module Project: Onboarding to an Open-Source Codebase (this module's project):
- You'll produce a complete onboarding doc as one of the main deliverables
- You'll use the 6-section structure to organize your findings from the open-source project
- The Gotchas section will be especially relevant because open-source projects have undocumented traps
- The technique of generating section by section with Claude Code is exactly how you'll produce your deliverable
- The onboarding doc is the tangible evidence that you understood the codebase — "I explored it" isn't enough
Everything you learn here becomes your main deliverable for the project.
Troubleshooting
Problem 1: Claude Code generates documentation that's too generic
Cause: The prompt doesn't specify the expected level of detail or include examples. Solution: Add context to the prompt and ask for specificity:
# Instead of:
claude "Document this project's architecture."
# Use:
claude "Document this project's architecture for an onboarding doc.
Level of detail: a senior developer who knows Python and FastAPI
but has never seen this codebase. Include:
- Layer diagram with real directory names
- Dependency rule between layers
- The 3 entry points with what each one does
Don't include explanations of what FastAPI or SQLAlchemy are."
Problem 2: The doc sections contradict each other
Cause: You generated each section in a separate prompt and Claude Code didn't have cross-context. Solution: After generating all the sections, do an integration step:
claude "Review this complete onboarding doc and identify
inconsistencies between sections. For example: the Architecture
section says X but the Data Flow section implies Y.
List all the inconsistencies you find."
Problem 3: The Gotchas section is empty or trivial
Cause: Claude Code doesn't know what to look for if you don't give it specific criteria. Solution: Ask for specific categories of gotchas:
claude "Look for gotchas in these specific categories:
1. Circular dependencies (analyze all the imports)
2. Hidden side effects (functions that do more than their name suggests)
3. Hardcoded or undocumented configuration
4. Discrepancies between tests and production
5. Dead code or half-implemented features
6. Exceptions that are swallowed silently (except: pass)"
Problem 4: The doc is too long and nobody will read it
Cause: You included too much detail in each section. Solution: Create two versions — a TL;DR and a complete one:
claude "From this complete onboarding doc, generate a
TL;DR version of at most 1 page. Include only: stack,
layer diagram (3 lines), top 5 gotchas, and the 3 commands
to run the project. Put a link to the complete doc."
Problem 5: You don't know how up to date the doc is after 2 weeks
Cause: The codebase changed but the doc didn't. Solution: Create a validation checklist:
claude "Compare this onboarding doc with the current state of the code.
Identify sections that are outdated:
- New files the doc doesn't mention?
- Dependencies that changed?
- Patterns that are no longer used?
- New entry points?"
Exercises
Exercise 1: Project Overview of httpx (Easy)
Clone httpx and generate the "Project Overview" section of the onboarding doc using Claude Code. Include: what it does, stack, size, status, consumers.
See solution
git clone https://github.com/encode/httpx.git
cd httpx
claude "Generate the Project Overview section of an onboarding doc
for this project. Include: what it does, tech stack,
approximate size (files and lines), status (git activity),
and who uses it (consumers)."
Expected output:
## Project Overview
**What it is:** HTTP library for Python, compatible with sync and async.
A modern replacement for `requests` with native support for HTTP/2,
async/await, and type hints.
**Stack:** Python 3.8+, httpcore (transport), certifi (SSL),
idna (domain internationalization), sniffio (async detection).
**Size:** ~40 core files, ~15,000 lines of code,
~200 test files, 5 direct dependencies.
**Status:** Active and mature. ~500 contributors, 12K+ stars.
Regular releases. Last release: [recent date].
**Consumers:** Python developers who need an HTTP client.
Used as a dependency by FastAPI (for TestClient), Starlette,
and hundreds of open source projects.
Explanation: The Project Overview is the easiest section. Claude Code can extract all this information from the code, pyproject.toml, and git log. What matters is that it's precise and concise.
Exercise 2: Gotchas Section of httpx (Easy)
Using the same httpx project, generate the "Gotchas" section of the onboarding doc. Ask Claude Code to look specifically for: non-obvious dependencies, surprising behavior, and implicit configuration.
See solution
claude "Analyze httpx and generate the 'Gotchas' section for an onboarding doc.
Look for:
1. Behavior that isn't obvious from reading the documentation
2. Differences between sync Client and async AsyncClient
3. Default configuration that could surprise
4. Edge cases in handling redirects, timeouts, or encoding
5. Things that changed between recent versions"
Expected output:
## Gotchas
⚠️ Client and AsyncClient do NOT share implementation.
It's not that AsyncClient is a wrapper of Client.
They're separate implementations that use different transports.
⚠️ Redirects are limited to 20 by default.
If your API has more than 20 chained redirects, it fails
silently with TooManyRedirects.
⚠️ The default timeout is 5 seconds.
Different from requests (which has no default timeout).
If you don't specify a timeout, requests with slow APIs fail.
⚠️ The Client must be closed explicitly.
If you don't use `with Client() as client:`, the connections
stay open. There's a __del__ but it's not guaranteed.
⚠️ HTTP/2 is not enabled by default.
You need `Client(http2=True)` and the h2 dependency installed.
Explanation: The gotchas are the highest-value section in an onboarding doc. Claude Code can find them by analyzing the code, the tests, and the edge cases. A new developer who reads these gotchas saves hours of debugging.
Exercise 3: Data Flow of an HTTP Request (Medium)
Generate the "Data Flows" section of httpx's onboarding doc. Document the complete flow of a client.get("https://example.com") from the user's call to the response.
See solution
claude "Document the data flow of an HTTP request in httpx.
Trace client.get('https://example.com') step by step:
1. What method/function runs first
2. How the Request object is built
3. How authentication is processed (if any)
4. How it's sent via the transport
5. How the Response object is built
6. What it returns to the user
Include the specific files and functions it passes through."
Expected output:
## Data Flow: client.get(url)
- Client.get(url) → _client.py │ Calls Client.request(method="GET", url=url) ▼
- Client.request() → _client.py │ Builds Request(_models.py) │ Applies auth if any (_auth.py) │ Applies redirects, cookies, header defaults ▼
- Client._send() → _client.py │ Merges headers, prepares transport request ▼
- HTTPTransport.handle_request() → _transports/default.py │ Delegates to httpcore.ConnectionPool ▼
- httpcore.request() → [external dependency] │ TCP/TLS connection, sends HTTP bytes │ Receives response bytes ▼
- Builds Response → _models.py │ Status code, headers, body stream ▼
- Returns Response to the user
Side effects: TCP connection (kept in pool),
SSL handshake (first time), DNS lookup.
Explanation: The data flow is the section that most helps you understand how the project works internally. It's the perfect complement to the Architecture Overview (which shows the structure) — the data flow shows the behavior.
Exercise 4: Onboarding Doc Section by Section (Medium)
Choose a Python project you don't know (suggestions: rich, typer, pydantic). Generate the 6 sections of the onboarding doc using the "section by section" technique described in this capsule. Assemble the final document. Measure how long it took you.
See solution
# Example with rich
git clone https://github.com/Textualize/rich.git
cd rich
# Section 1: Project Overview (5 min)
claude "Generate the Project Overview section of the onboarding doc."
# Section 2: Architecture Overview (10 min)
claude "Generate the Architecture Overview section with a layer
diagram and directory structure."
# Section 3: Key Patterns (10 min)
claude "Generate the Key Patterns section: architectural patterns,
naming conventions, error handling."
# Section 4: Gotchas (15 min)
claude "Generate the Gotchas section: look for non-obvious dependencies,
surprising behavior, edge cases."
# Section 5: Data Flows (10 min)
claude "Generate the Data Flows section: document the flow of
console.print('Hello, World!') step by step."
# Section 6: Getting Started (5 min)
claude "Generate the Getting Started section: setup, tests, how to add
a new renderable."
# Assemble (5 min)
claude "Assemble these 6 sections into a coherent onboarding doc in
markdown. Add a table of contents and check for inconsistencies."
Target time: 55-60 minutes for the complete doc.
Explanation: This exercise replicates exactly what you'll do in the module project. The key is the time-boxing per section: don't spend 30 minutes on one section and 2 on another. The suggested distribution (5-10-10-15-10-5-5) is designed to maximize the doc's quality in the available time.
Exercise 5: Improve an Existing Onboarding Doc (Hard)
Take the onboarding doc you generated in Exercise 4. Now improve it:
- Add 3 personal opinions (things that seemed good or bad to you about the codebase)
- Add 2 gotchas that Claude Code didn't find but you did (reading the code)
- Create a 1-page TL;DR version
- Validate that the doc is still accurate by comparing it with the current code
See solution
# Step 1: Add personal opinions
# You do NOT do this with Claude Code — you write it yourself:
# Example opinions:
# "rich's rendering system is elegant: each object
# implements __rich_console__() and the console renders them
# polymorphically. However, the number of classes is
# overwhelming — there are 40+ renderables and it's not clear which
# one to use in each case."
# Step 2: Gotchas you found
# Read the code manually and look for things Claude Code didn't mention.
# Example: "The _inspect.py module uses eval() in some cases
# to render objects. This could be a security risk
# if used with untrusted input."
# Step 3: TL;DR version
claude "From this complete onboarding doc for rich,
generate a TL;DR version of at most 30 lines. Include:
stack, architecture in 1 paragraph, top 3 gotchas, and how to
run the project in 3 commands."
# Step 4: Validate accuracy
claude "Compare this onboarding doc with the current code of rich/.
Are there outdated sections? Files the doc doesn't mention?
Patterns that changed?"
Explanation: This exercise teaches you that the best onboarding doc combines what Claude Code generates (80% — structure, precision) with what you add (20% — opinion, human context, prioritization). The TL;DR version is crucial: nobody reads a 5-page doc when they're in a hurry, but they do read 30 lines.
Exercise 6: Onboarding Doc as a Team Tool (Hard)
Imagine your onboarding doc will be read by 5 new developers over the next 6 months. Take your doc from Exercise 4 and:
- Add a "Frequently Asked Questions" section with the 5 questions a new developer would ask
- Add a "Doc Changelog" section to track updates
- Create a script that automatically checks whether the doc is outdated
See solution
# Step 1: Frequently Asked Questions
claude "Based on this onboarding doc, generate a
'Frequently Asked Questions' section with the 5 questions a new
developer would probably ask. Include concise answers."
# Step 2: Changelog
# Add manually at the end of the doc:
# ## Changelog
# | Date | Author | Change |
# |-------|-------|--------|
# | 2026-04-05 | [Your name] | Initial creation |
# Step 3: Validation script
claude "Write a Python script that:
1. Reads the onboarding doc (ONBOARDING.md)
2. Extracts the file names mentioned
3. Verifies that those files exist in the project
4. Reports mentioned files that don't exist (outdated doc)
5. Reports new files in src/ that the doc doesn't mention (gaps)
It must be runnable with: python validate_onboarding.py"
Expected script:
#!/usr/bin/env python3
"""Validate that the onboarding doc reflects the current state of the project."""
import re
from pathlib import Path
def extract_mentioned_files(doc_path: str) -> set[str]:
"""Extract file names mentioned in the doc."""
content = Path(doc_path).read_text()
# Look for patterns like file.py, dir/file.py
pattern = r'[\w/]+\.py'
return set(re.findall(pattern, content))
def get_project_files(project_dir: str) -> set[str]:
"""List the project's Python files."""
project_path = Path(project_dir)
return {
str(f.relative_to(project_path))
for f in project_path.rglob("*.py")
if "test" not in str(f) and "__pycache__" not in str(f)
}
def validate(doc_path: str, project_dir: str) -> None:
"""Compare the doc with the project and report discrepancies."""
mentioned = extract_mentioned_files(doc_path)
actual = get_project_files(project_dir)
# Mentioned files that don't exist
missing = mentioned - actual
if missing:
print("⚠️ Files in the doc that do NOT exist in the project:")
for f in sorted(missing):
print(f" - {f}")
# New files not mentioned
new_files = actual - mentioned
if new_files:
print("\n📝 Files in the project NOT mentioned in the doc:")
for f in sorted(new_files):
print(f" - {f}")
if not missing and not new_files:
print("✅ The onboarding doc is up to date.")
if __name__ == "__main__":
validate("ONBOARDING.md", "src/")
Explanation: This exercise takes documentation to the next level: from a personal artifact to a team tool. The FAQ anticipates questions, the changelog lets you track changes, and the validation script automates the most tedious task (checking that the doc is up to date).
Summary
In this capsule you learned:
- Documentation is THE output of onboarding, not an extra. "I already get it" is ephemeral; a doc is permanent and shareable.
- A professional onboarding doc has 6 sections: Project Overview, Architecture, Key Patterns, Gotchas, Data Flows, Getting Started.
- The Gotchas section is the most valuable and the one no README contains. Only someone who explored the codebase can write it.
- The correct strategy is to generate section by section with Claude Code, not to ask for everything in one prompt. This gives more control and precision.
- The best onboarding doc combines 80% generated by Claude Code (structure, precision) with 20% human (opinion, context, prioritization).
- Documentation must be maintained. An outdated doc is worse than no doc because it creates false confidence.
- You write for the developer who arrives tomorrow: direct language, concrete examples, useful opinions.
Next capsule: Module Project — where you apply everything (exploration, mental model, documentation) to a real open-source codebase.
Additional Resources
-
"Docs for Developers" — Jared Bhatti et al. A practical guide on how to write effective technical documentation. The chapters on "writing for your audience" and "documentation types" directly complement this capsule.
-
"Living Documentation" — Cyrille Martraire The concept of documentation that's generated and validated automatically from the code. Inspiration for the validation script in Exercise 6.
-
Diátaxis Framework — https://diataxis.fr/ A framework for organizing technical documentation into 4 types: tutorials, how-to guides, reference, explanation. The onboarding doc is a hybrid of reference and explanation.
-
"The Documentation System" — Divio — https://documentation.divio.com/ A simplified version of Diataxis with concrete examples. Useful for understanding what type of documentation an onboarding doc is (and what type it's NOT).
-
Claude Code Documentation — https://docs.anthropic.com/en/docs/claude-code The official Claude Code reference. The section on context management is relevant for generating documentation of large projects.
-
"A Practical Guide to Writing Technical Specs" — Stack Overflow Blog Although it's about specs, not onboarding docs, the techniques for clear and structured writing apply directly.