Skip to main content

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 .ods folder, 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 .ods folder, 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:

AgentFolder
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

FilePurpose
SKILL.mdThe always-loaded instructions: role, mode detection, the read, interview, translate, edit, validate loop, defaults and a do-not list.
references/interview-playbook.mdThe facilitator script, in seven phases from orientation to validation.
references/translation-table.mdWhat people say, the ODS element, where it lives in JSON and the DSL call that creates it.
references/ddd-glossary.mdOne sentence per DDD term, phrased to be filled with the user's example.
references/json-mode.md, references/dsl-mode.mdMechanics of each authoring mode, including how to validate.
references/dsl-api.mdThe core DSL surface.
references/model-reference.mdGenerated from the JSON Schema: every element, field, type and requirement, plus the ref grammar.
references/validation-rules.mdGenerated 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"
}
}
}