Progressive disclosure
Keep the always-loaded context small by pointing at detail instead of including it.
Progressive disclosure is loading only what is needed now, with pointers to the rest. It is what lets a project have deep documentation without every session paying for all of it.
A context pointer is a mention in one document that tells the agent where to look for more — a path, a filename, a condition for reading it.
## Database Schema changes: read db/README.md first. It covers the migration workflow, the two-phase deploy rule, and why we never drop columns directly. ## Payments Anything touching src/payments/: read src/payments/AGENTS.md before editing. It has invariants that are not obvious from the code. ## Frontend forms We use a specific validation pattern. See docs/forms.md — read it before adding a new form, not before editing an existing one.
Three lines in the always-loaded brief. Hundreds of lines of detail available on demand. Sessions that never touch payments never pay for the payments documentation.
Nested briefs
Many harnesses support instruction files at multiple directory levels, loading the nearest ones. Where supported, this is progressive disclosure for free: src/payments/AGENTS.md loads when the agent works there and stays out of every other session.
If your harness does not support nesting, the pointer pattern above achieves the same effect with one extra tool call.
Write pointers with a trigger condition
A pointer without a condition gets read always or never. Include when to follow it:
| Weak pointer | Strong pointer |
|---|---|
| "See docs/forms.md for form conventions." | "Before adding a new form, read docs/forms.md. Not needed for edits to existing forms." |
| "Database docs are in db/README.md." | "Read db/README.md before writing any migration or changing any file in db/schema/." |
The same idea inside a session
Progressive disclosure is not only a file-layout technique. It is how you should load context by hand: start narrow, expand on evidence.
1. grep for the symbol ~100 tokens 2. read the one function that matched ~400 tokens 3. read its file only if needed ~4,000 tokens 4. read its callers only if needed ~8,000 tokens
Most tasks terminate at step 2. The reflex to open the whole file first is what fills windows.
Watch out
Pointers only work if the target is worth reading. A pointer to a stale doc is worse than no pointer: it costs a tool call and delivers a confident secondary source (Lesson 2.9). Audit pointer targets whenever you prune the brief.
Try it
Find the longest section of your brief and move it to its own file with a conditional pointer. Measure the starting token count of a fresh session before and after.
Takeaways
- Point at detail with a trigger condition instead of including it always.
- Use nested instruction files where the harness supports them.
- Load context narrow-to-wide inside sessions too: grep, then function, then file.
What makes a pointer good rather than just present?
A trigger condition. "See docs/forms.md" gives the agent no basis for deciding whether now is the time, so it either always reads it (no saving) or never does (no effect). "Before adding a new form, read docs/forms.md" makes the decision mechanical.
A course by Pieter Zandbergen