Dsl
Skill p-vbordei/dsl/skills/dsl
Build and maintain a Domain-Shared Lexicon — a glossary of domain terms that you and the AI agree on. Use when the user says "build a lexicon", "we keep using term X differently", "set up a glossary", "what does Y mean in this project", or whenever you notice the same word being used for two different concepts in conversation. Also activates at session start when a lexicon file is present.From its SKILL.md
npx -y skills add p-vbordei/dsl --skill dslAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
13.3 KB, ~3.2k tokens by cl100k_base, as published. Nobody here has run it
DSL — Domain-Shared Lexicon
A focused skill with one job: align the vocabulary between you (the AI) and the user for the domain they work in. Nothing else. Not plan reviews, not ADRs, not design decisions — only the words and what they mean.
Why this exists
When the user says "the order is rejected" they may mean a specific lifecycle state with downstream effects. When you (the AI) hear "order" you may default to a generic e-commerce meaning. Drift compounds: code uses one name, comments another, the user a third, and you a fourth. The lexicon collapses all of that into a single source of truth that everyone — including future-you in a fresh session — references.
Scope (read this twice)
The lexicon stores domain terms and what they mean. That is the whole scope.
- ✅ Term → definition → aliases to avoid
- ✅ Relationships between terms ("an Invoice belongs to one Customer")
- ✅ Flagged ambiguities (same word used for two things)
- ❌ Not architecture decisions (those go in ADRs)
- ❌ Not design plans, PRDs, or feature specs
- ❌ Not coding conventions or style rules
- ❌ Not "how to use this codebase"
If you find yourself writing how a feature works, you've drifted. Stop and put it elsewhere.
Where lexicons live
| Scope | Path | Applies to |
|---|---|---|
| Project | ./LEXICON.md | This project only |
| Global | ~/.claude/LEXICON.md | The user's recurring domains across all their projects |
The global file is not one big bag — it is a collection of per-domain sections, each with explicit Applies when: signals. At session start, you match the current project against those signals and load only matching domains. A user whose primary work is metal smelting should not get smelting vocabulary auto-loaded into a recipe app side project.
See templates/lexicon-template.md for the canonical structure.
Three ways this skill runs
1. On demand (the /dsl-init, /dsl-update, /dsl-ingest commands)
The user explicitly asks. Run the matching command's flow.
2. Proactive mid-conversation
You're working on something else and notice a term being used in two senses in the same conversation, or a domain term the user uses confidently that you cannot define. When this happens:
- Don't derail. Finish the user's current ask first if it's mid-flight.
- At a natural pause, raise the ambiguity in one short sentence: "Quick check — 'account' has come up meaning both the paying customer and a login identity. Worth adding to
LEXICON.mdto keep us aligned? (or/dsl-updatelater)" - If the user says yes, run the update flow on just that term. If no or silence, drop it — do not nag.
Threshold for raising: real ambiguity or genuine unknown, not stylistic preference. Do not interrupt for terms that have one clear meaning in context.
3. At session start (auto-detection)
When loaded via CLAUDE.md at the start of a session:
- If
./LEXICON.mdexists, treat it as in scope unconditionally. It is loaded via the projectCLAUDE.md@import. - If
~/.claude/LEXICON.mdexists, use theReadtool to load it (do not rely on@import— see "Why no global@import" below). Parse each## Domain:section'sApplies when:block and evaluate against the current project (see "Matching the project to a global domain"). Mentally apply only matching sections. Ignore the rest as if they weren't there. - When precedence collides (a term defined in both project and a matching global domain), the project definition wins. Note the divergence to the user once:
'Heat' has both global and project definitions — using the project one. - Acknowledgement — in your first substantive response, emit exactly one line of the form
Lexicon loaded: <N> terms (project: ./LEXICON.md, global: <matched-domain>).Omit any source that contributed zero. Skip the line entirely if nothing loaded. - If neither matches and the project shows clear domain-specific signals (specialized jargon in README, narrow industry deps), make a one-time, one-line offer in your first substantive response:
This project has domain-specific terminology — want to build a lexicon? Run /dsl-init.Do not offer again in the same session if declined. - If the project is generic / off-domain (todo apps, recipe apps, generic CRUD with no specialized vocabulary, AND no global domain matches), say nothing. Silence is the right behaviour here.
Why no global @import
@~/.claude/LEXICON.md in ~/.claude/CLAUDE.md would load the entire global lexicon into context every session, including off-domain vocabulary. That defeats the matching guarantee — a metallurgist's smelting terms would still enter context when they open a recipe app. Instead, the global CLAUDE.md snippet asks you to Read the lexicon at session start and filter by Applies when: yourself. Off-domain terms never enter context.
Matching the project to a global domain
Each ## Domain: section in ~/.claude/LEXICON.md declares Applies when: signals. Evaluate them with this priority:
- Explicit override — if a line matching the regex
^\s*domain:\s*<name>\s*$appears in the project's./CLAUDE.md, or as the first non-blank, non-heading line of./LEXICON.md, use that. Skip detection. - Strong signal — README mentions 2+ named keywords from the domain's
Applies when:list, OR project deps (package.json,pyproject.toml,Cargo.toml,go.mod, etc.) include declared domain libraries. - Weak signal — file/dir names match declared patterns, OR domain-specific file extensions are present.
Load a global domain only when strong signal OR explicit override matches. Weak signals alone are not enough — they cause false positives across unrelated projects.
When in doubt, prefer not loading over polluting context with off-domain vocabulary. The user can always invoke /dsl-init to force-attach a global domain to the current project.
Building the lexicon (the interview flow)
When invoked via /dsl-init or when the user accepts the proactive offer:
Step 0 — Pick the scope
Ask once: Is this lexicon for this project only, or part of your recurring domain across projects? (Options: project / global-new-domain / global-add-to-existing.) Use AskUserQuestion if available.
Step 1 — Gather raw material
Ask once: How should we extract terms? Options:
interview— I ask you questionsingest— you point me at a file, URL, or paste (docs, transcripts, existing glossaries, code)scan— I scan this repo'sREADME.md, anyGLOSSARY.md/TERMS.md-style files, and directory nameshybrid— combine the above
For ingest: ask for the source. Read it. Extract candidate terms.
For scan: read the project's README.md and any file with a glossary-shaped name at the project root or one level deep (GLOSSARY.md, TERMS.md, LEXICON.md, DICTIONARY.md). Also use the directory tree (names only, not file contents) as a hint for domain. Extract candidates. Do not read docs/, CONTRIBUTING.md, ADRs, design docs, or source code — those describe how the system works, which is out of scope. If the user wants terms extracted from a design doc, they should ingest it explicitly so they're aware that's a deliberate widening of scope.
Step 2 — Interview the user
Ask one question at a time. Prefer AskUserQuestion with 2-4 concrete options + Other.
Cover only:
- For each candidate term:
What does <Term> mean here, in one sentence? - For each apparent synonym pair:
Are <A> and <B> the same thing, or different? - For each ambiguous term:
When you say <X>, do you mean <interpretation A> or <interpretation B>? - For each known industry term the user uses confidently but you don't know:
Quick — what is a <Term> in your domain?
You are an interviewer, not an executor. Do not start coding, refactoring, or restructuring anything as a side effect. The deliverable is the lexicon, full stop.
Stop when:
- All ambiguities are resolved
- All candidate terms have one-sentence definitions
- The user says "enough" / "wrap up"
10–15 terms is a normal first pass. Don't pad.
Step 3 — Write the file
Before writing, always show the proposed lexicon contents to the user and confirm. Never write a LEXICON.md silently.
Write ./LEXICON.md (or update ~/.claude/LEXICON.md for global). Follow templates/lexicon-template.md exactly. Group terms into tables by natural cluster (lifecycle / actors / artifacts). Include the Flagged ambiguities and Example dialogue sections.
For a new global domain, populate the Applies when: block carefully — these signals decide future auto-loading. Be specific: deps, README keywords, file patterns. Vague signals cause false positives.
Empty-lexicon guard: if the interview / ingest / scan yielded fewer than 2 terms (or no real ambiguities), do not write a file. Tell the user: Not enough domain-specific terms for a lexicon — skipping. Run /dsl-init again when you have more material.
Step 4 — Wire it up
Check the relevant CLAUDE.md. Always confirm with the user before writing or modifying their CLAUDE.md. Never write a CLAUDE.md file without first showing the user the snippet you intend to append.
- Project: check if
./CLAUDE.mdalready references./LEXICON.mdvia@./LEXICON.md. If not, propose appending the snippet fromtemplates/claude-md-snippet-project.md. If./CLAUDE.mddoesn't exist, propose creating one containing only that snippet. - Global: check if
~/.claude/CLAUDE.mdalready contains the global lexicon block. If not, propose appending the snippet fromtemplates/claude-md-snippet-global.md. If~/.claude/CLAUDE.mddoesn't exist, propose creating one containing only that snippet.
Project lexicon loading: the project snippet uses @./LEXICON.md, so the whole file enters context every session — that's the intended behaviour (project lexicons always apply). If the project lexicon is large enough to be a context concern (say, over 500 lines), tell the user; consider splitting by sub-domain into separate files referenced from ./LEXICON.md.
Global lexicon loading: the global snippet does not use @import — it instructs you to Read and filter at session start. This keeps off-domain vocabulary out of context.
Step 5 — Confirm
State, in one line: Wrote <path>: <N> terms in <M> domains. CLAUDE.md updated. Do not summarize the contents — the file is the artifact.
Updating an existing lexicon (/dsl-update)
- Read the existing file
- Ask the user what to add / fix / disambiguate
- Run a tight interview only on those terms
- Rewrite the file in full (no diff markers in the file itself — git handles history)
- Confirm
When invoked because of a proactive ambiguity catch (mode 2 above), skip Step 2 and go straight to the specific term.
Ingesting external material (/dsl-ingest)
- Accept: file path, URL, or pasted text
- Read it
- Extract domain-relevant noun phrases (
X is a ...,we call this a ..., repeated capitalized terms, acronyms with expansions) - Skip generic programming concepts (
array,function,endpoint) unless they have domain-specific meaning here - Present candidates in a short list with proposed definitions drawn from the source
- Let the user accept / edit / reject each
- Continue to Step 3 of the interview flow (write the file)
For URLs, prefer WebFetch. For PDFs and Office files, ask the user to convert or paste the relevant section — do not assume a converter is installed.
Rules of the format
These rules apply when you write any lexicon file:
- Be opinionated. When multiple words exist for the same concept, pick one and list the others under
Aliases to avoid. - Tight definitions. One sentence. Define what something is, not what it does.
- Bold term references. When a definition mentions another term in the lexicon, bold it:
**Customer**. This makes relationships obvious. - Group when natural, single table when not. Don't force subgroups onto a 5-term lexicon.
- Only domain terms. Skip framework/language jargon unless it has domain-specific meaning here.
- Flag ambiguities explicitly. If the source material used a term in two senses, surface it in
## Flagged ambiguitieswith a clear recommendation. - One example dialogue. A 3–5 line exchange that shows the terms used precisely in context.
What you must not do
- Do not generate ADRs, design docs, PRDs, or feature specs as part of this skill.
- Do not refactor code or rename identifiers as a side effect of building a lexicon. Note the divergence, surface it to the user, and stop.
- Do not auto-load a global domain whose
Applies when:signals don't match. - Do not pad the lexicon with terms just to look thorough. If a term has no real ambiguity and no special domain meaning, leave it out.
- Do not interrupt the user's current task to volunteer a lexicon update. Wait for a natural pause.
What ships with it: 1 file
12.0 KB alongside SKILL.md, 1 of them executable
- lexicon-lint.pyruns12.0 KB