When you pick up the second agent, you discover AI is a context problem. When you pick up the fifth, you discover it’s a context-coordination problem. The first is solved with better prompts. The second isn’t.
The question that shows up is simple: how do two or more agents work in parallel on the same feature, without one’s work overwriting the other’s, and without each one having to re-read everything that happened before to understand the current state?
The answer I’ve been using is what I’ve come to call a context lattice — a grid of versioned lat.md files that serve as the canonical source of context. It’s not original. It’s a remix of design docs, ADRs1, and what the spec-driven-development crowd calls a “shared brain.” But the idea grows teeth when you put multiple Claude Code agents (or Codex, or Cursor — doesn’t matter) reading and writing to the same lattice in parallel.
The concrete problem
Picture this scenario, which is real: you’re implementing a PIX feature in e-commerce. The feature touches four areas:
- Backend — charge-creation endpoint, confirmation webhook, idempotency.
- Frontend — checkout flow, status polling, timeout fallback.
- Operations — observability, failure-rate alarm, dashboard.
- Integration — PSP adapter, retry policy, dead letter queue.
Each of these can be attacked by a different agent, in parallel. But all of them have to agree on:
- The shape of the payload in flight.
- The idempotency key (and how it’s generated).
- The possible states of the charge and the valid transitions between them.
- What happens when the webhook arrives before the response of the creation POST.
If each agent decides this independently, you end up with four implementations that talk to each other like they just met.
The structure of the lattice
A lat.md file has three sections, always in this order:
# Lattice — feature/pix-checkout
## IntentWhat we're building, in one sentence. Why. For whom.No epic, no JIRA, no story points.
## DecisionsDecisions made that affect more than one piece.Each decision is one line: "[2026-04-21] Idempotency via SHA256(orderId+psp).Reason: PSP X returns 502 sometimes, we want retry with no side effect."
## Open questionsThings we haven't decided yet but will need to.Named, not vague. "Q1: webhook arrives before the POST — ignore orbuffer 30s?"Each agent, before starting work, reads the feature’s lat.md. Each agent, on making a decision that affects the other areas, records it under Decisions. Each agent, on hitting a question whose answer affects the other areas, records it under Open questions and waits — it doesn’t decide solo.
The golden rule: nothing under Decisions changes without you announcing the change. A decision is a commit. You can revoke it — but you have to write a new line recording the revocation.
Why this works better than JIRA
Three reasons. First, it’s in Markdown, in the repository, versioned by the same Git that versions the code. Context and code travel together. Second, it’s in a format that agents read natively — it’s not an API adapter, it’s just a file. Third, it forces decisions to be explicit. You can’t “implement” without recording what you decided, because the next agent is going to read it.
Compared with Slack — the default coordination mechanism of most teams — the advantage is absurd. Slack is write-only to the future: what got discussed yesterday is buried under a thousand messages, and nobody’s going to mine for it. lat.md is read-first.
The detail nobody mentions
You need a human (or a meta agent) reviewing the lat.md files periodically. The Open questions pile grows faster than you’d think. Without someone cleaning, closing, and promoting Open → Decision, the lattice turns into a graveyard of TODOs.
In my setup, the final step of each work cycle is a specific agent — I call it the lattice-curator — that reads all the active lat.md files and asks me: which Open questions can already be resolved based on what’s implemented? Which Decisions conflict with the code that got written? It’s a maintenance agent, and it’s the most underrated piece of the system.
Where this touches the real
If you’re on Claude Code, the cheapest way to test this is to drop a lat.md file at the root of the feature and instruct each subagent to read it before starting and write to it when done. The Claude Code subagents docs cover how dispatch works; the lattice is what makes the dispatch coherent.
If you’re on the SDK directly, the Agent SDK docs have examples of passing shared context. Adapt: pass the lat.md content as the initial system message, and give the agent an update_lattice(section, content) tool that writes back to the file.
It’s not magic. It’s just the recognition that shared context has to live somewhere — and that somewhere can’t be each agent’s individual memory, because agents don’t share memory. They share a filesystem.
Footnotes
-
Architecture Decision Record. See Michael Nygard, “Documenting Architecture Decisions” — the canonical reference since 2011. A classic ADR is more formal; the lattice is the pragmatic version for the fast AI iteration loop. ↩