domain-modeling
Build and sharpen a project's domain model. Use when the user wants to pin down domain terminology or a ubiquitous language, record an architectural decision, or when another skill needs to maintain the domain model.
Install
npx skills add https://github.com/ConnorGriffin/skills/tree/main/skills/tools/domain-modeling
claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install connorgriffin-skills@llmmart
git clone https://github.com/ConnorGriffin/skills.git
The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole connorgriffin/skills collection as a plugin from our marketplace. Git is the plain clone.
Skill manifest
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.)
Two files, two different contents: sharpened glossary terms go to
CONTEXT.md; decisions that constrain architecture or behaviour go to the
repository's resolved ADR home. With active OpenSpec, that is the change's
design.md; otherwise follow references/ADR-FORMAT.md. Don't
conflate them — a term is not a decision, and a decision is not a definition.
File structure
Most repos have a single context (the docs/adr/ trees below illustrate a repo
with no existing decision record; resolve the ADR's home first, per
references/ADR-FORMAT.md):
/
├── CONTEXT.md
├── docs/
│ └── adr/
│ ├── adr-42-event-sourced-orders.md
│ └── adr-57-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. An ADR goes
wherever the repo already records decisions (references/ADR-FORMAT.md),
and a new docs/adr/ is created only when that resolves to docs/adr/.
During the session
Challenge against the glossary
When the user uses a term that conflicts with the existing language in
CONTEXT.md, call it out immediately. "Your glossary defines 'cancellation'
as X, but you seem to mean Y — which is it?"
Sharpen fuzzy language
When the user uses vague or overloaded terms, propose a precise canonical term. "You're saying 'account' — do you mean the Customer or the User? Those are different things."
Discuss concrete scenarios
When domain relationships are being discussed, stress-test them with specific scenarios. Invent scenarios that probe edge cases and force the user to be precise about the boundaries between concepts.
Cross-reference with code
When the user states how something works, check whether the code agrees. If you find a contradiction, surface it: "Your code cancels entire Orders, but you just said partial cancellation is possible — which is right?"
When the model touches module shape — interfaces, seams, adapters — use the
codebase-design skill's vocabulary rather than inventing your own terms for
architecture; keep CONTEXT.md itself limited to domain language (see
references/CONTEXT-FORMAT.md).
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
references/CONTEXT-FORMAT.md.
CONTEXT.md should be totally devoid of implementation details. Do not treat
CONTEXT.md as a spec, a scratch pad, or a repository for implementation
decisions. It is a glossary and nothing else.
Offer ADRs sparingly
Only offer to create an ADR when all three are true:
- Hard to reverse — the cost of changing your mind later is meaningful
- Surprising without context — a future reader will wonder "why did they do it this way?"
- 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 references/ADR-FORMAT.md.
Files (skills)
-
agents
-
openai.yaml 209 B
interface: display_name: "Domain Modeling" short_description: "Build and sharpen a project's domain model and terminology" default_prompt: "Use $domain-modeling to pin down this project's domain model."
-
-
references
-
ADR-FORMAT.md 3.8 KB
# ADR Format Resolve the ADR's home before anything else. A repository with active OpenSpec changes records a new decision in that change's `design.md` (no parallel `docs/adr/` tree, and the file-naming rule below does not apply there). Existing `docs/adr/` files are frozen legacy history while that workflow is active: retain their names and links, but do not add a record there. Without active OpenSpec changes, an established `docs/adr/` tree remains the decision home. Only a repository with no existing home gets one: `docs/adr/adr-<issue>-<slug>.md`, heading `# ADR <issue> — Title`, where `<issue>` is the id of the issue, ticket, or PR that originated the decision. Two records from one issue use distinct slugs, so one decision's file never overwrites another's. Create the `docs/adr/` directory lazily, only when the first ADR needs it. ## Template ```md # ADR <issue> — {Short title of the decision} {1-3 sentences: what's the context, what did we decide, and why.} ``` That's it. An ADR can be a single paragraph. The value is in recording *that* a decision was made and *why* — not in filling out sections. ## Optional sections Only include these when they add genuine value. Most ADRs won't need them. - **Status** frontmatter (`proposed | accepted | deprecated | superseded by ADR <issue>`) — useful when decisions are revisited - **Considered Options** — only when the rejected alternatives are worth remembering - **Consequences** — only when non-obvious downstream effects need to be called out ## Legacy numbering Some repos have earlier ADRs as sequential `0001-slug.md`, `0002-slug.md`, etc., with no issue id in the name. That format is legacy: keep those files and their links exactly as they are — never renumber or relink them — but never extend that numbering for a new ADR. Every new record uses the `adr-<issue>-<slug>.md` scheme above, even in a repo whose older ADRs are still numbered, once `docs/adr/` is the resolved home. ## When to offer an ADR All three of these must be true: 1. **Hard to reverse** — the cost of changing your mind later is meaningful 2. **Surprising without context** — a future reader will look at the code and wonder "why on earth 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 a decision is easy to reverse, skip it — you'll just reverse it. If it's not surprising, nobody will wonder why. If there was no real alternative, there's nothing to record beyond "we did the obvious thing." ### What qualifies - **Architectural shape.** "We're using a monorepo." "The write model is event-sourced, the read model is projected into Postgres." - **Integration patterns between contexts.** "Ordering and Billing communicate via domain events, not synchronous HTTP." - **Technology choices that carry lock-in.** Database, message bus, auth provider, deployment target. Not every library — just the ones that would take a quarter to swap out. - **Boundary and scope decisions.** "Customer data is owned by the Customer context; other contexts reference it by ID only." The explicit no-s are as valuable as the yes-s. - **Deliberate deviations from the obvious path.** "We're using manual SQL instead of an ORM because X." Anything where a reasonable reader would assume the opposite. These stop the next engineer from "fixing" something that was deliberate. - **Constraints not visible in the code.** "We can't use AWS because of compliance requirements." "Response times must be under 200ms because of the partner API contract." - **Rejected alternatives when the rejection is non-obvious.** If you considered GraphQL and picked REST for subtle reasons, record it — otherwise someone will suggest GraphQL again in six months. -
CONTEXT-FORMAT.md 2.4 KB
# CONTEXT.md Format ## Structure ```md # {Context Name} {One or two sentence description of what this context is and why it exists.} ## Language **Order**: {A one or two sentence description of the term} _Avoid_: Purchase, transaction **Invoice**: A request for payment sent to a customer after delivery. _Avoid_: Bill, payment request **Customer**: A person or organization that places orders. _Avoid_: Client, buyer, account ``` ## Rules - **Be opinionated.** When multiple words exist for the same concept, pick the best one and list the others under `_Avoid_`. - **Keep definitions tight.** One or two sentences max. Define what it IS, not what it does. - **Only include terms specific to this project's context.** General programming concepts (timeouts, error types, utility patterns) don't belong even if the project uses them extensively. Before adding a term, ask: is this a concept unique to this context, or a general programming concept? Only the former belongs. Module/interface/seam/adapter language belongs in the `codebase-design` vocabulary, not here. - **Group terms under subheadings** when natural clusters emerge. If all terms belong to a single cohesive area, a flat list is fine. ## Single vs multi-context repos **Single context (most repos):** One `CONTEXT.md` at the repo root. **Multiple contexts:** A `CONTEXT-MAP.md` at the repo root lists the contexts, where they live, and how they relate to each other: ```md # Context Map ## Contexts - Ordering (`./src/ordering/CONTEXT.md`) — receives and tracks customer orders - Billing (`./src/billing/CONTEXT.md`) — generates invoices and processes payments - Fulfillment (`./src/fulfillment/CONTEXT.md`) — manages warehouse picking and shipping ## Relationships - **Ordering → Fulfillment**: Ordering emits `OrderPlaced` events; Fulfillment consumes them to start picking - **Fulfillment → Billing**: Fulfillment emits `ShipmentDispatched` events; Billing consumes them to generate invoices - **Ordering ↔ Billing**: Shared types for `CustomerId` and `Money` ``` The skill infers which structure applies: - If `CONTEXT-MAP.md` exists, read it to find contexts - If only a root `CONTEXT.md` exists, single context - If neither exists, create a root `CONTEXT.md` lazily when the first term is resolved When multiple contexts exist, infer which one the current topic relates to. If unclear, ask.
-
-
SKILL.md 4.3 KB
--- name: domain-modeling description: Build and sharpen a project's domain model. Use when the user wants to pin down domain terminology or a ubiquitous language, record an architectural decision, or when another skill needs to maintain the domain model. --- # 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.) Two files, two different contents: sharpened glossary terms go to `CONTEXT.md`; decisions that constrain architecture or behaviour go to the repository's resolved ADR home. With active OpenSpec, that is the change's `design.md`; otherwise follow `references/ADR-FORMAT.md`. Don't conflate them — a term is not a decision, and a decision is not a definition. ## File structure Most repos have a single context (the `docs/adr/` trees below illustrate a repo with no existing decision record; resolve the ADR's home first, per [references/ADR-FORMAT.md](references/ADR-FORMAT.md)): ``` / ├── CONTEXT.md ├── docs/ │ └── adr/ │ ├── adr-42-event-sourced-orders.md │ └── adr-57-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. An ADR goes wherever the repo already records decisions ([references/ADR-FORMAT.md](references/ADR-FORMAT.md)), and a new `docs/adr/` is created only when that resolves to `docs/adr/`. ## During the session ### Challenge against the glossary When the user uses a term that conflicts with the existing language in `CONTEXT.md`, call it out immediately. "Your glossary defines 'cancellation' as X, but you seem to mean Y — which is it?" ### Sharpen fuzzy language When the user uses vague or overloaded terms, propose a precise canonical term. "You're saying 'account' — do you mean the Customer or the User? Those are different things." ### Discuss concrete scenarios When domain relationships are being discussed, stress-test them with specific scenarios. Invent scenarios that probe edge cases and force the user to be precise about the boundaries between concepts. ### Cross-reference with code When the user states how something works, check whether the code agrees. If you find a contradiction, surface it: "Your code cancels entire Orders, but you just said partial cancellation is possible — which is right?" When the model touches module shape — interfaces, seams, adapters — use the `codebase-design` skill's vocabulary rather than inventing your own terms for architecture; keep `CONTEXT.md` itself limited to domain language (see [references/CONTEXT-FORMAT.md](references/CONTEXT-FORMAT.md)). ### 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 [references/CONTEXT-FORMAT.md](references/CONTEXT-FORMAT.md). `CONTEXT.md` should be totally devoid of implementation details. Do not treat `CONTEXT.md` as a spec, a scratch pad, or a repository for implementation decisions. It is a glossary and nothing else. ### 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 [references/ADR-FORMAT.md](references/ADR-FORMAT.md).
Comments (0)
Sign in to join the conversation.
Reviews (0)
No reviews yet.
No comments yet.