PATTERN 05 / CONTEXT
Let the code do the talking
Make code carry its own meaning, and keep comments for knowledge the code cannot express.
A comment should add information that reading the code would not give you.
The idea
When an agent writes code, it can also produce a running commentary: what each function does, what the next line will do, and why the obvious implementation is obvious. That leaves two descriptions of the same behavior to maintain.
Start with fewer comments, or none when the code is already clear. Use precise names, explicit types, small functions, and tests that show the intended behavior. Let people and agents read the implementation directly instead of making them reconcile it with a prose translation.
This is a working hypothesis for collaborating with agents: redundant explanations create another place for context to go stale. The goal is a codebase that is easier to understand and change, not a particular comment count.
When it helps
Reach for this when generated changes arrive with a comment above every step, or when comments describe behavior that the implementation no longer has. It matters especially when several agents touch the same area: one may change the code while another reasons from an old explanation.
It is also a useful review question. If a block needs a paragraph explaining what it does, could a better name, a clearer data structure, or a smaller function make that meaning visible?
Remove the narration
Delete comments that simply restate an operation. If a comment is compensating for an unclear name, fix the name first. Keep the change focused; an unnecessary abstraction can obscure more than a short comment.
In this example, the comments translate vague names into English. The code itself can carry that meaning.
// Check whether the user owns the project.
const ok = p.ownerId === u.id;
// Only allow the owner to archive an active project.
if (ok && p.status === 'active') {
archiveProject(p.id);
}Make meaning explicit
Use the vocabulary of the domain. The same behavior can be understood without the line-by-line explanation.
const isProjectOwner = project.ownerId === user.id;
const isActiveProject = project.status === 'active';
if (isProjectOwner && isActiveProject) {
archiveProject(project.id);
}Pair the implementation with tests for the rules that must survive later edits: an owner can archive an active project, and another user cannot. Tests give future collaborators something to check when they change the code.
Keep what the code cannot tell you
A blanket ban on comments would discard useful knowledge. Keep explanations of surprising constraints, rejected alternatives, external-system quirks, or why an apparently simpler change would be wrong. Put them beside the relevant code, and link to the decision or issue when that helps.
// The legacy importer treats a missing archive date as active.
// Keep the timestamp until that importer is retired.
project.archivedAt = now;Preserve required license headers, public API documentation, and meaningful tool directives. Document a subtle algorithm when rewriting it would make it less clear. When behavior changes, review the nearby comments as part of the same change.
Do not move every deleted comment into a giant instruction file. Put shared workflow guidance in repository instructions; keep local rationale close to the implementation.
Connect the patterns
This extends less prompt, more feedback into the codebase: make every explanation earn its place. Use AGENTS.md for how to work in the repository, SCENARIOS.md for observable journeys, and focused comments for intent that would otherwise be lost.