AI Skill
@open-domain-specification/skill is an installable agent skill that teaches an AI coding
agent (Claude Code, Codex, or anything that reads the Agent Skills layout) to author ODS
workspaces well. It is the successor of the copy-paste "LLM context" prompt this page used to
carry: instead of pointing a model at raw source files, it ships a SKILL.md and a set of
reference documents that are generated from the core package, so they can never drift from
the model the tooling implements.
What the skill does
- Detects how the workspace is authored. A project either keeps its model as JSON files
in a
.odsfolder, edited by the VS Code extension, or builds it with the TypeScript DSL and generates the JSON. The skill looks for a generator script first, falls back to the.odsfolder, and asks only when neither exists. In DSL mode it edits the source and re-runs the generator; in JSON mode it edits the files and validates them. - Interviews before it models. Most developers do not know DDD, and the skill does not expect them to. It plays the role of a facilitator: plain-language questions about the business areas, who owns which part, how the parts talk to each other, what the things inside one part are and what must never happen to them. Each answer is reflected back as the element it would record before anything is written.
- Translates. A translation table maps what people say ("we copy their data and reshape it", "when an order is placed we then reserve stock") onto ODS elements (an anti-corruption-layer consumption, an event, a policy and an operation).
- Teaches lightly. The first time a DDD term comes up, the skill explains it in one sentence tied to the user's own example, then moves on.
- Validates every change with the same
Workspace.validate()rules the extension and the core library apply, and explains each diagnostic in plain words with the fix it proposes. See Validation for the rules themselves.
Installing it
From VS Code, run ODS: Install AI Skill. Pick the agents to install for and whether the
skill goes into the project or your user folder. The command writes the bundle to:
| Agent | Folder |
|---|---|
| Claude Code | .claude/skills/ods-authoring/ |
| Agent Skills (Codex and others) | .agents/skills/ods-authoring/ |
| OpenAI Codex | .codex/skills/ods-authoring/ |
For agents that read a rules file instead, the command can append a short pointer paragraph to
AGENTS.md or .github/copilot-instructions.md. When a newer extension carries a newer skill
than the one installed in a project, it offers to update it once.
Without VS Code, copy the skill/ folder of the npm package into the same location:
npm pack @open-domain-specification/skill
tar -xzf open-domain-specification-skill-*.tgz
cp -r package/skill .claude/skills/ods-authoring
What is in the bundle
| File | Purpose |
|---|---|
SKILL.md | The always-loaded instructions: role, mode detection, the read, interview, translate, edit, validate loop, defaults and a do-not list. |
references/interview-playbook.md | The facilitator script, in seven phases from orientation to validation. |
references/translation-table.md | What people say, the ODS element, where it lives in JSON and the DSL call that creates it. |
references/ddd-glossary.md | One sentence per DDD term, phrased to be filled with the user's example. |
references/json-mode.md, references/dsl-mode.md | Mechanics of each authoring mode, including how to validate. |
references/dsl-api.md | The core DSL surface. |
references/model-reference.md | Generated from the JSON Schema: every element, field, type and requirement, plus the ref grammar. |
references/validation-rules.md | Generated from the core rule catalog: what each rule requires, why it matters and the usual fix. |
examples/ | A minimal workspace as JSON and as DSL, a validation script, and patterns excerpted from the Petstore example. |
The minimal workspace the skill starts from:
{
"$schema": "./schema.json",
"id": "bookshop",
"name": "Bookshop",
"description": "A small online bookshop: a catalogue of titles and the orders customers place for them.",
"version": "0.1.0",
"odsVersion": "2.0.0",
"domains": {
"bookselling": {
"name": "Bookselling",
"description": "Everything involved in selling books online",
"subdomains": {
"sales": {
"name": "Sales",
"type": "core",
"description": "Taking and fulfilling orders"
}
}
}
},
"boundedcontexts": {
"orders": {
"name": "Orders",
"description": "Owns orders from placement to dispatch",
"subdomains": [{ "$ref": "#/domains/bookselling/subdomains/sales" }],
"team": { "$ref": "#/teams/shop_team" },
"aggregates": {
"order": {
"name": "Order",
"description": "One customer's request to buy some books",
"entities": {
"order": {
"name": "Order",
"description": "The order itself",
"root": true,
"attributes": {
"order_number": {
"name": "orderNumber",
"type": "order number",
"identity": true
},
"total": { "name": "total", "type": "money" },
"ships_to": {
"name": "shipsTo",
"type": "Address",
"valueobject": {
"$ref": "#/boundedcontexts/orders/valueobjects/address"
}
}
}
}
},
"invariants": {
"total_not_negative": {
"name": "Total not negative",
"description": "An order's total can never be below zero",
"constrains": [
{
"$ref": "#/boundedcontexts/orders/aggregates/order/entities/order/attributes/total"
}
]
}
},
"provides": {
"order_placed": {
"name": "OrderPlaced",
"description": "A customer placed an order",
"type": "event",
"pattern": "published-language",
"schema": {
"$ref": "#/boundedcontexts/orders/schemas/order_placed"
}
}
},
"consumes": []
}
},
"services": {
"order_api": {
"name": "Order API",
"description": "The endpoints the web shop calls",
"type": "application",
"provides": {
"place_order": {
"name": "PlaceOrder",
"description": "POST /orders",
"type": "operation",
"pattern": "open-host-service",
"raises": [
{
"$ref": "#/boundedcontexts/orders/aggregates/order/provides/order_placed"
}
]
}
},
"consumes": []
}
},
"glossary": {
"order": {
"name": "Order",
"definition": "A customer's request to buy some books, paid up front",
"aliases": ["Purchase"],
"embodiedBy": { "$ref": "#/boundedcontexts/orders/aggregates/order" }
}
},
"valueobjects": {
"address": {
"name": "Address",
"description": "Where the order ships to",
"attributes": {
"lines": { "name": "lines", "type": "text" },
"postcode": { "name": "postcode", "type": "postcode" }
},
"invariants": {}
}
},
"schemas": {
"order_placed": {
"name": "OrderPlaced",
"description": "What other parts learn when an order is placed",
"attributes": {
"order_number": {
"name": "orderNumber",
"type": "order number",
"identity": true
},
"total": { "name": "total", "type": "money" }
}
}
}
}
},
"relationships": [],
"teams": {
"shop_team": {
"name": "Shop Team",
"description": "Runs the online shop"
}
}
}