--- name: domain-modeling description: Use when a term is fuzzy, overloaded, or contradicts how the code behaves; when writing or editing a CONTEXT.md glossary; or when a hard-to-reverse decision needs recording as an ADR. --- # Domain Modeling Actively build and sharpen a project's domain model as you design: challenge terms, stress-test them with scenarios, and write the glossary and the decisions down the moment they crystallise. This is the *active* discipline. Merely **reading** `CONTEXT.md` for vocabulary is a one-line habit any skill can do and is not this skill. Reach for this one when you are **changing** the model, not 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/ ``` A `CONTEXT-MAP.md` at the root means the repo has several contexts, and 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 once there is something to write. No `CONTEXT.md` yet? Create it when the first term is resolved. No `docs/adr/`? Create it when the first ADR is needed. ## During the session ### Challenge against the glossary When a term conflicts with the language already in `CONTEXT.md`, call it out immediately. > "Your glossary defines *cancellation* as X, but you seem to mean Y here. Which is it?" ### Sharpen fuzzy language When a term is vague or overloaded, propose a precise canonical one. > "You're saying *account*: do you mean the Customer or the User? Those are different things." ### Discuss concrete scenarios When domain relationships are on the table, stress-test them with specific scenarios. Invent the edge cases that force the boundaries between concepts to become precise. ### Cross-reference with the code When a claim is made about how something works, check whether the code agrees, and surface any contradiction. > "The code cancels whole Orders, but you just said partial cancellation is possible. Which is right?" The schema is the highest-signal place to check, because it is where the domain nouns are declared rather than merely used. In a Convex project that is `convex/schema.ts`; elsewhere it is whatever file defines the tables or types. A term that appears in conversation but nowhere in the schema is either missing from the model or is not really a domain term. ### Update CONTEXT.md inline When a term resolves, write it to `CONTEXT.md` right then. Do not batch them: capture each as it happens, because the precision is what fades between now and the end of the session. Use the format in [CONTEXT-FORMAT.md](CONTEXT-FORMAT.md). `CONTEXT.md` is a glossary and nothing else. Keep implementation details, specs, and scratch notes out of it. ### Offer ADRs sparingly Offer an ADR only 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 on earth did they do it this way?" 3. **The result of a real trade-off**: genuine alternatives existed and one was picked for specific reasons. Missing any one of the three, skip it. Use the format in [ADR-FORMAT.md](ADR-FORMAT.md). ## Done when - Every term resolved this session is in `CONTEXT.md`, in the house format, with its rejected synonyms under `_Avoid_`. - No implementation detail has leaked into `CONTEXT.md`. - Every contradiction found between a stated claim and the code was surfaced, not silently resolved. - An ADR exists for each decision meeting all three tests, and for none that miss one.