---
name: domain-modeling
description: Use when defining or refining a project's domain model — pinning down domain terminology, building a ubiquitous language/glossary (CONTEXT.md), recording architectural decisions (ADRs), or when another skill needs to maintain or consult the domain model. 触发词：领域模型、术语、统一语言、glossary、CONTEXT.md、ADR、架构决策、architectural decision.
---

# Domain Modeling

Actively build and sharpen the project's domain model as you design. This is the *active* discipline — challenging terms, inventing edge-case scenarios, and writing the glossary and decisions down the moment they crystallise. (Merely *reading* `CONTEXT.md` for vocabulary is not this skill — that's a one-line habit any skill can do. This skill is for when you're changing the model, not just consuming it.)

## File structure

Most repos have a single context:

```
/
├── CONTEXT.md
├── docs/
│   └── adr/
│       ├── 0001-event-sourced-orders.md
│       └── 0002-postgres-for-write-model.md
└── src/
```

If a `CONTEXT-MAP.md` exists at the root, the repo has multiple contexts. The map points to where each one lives:

```
/
├── CONTEXT-MAP.md
├── docs/
│   └── adr/                          ← system-wide decisions
├── src/
│   ├── ordering/
│   │   ├── CONTEXT.md
│   │   └── docs/adr/                 ← context-specific decisions
│   └── billing/
│       ├── CONTEXT.md
│       └── docs/adr/
```

Create files lazily — only when you have something to write. If no `CONTEXT.md` exists, create one when the first term is resolved. If no `docs/adr/` exists, create it when the first ADR is needed.

## During the session

| Action | When it applies | What to do |
|--------|-----------------|------------|
| Challenge against the glossary | The user uses a term that conflicts with `CONTEXT.md` | Call it out immediately: "Your glossary defines 'cancellation' as X, but you seem to mean Y — which is it?" |
| Sharpen fuzzy language | The user uses vague or overloaded terms | Propose a precise canonical term: "You're saying 'account' — do you mean the Customer or the User?" |
| Discuss concrete scenarios | Domain relationships are being discussed | Stress-test with specific scenarios that probe edge cases and force precise boundaries between concepts. |
| Cross-reference with code | The user states how something works | Check whether the code agrees; surface any contradiction: "Your code cancels entire Orders, but you just said partial cancellation is possible — which is right?" |

### Update CONTEXT.md inline

When a term is resolved, update `CONTEXT.md` right there. Don't batch these up — capture them as they happen. Use the format in [CONTEXT-FORMAT.md](./CONTEXT-FORMAT.md).

### Offer ADRs sparingly

Only offer to create an ADR when all three are true:

1. **Hard to reverse** — the cost of changing your mind later is meaningful
2. **Surprising without context** — a future reader will wonder "why did they do it this way?"
3. **The result of a real trade-off** — there were genuine alternatives and you picked one for specific reasons

If any of the three is missing, skip the ADR. Use the format in [ADR-FORMAT.md](./ADR-FORMAT.md).

## Gotchas

| Gotcha | Reality |
|--------|---------|
| "I'll put implementation details in CONTEXT.md for now" | `CONTEXT.md` is a glossary and nothing else — never a spec, scratch pad, or repository for implementation decisions. |
| "This decision is interesting, let's record an ADR" | An ADR needs all three conditions (hard to reverse, surprising, real trade-off). Missing one? Skip it — you'll just reverse it or nobody will wonder. |
| "This term is used a lot, so it belongs in the glossary" | Only terms specific to this context belong. General programming concepts (timeouts, error types, utility patterns) don't — even if heavily used. |
| "I'll note the conflict and keep going" | Call out term conflicts immediately. Don't silently continue with an ambiguous or contradicted definition. |
