Ubiquitous language
Domain words drift unless something stops them. This page answers where the agreed words are written down, how a word that means two things is handled, and how a glossary term becomes the name in code, tables and PRs.
Keep one glossary per context, with an avoid list
Section titled “Keep one glossary per context, with an avoid list”Impact: HIGH only the avoid list stops near-synonyms creeping in
- Each bounded context has a
GLOSSARY.md. Each entry is**Term**:with one sentence of meaning, then_Avoid_:with the synonyms that must not be used. - When user-facing and internal terms differ, they go under separate headings.
- Accepted cost: another document per context, kept by hand. No tool checks that code uses the terms, and agents sometimes ignore an avoid list; review is the guard.
❌ Incorrect — a definition with nothing to stop the next writer drifting:
- Rule: a labeling condition. Also called a filter or trigger.- Policy: the rules for a repo.✅ Correct — one sentence of meaning, then what to avoid:
## Language
**Labeling Rule**: A condition on a pull request that, when it holds, applies one label._Avoid_: Policy (a different model), filter, trigger
**Labeling Policy**: The set of Labeling Rules active for one repository, with its revision._Avoid_: Rule set, configSource: notes/03-naming-and-language/ubiquitous-language.md · Decision 1
List every cross-context collision in one map
Section titled “List every cross-context collision in one map”Impact: HIGH makes the dangerous words visible
- A root
GLOSSARY-MAP.mdlists the contexts and every word whose meaning differs between them. It is the only place a word may mean two things. - A second meaning that is not listed there is a bug in the glossary. A colliding word is never used bare: say which one you mean.
AGENTS.mdpoints agents atGLOSSARY-MAP.mdfirst.
❌ Incorrect — the same word in two contexts, collision unrecorded:
<!-- labeling glossary --> **Policy**: the rules for a repository.<!-- foundation glossary --> **Policy**: decides whether an actor may act.✅ Correct — the map names the collision, and neither side says just “policy”:
## Contexts- [Labeling](…/labeling/GLOSSARY.md): what labels a pull request gets, and why- [Foundation](…/foundation/GLOSSARY.md): identity, orgs, authorization
## Words that differ across contexts- **Policy** (Labeling) is a set of rules for a repository. An **authorization policy** (Foundation, `policy.ts`) decides whether an actor may act. Neither is called just "policy".Source: notes/03-naming-and-language/ubiquitous-language.md · Decision 1
Root code names in glossary terms
Section titled “Root code names in glossary terms”Impact: MEDIUM one word from the glossary to the database
- A glossary term is the root of the code name. It fills the unsuffixed service name from
naming and vocabulary: Labeling Rule →
LabelingRules,labeling_rules,LabelingRule. - The table prefix follows the owning context (see database migrations).
❌ Incorrect — an _Avoid_ synonym in code:
export class RuleFilters extends Context.Service<RuleFilters, RuleFiltersShape>()( "@app/labeling/RuleFilters",) {}// table: rule_triggers✅ Correct — the glossary term, in every place:
export class LabelingRules extends Context.Service<LabelingRules, LabelingRulesShape>()( "@app/labeling/LabelingRules",) {}// table: labeling_rules, type: LabelingRuleSource: notes/03-naming-and-language/ubiquitous-language.md · Decision 2
Use the terms in prose, and add missing ones in the same PR
Section titled “Use the terms in prose, and add missing ones in the same PR”Impact: MEDIUM vocabulary drift starts in prose, not code
- Agents and humans use the terms in issue titles, test names, identifiers, PR text and commit
messages. Drifting to an
_Avoid_synonym is a review comment. - A concept with no term is a signal. Either the word is invented, so reconsider it, or the glossary has a gap, so add the term in the same PR that introduces the concept.
❌ Incorrect — a new concept and a drifting synonym, glossary untouched:
feat(labeling): add trigger cooldownit("skips the filter when the config is stale", …)✅ Correct — glossary terms, and the new one added alongside:
feat(labeling): add Labeling Rule cooldown + GLOSSARY.md: **Cooldown**: … _Avoid_: throttleit("skips the Labeling Rule when the Labeling Policy revision is stale", …)Source: notes/03-naming-and-language/ubiquitous-language.md · Decision 2