Skip to content

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, config

Source: 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.md lists 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.md points agents at GLOSSARY-MAP.md first.

❌ 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

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: LabelingRule

Source: 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 cooldown
it("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_: throttle
it("skips the Labeling Rule when the Labeling Policy revision is stale", …)

Source: notes/03-naming-and-language/ubiquitous-language.md · Decision 2