Planning

Trade-offs and alternatives: make the design section argue

September 15, 2026

The win for today: the three design paragraphs of the DocuDex doc — CLI, storage, serving — rewritten so each names what it cost, and an alternatives section that mirrors them: for every choice, the option it beat and why. About forty minutes. Start from the lesson 2 draft.

Key idea —

A design paragraph is finished when it has four parts: the choice, the reason, the cost, and the open question if there is one. Your current paragraphs have the first two. The cost is what lets a reviewer disagree with you precisely instead of vaguely.

1. Why the cost is the part that matters (4 min)

Ubl's rule from Design Docs at Google is that the design section should focus on trade-offs rather than implementation detail — the doc exists to surface the decisions a senior engineer might make differently. A paragraph that only gives reasons reads as finished; there is nothing for a reviewer to push on except "I disagree", which is not useful to either of you. A paragraph that names its cost invites "is that cost acceptable?", which is a conversation with an answer.

The Rust RFC template makes this structural. It has a Drawbacks section whose whole prompt is "why should we not do this?", and a Rationale and alternatives section asking why this design is the best in the space of possible designs, what other designs were considered and why not, and what the impact of not doing it would be. Steal the drawbacks question: every design choice gets asked "why not?" before it is written down.

Ousterhout's A Philosophy of Software Design supplies the vocabulary for many of the costs you will name: complexity is anything that makes the system harder to understand or change, and it accumulates from dependencies and obscurity. "This choice adds a second storage format that has to be kept in sync" is a complexity cost, and it should be said in those words.

2. Which of your paragraphs argue? (5 min)

These are the design paragraphs from your draft, compressed. Sort them.

Choice with a cost, reason only, or assertion only?0 of 5

CLI as the entry point: developers and coding agents both live in the terminal; agents can be told to keep DocuDex current and to look up repo-scoped docs.

Storage "has to be" SQLite plus Markdown: Markdown for the web app and for agents, SQLite for full-text search.

Go only for the MVP: DocuDex is written in Go so it can be dogfooded, and Go generates docs from source the way pkg.go.dev does.

Browsing only via a local web app; no TUI yet. The web app gets full-text search and keyboard shortcuts.

A manifest file committed to version control is the source of truth for a team, so team use is free.

None of the five has a cost. That is not a criticism of the thinking — you know the costs, which is why you could sort them — it is the gap between knowing and writing.

3. The four-part paragraph (5 min)

Here is your CLI paragraph rewritten in the form. Same decision, same reasons.

Reason only
I'm building a CLI as the entrypoint into the product. This is because more and more developers are using the terminal for their work but it's not just humans. Coding agents are being run in the terminal. I'm building the CLI so both humans and agents can run DocuDex. Agents could be instructed to keep DocuDex up-to-date whenever new dependencies are added… For all of these reasons, DocuDex will ship as a CLI.
Choice, reason, cost, question
DocuDex ships as a CLI rather than a desktop app or editor extension. Both audiences — developers and coding agents — already work in the terminal, and an agent can be told to run sync when go.mod changes and lookup when it needs a symbol. The cost is reach: nothing is visible until serve runs, and developers who would try an extension will never install a CLI. I accept that for the MVP because agents are the audience I can't reach any other way. Open: whether the agent interface is a subcommand, files on disk the agent reads directly, or an MCP server.
Choice (CLI, and what it was chosen over), reason (both audiences in the terminal), cost (reach), why the cost is acceptable, and the open question moved from the end of the doc to the paragraph it belongs to.

Two things to notice. "Rather than a desktop app or editor extension" names the alternative inside the choice; that sentence is what the alternatives section will expand. And "I accept that because…" is the sentence that makes it a decision rather than a list of considerations.

4. Do it (25 min)

Rewrite the storage and serving paragraphs in the four-part form, and add a short one for the manifest. For each, before you write, answer the drawbacks question on paper: why should I not do this? If you cannot think of a reason, you have not found the alternative yet.

Prompts, so you do not have to invent the alternatives from nothing:

Then rewrite Alternatives considered so it mirrors the design: one short entry per design choice, naming the option that lost and the trade-off that decided it. Your current entries (scraping, hosted, TypeScript) are about scope; keep them, but move them under the goals or non-goals they justify. Finally, take "via godoc" out of the goal it is still attached to and let it live here, as the choice it is.

Self-review: does the design section argue?0 of 7

5. Retrieval (2 min)

Two of these are from earlier lessons.

Q1. A design paragraph is complete when it has:

Q2. The Rust RFC template's Drawbacks section asks:

Q3. A real alternative is one you:

Q4. Sourcegraph's 'Reviewing problem' label means reviews should:

The Rust RFC template itself — five minutes. Read the section prompts as questions to ask of your own doc, not as headings to copy. Then, if you have twenty minutes more, chapter 2 of Ousterhout ("The nature of complexity") gives you the words for the costs you are about to write.