🗣️ What is Ubiquitous Language
Ubiquitous Language is a term coined by Eric Evans in Domain-Driven Design (2003). The idea is simple: the team, code, and documentation share exactly the same vocabulary. No translations between "business term" and "technical term." No synonyms. No ambiguity. One word, one concept.
In the context of working with agents (Claude Code, Codex, Copilot), ubiquitous language stops being a “best practice” and becomes critical infrastructure. Every ambiguous term costs tokens, attention, and iterations. Every well-defined term reduces prompts by orders of magnitude.
💡 Tip: the 20→1 rule
The practical heuristic is: if you need 20 words to explain a concept to the agent every time it comes up, that concept deserves a name. Define it in CONTEXT.md once, and use that name from then on.
The payoff is huge: you replace 20 repeated tokens on every turn with 1 named token and one definition line in the initial context.
Example: “materialization cascade”
✗ BEFORE (unnamed)
Every time the bug appeared, someone would write in the chat:
"When a user updates a derived field, all other fields that depend on it need to be recalculated in order, and if one fails, the subsequent ones become inconsistent, and we need to run everything again from the top..."
→ 40+ words, repeated across 12 different conversations.
✓ LATER (named)
We defined in CONTEXT.md:
materialization cascade: sequential recalculation of derived fields after a mutation.
"The bug is in the materialization cascade when step 3 fails."
→ 12 words, zero ambiguity.
📑 Anatomy of CONTEXT.md
O CONTEXT.md is the file that contains your project's ubiquitous language. It's the first file an agent reads when it starts working. Recommended minimum structure:
# MeuProjeto ## Language **materialization cascade**: recálculo sequencial de campos derivados após mutação de um campo-raiz. _Avoid_: "recálculo em cadeia", "refresh", "update propagation" **handoff**: documento estruturado escrito ao fim de uma sessão pra continuar contexto em outra. Não confundir com "resumo". _Avoid_: "summary", "transferência", "wrap-up doc" **flagged ambiguity**: termo ou comportamento ainda não definido que aparece >2x em conversas — candidato a virar entrada aqui. _Avoid_: "TODO", "open question" ## Decisions - Ver pasta /adrs para decisões arquiteturais. - Mudanças em Language exigem ADR se afetam código.
Required sections
- •Language — domain terms
- •Decisions — pointer to the ADRs
- •Header with the project name
Optional sections (use when useful)
- •Constraints — technical/regulatory constraints
- •Conventions — style, file names
- •Flagged Ambiguities — things to resolve
📐 The “term + Avoid” pattern
Each entry of Language has 2 parts: the positive definition and the list of synonyms to avoid. Why? Because without this, everyone (human and agent) reintroduces the synonym in 2 weeks.
O Avoid is what prevents entropy. It's the rule the agent cites when you write "refresh" in a PR and it responds, "did you mean materialization cascade?".
🏛️ ADRs (Architecture Decision Records)
One ADR is a short document that records a architectural decision: what was decided, in what context, and what the consequences are. Coined by Michael Nygard in 2011. The winning format is minimalist—4 sections, 1 page.
🧱 Canonical structure of an ADR
- 1. Status — proposed / accepted / deprecated / superseded by ADR-NNN
- 2. Context — what was the situation? What problem were we trying to solve?
- 3. Decision — what we decide to do (active voice, present tense).
- 4. Consequences — assumed trade-offs, what got worse, what got better.
Example: ADR-007 — Postgres instead of Mongo
# ADR-007: Usar Postgres em vez de Mongo para o catálogo de produtos ## Status Accepted — 2025-11-12 ## Context O catálogo cresceu pra ~2M de itens com relações fortes (SKU ↔ variantes ↔ preços regionais ↔ promoções). Mongo nos forçou a duplicar dados pra evitar joins manuais, e a materialization cascade ficou frágil. Precisamos de JOINs nativos, transações ACID e queries analíticas ad-hoc. ## Decision Migrar o catálogo para Postgres 16. Mantemos Mongo apenas para session blobs (efêmeros, schema-less). ## Consequences + JOINs e CTEs viáveis; analytics direto no DB. + materialization cascade vira VIEW materializada (uma única fonte da verdade). - Migração custa ~3 semanas + 1 freeze de 4h. - Time precisa subir nível em índices Postgres. - 2 bancos em produção (overhead operacional).
💡 Tip: An ADR is frozen, not edited
ADRs are immutable after they're accepted. Changed your mind? Create a new ADR with status "supersedes ADR-007". This preserves the history—in 6 months, when someone asks "why did we choose Postgres?", the original answer is still intact, along with the rationale for the change.
🔥 Real example: materialization cascade
How a team discovered a bug, gave the concept a name, and watched the name spread from CONTEXT.md to production code in 2 weeks. A real, anonymized story.
Day 0 — production bug
Symptom: final price fields became inconsistent after a regional tax change.
Each engineer described the bug with different words: “cascade,” “recalc bug,” “chain refresh issue.” No agent could help—the problem was invisible because it had no name.
Day 3 — baptism
Tech lead opens CONTEXT.md and writes the entry.
materialization cascade: sequential recalculation of derived fields after a root field mutation. Avoid: cascade, recalc, refresh.
From that point on, Claude Code starts using the term in its responses. Within 24h, 4 PRs already mention "materialization cascade" in the title.
Day 7 — renamed code
Refactor: refreshPrices() → runMaterializationCascade().
The function, class, module, Prometheus metric, and log event all started using the same name. Searching for "materialization cascade" in the repo began returning all the relevant places.
Day 14 — ADR + decision
ADR-007 is created: replace the imperative cascade with a materialized VIEW in Postgres.
With CONTEXT.md + ADR as context, the agent proposes the patch in a single conversation. No one has to explain the problem again. The term became a lever.
📊 Before/after metrics
- Before: ~14 days per fix iteration, 3 reverted PRs.
- After: 1 PR, merged in 36h, zero rollbacks.
- Tokens in prompts: ~70% drop in conversations about the pricing system.
🔄 Continuous maintenance
Ubiquitous language isn't a one-time act — it's a practice. Without maintenance, CONTEXT.md becomes a fossil in 3 months: outdated terms, definitions inconsistent with the code, synonyms coming back to life. The healthy cycle has 4 beats:
Each new feature → revisit CONTEXT.md
Before coding, ask: "Does this feature introduce a new term? Does an existing term change meaning?" If so, update it BEFORE coding.
Flagged ambiguities → revisit weekly
The "Flagged Ambiguities" section lists terms that appeared >2x without a clear definition. Once a week, someone promotes the most-used ones to formal entries.
Important decision → new ADR
Whenever a change alters trade-offs or supersedes an earlier decision, create an ADR. Mark the old one as "superseded by ADR-NNN" — never delete it.
The language evolves—you document the evolution
Retired term? Mark it “deprecated, replaced by X.” Refined term? Update the definition with a date. CONTEXT.md is also the project’s semantic history.
✓ Keep it alive
- ✓Update alongside each relevant PR
- ✓Review Flagged Ambiguities every Friday
- ✓Cite the term in commits ("fix: materialization cascade reorder")
- ✓Link ADRs in the PR description when applicable
✗ Let it rot
- ✗Create it and never open it again
- ✗Accept synonyms in PRs without challenging them
- ✗Editing old ADRs instead of creating new ones
- ✗Let Flagged Ambiguities grow indefinitely
📈 Measurable benefits
Ubiquitous language isn't aesthetics — it's an operational lever. The 4 benefits seen in teams that adopt CONTEXT.md + ADRs in practice:
🎯 The 4 concrete benefits
-
1.
Consistent names across the entire stack. Function, class, log, metric, dashboard, ticket, and PR all use the same word. Search = find.
-
2.
Code navigable by non-experts. A product manager reads the method’s name and understands the domain. Onboarding drops from weeks to days.
-
3.
Fewer tokens in thinking. The agent doesn’t need to “infer what you meant.” It reduces long prompts and eliminates clarification turns. In dense projects, consumption drops by 40-70%.
-
4.
Human-agent alignment. Claude Code and the engineer use the same vocabulary. A pull request becomes a dialogue on equal footing, not a translation.
🛠️ Practical exercise
Time to get started. The exercise has 3 steps and takes ~15 minutes. Do it NOW, before moving on to module 1.4.
🎯 Step by step
-
1.
Create the file
At the root of the current project (any project—it can be personal), create
CONTEXT.mdwith the Section 2 template. -
2.
Define 3 terms from your domain
Think of recent conversations where you had to explain the same thing more than once. Those are obvious candidates. For each term, write: definition (1 sentence) + Avoid (the synonyms you want to eliminate).
-
3.
Run
/grill-with-docsIn Claude Code, run the command with a plan or idea in mind. The grill will use your CONTEXT.md as a reference and challenge inconsistencies. Notice how often it mentions your terms.
💡 Tip: start small, improve weekly
Don't try to list 50 terms on the first day — that's a recipe for abandoning the file. Start with 3, use it for 1 week, add 2-3 new ones. In 1 month, you'll have a living, useful glossary instead of a dead document.
✅ Exercise checklist
- ☐CONTEXT.md created at the root
- ☐3 terms with definitions + Avoid
- ☐
/grill-with-docsrun at least once - ☐Did you notice a difference in the agent’s response?
📝 Summary + Next Steps
Next Module:
1.4 — Skills, sub-agents, and the Claude Code ecosystem