Claude Code skill — Domain-Shared Lexicon: keep the AI's vocabulary aligned with yours. Per-project + per-domain global glossary with smart matching so off-domain projects stay clean.
SaferSkills independently audited dsl (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
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.
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.
The lexicon stores domain terms and what they mean. That is the whole scope.
If you find yourself writing how a feature works, you've drifted. Stop and put it elsewhere.
| 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.
/dsl-init, /dsl-update, /dsl-ingest commands)The user explicitly asks. Run the matching command's flow.
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:
LEXICON.md to keep us aligned? (or /dsl-update later)"Threshold for raising: real ambiguity or genuine unknown, not stylistic preference. Do not interrupt for terms that have one clear meaning in context.
When loaded via CLAUDE.md at the start of a session:
CLAUDE.md @import.Read tool to load it (do not rely on @import — see "Why no global @import" below). Parse each ## Domain: section's Applies 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.'Heat' has both global and project definitions — using the project one.Lexicon loaded: <N> terms (project: ./LEXICON.md, global: <matched-domain>). Omit any source that contributed zero. Skip the line entirely if nothing loaded.This project has domain-specific terminology — want to build a lexicon? Run /dsl-init. Do not offer again in the same session if declined.@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.
Each ## Domain: section in ~/.claude/LEXICON.md declares Applies when: signals. Evaluate them with this priority:
^\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.Applies when: list, OR project deps (package.json, pyproject.toml, Cargo.toml, go.mod, etc.) include declared domain libraries.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.
When invoked via /dsl-init or when the user accepts the proactive offer:
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.
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's README.md, any GLOSSARY.md/TERMS.md-style files, and directory nameshybrid — combine the aboveFor 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.
Ask one question at a time. Prefer AskUserQuestion with 2-4 concrete options + Other.
Cover only:
What does <Term> mean here, in one sentence?Are <A> and <B> the same thing, or different?When you say <X>, do you mean <interpretation A> or <interpretation B>?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:
10–15 terms is a normal first pass. Don't pad.
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.
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.
./CLAUDE.md already references ./LEXICON.md via @./LEXICON.md. If not, propose appending the snippet from templates/claude-md-snippet-project.md. If ./CLAUDE.md doesn't exist, propose creating one containing only that snippet.~/.claude/CLAUDE.md already contains the global lexicon block. If not, propose appending the snippet from templates/claude-md-snippet-global.md. If ~/.claude/CLAUDE.md doesn'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.
State, in one line: Wrote <path>: <N> terms in <M> domains. CLAUDE.md updated. Do not summarize the contents — the file is the artifact.
/dsl-update)When invoked because of a proactive ambiguity catch (mode 2 above), skip Step 2 and go straight to the specific term.
/dsl-ingest)X is a ..., we call this a ..., repeated capitalized terms, acronyms with expansions)array, function, endpoint) unless they have domain-specific meaning hereFor 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.
These rules apply when you write any lexicon file:
Aliases to avoid.**Customer**. This makes relationships obvious.## Flagged ambiguities with a clear recommendation.Applies when: signals don't match.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.