Completeness Checklist
The chant dev check-lexicon command evaluates a lexicon directory against three tiers of completeness. Run it from anywhere:
chant dev check-lexicon lexicons/my-lexiconPass --format json for machine-readable output.
Tier 1 — Required
Section titled “Tier 1 — Required”These must all pass for the command to exit 0. Run for real via just check-lexicons and gated in CI (chant #1067) — see chant dev check-lexicon for the exceptions currently tracked, not silently skipped.
| Check | What it verifies |
|---|---|
The package exports a LexiconPlugin | The module named by exports["."].default exports an object satisfying the plugin contract |
The plugin exposes a Serializer with a name and rule prefix | serializer.name, serializer.rulePrefix, and serializer.serialize |
lintRules() returns at least 1 rule | Asked of the plugin, not counted from src/lint/rules/ |
postSynthChecks() returns at least 1 check | Asked of the plugin, not counted from src/lint/post-synth/ |
Every rule id starts with a declared rule prefix | Ids must fall under serializer.rulePrefix or a declared extraRulePrefixes entry, so ids do not collide when lexicons load together (chant #1349) |
The plugin registers completionProvider | chant serve lsp dispatches through this member — a file in src/lsp/ that nothing registers is unreachable (chant #1342) |
The plugin registers hoverProvider | As above |
The plugin registers docs() | chant dev generate reaches the docs generator through the plugin, not through a package script |
dist/manifest.json exists | The lexicon bundle was built |
dist/manifest.json declares a chantVersion | Present and shaped like a version — see below |
package.json routes exports["."].default at ./src/index.ts and deletes emitted JS in build | The packaging shape every consumer depends on |
At least 1 example in examples/ | A non-empty subdirectory |
Every shipped example builds and passes its own post-synth checks | Discovers and serializes each examples/*/src/ rather than counting directories (chant #1067), then runs the lexicon’s own post-synth checks against the output and fails on any error-severity finding (chant #1400) |
Registered intrinsics are exported by the package | Every intrinsics() entry’s name resolves to a real export of src/index.ts (chant #1067) |
Registered intrinsics' isTag matches how they're authored | isTag: true requires a first parameter typed TemplateStringsArray; isTag: false requires anything else (chant #1067) |
Registered intrinsics' foldsAsCall opt-in is only on plain calls | The call-form opt-in cannot be declared on a tagged template, which has no call form to fold (chant #1044) |
MCP tools and resources register under one well-formed namespace | The name an agent sees is <lexicon>:<verb> / chant://<lexicon>/<path>, not a doubled or scheme-carrying variant (chant #1341) |
plugin.test.ts exists | Plugin unit test |
serializer.test.ts exists | Serializer unit test |
At least 1 .mdx doc page | Documentation exists |
Every doc page is reachable from the sidebar | Starlight has no auto-discovery, so a page missing from the sidebar is reachable only by direct URL (chant #1312) |
Every authored doc page has a diataxis quadrant | Pages under docs/pages/ name their Diátaxis quadrant; the sidebar is grouped from it (chant #1731) |
coverageReport() leaves no spec kind unaccounted | A plugin declaring coverageReport() must account for every upstream spec kind — modeled or on its exclusion list, computed offline from committed snapshots (chant #1330); lexicons without the member pass vacuously |
chantVersion
Section titled “chantVersion”chantVersion on the manifest is checked for presence and shape only — it is not validated for compatibility against the core version actually running. That would need a live check at plugin-load time (a different tool, e.g. loadPlugin/loadPlugins), and is a deliberate non-goal of chant #1067.
Tier 2 — Recommended
Section titled “Tier 2 — Recommended”Warnings — these make the lexicon useful in practice.
| Check | What it verifies |
|---|---|
The plugin registers mcpTools | MCP tool contributions active |
The plugin registers mcpResources | MCP resource contributions active |
The plugin registers skills | AI skills active |
The plugin registers detectTemplate | Template detection active |
The plugin registers initTemplates | Init templates active |
auditCatalog() covers every post-synth check | Metadata for chant audit — title, tier, fix kind, category. A lexicon that omits it contributes nothing, silently (chant #1346) |
Any declared ownership channel names paths the plugin implements | A declared marker channel must name read paths the plugin actually implements, with complete keys (chant #1348) |
Declares a configSchema if it reads its own config namespace | A lexicon reading config.<name> should declare its shape, or an unknown key there is silently ignored (chant #1344) |
At least 1 composite in src/composites/ | .ts files other than index.ts |
At least 3 examples | Broader usage coverage |
src/lsp/completions.test.ts exists | LSP completions tested |
src/lsp/hover.test.ts exists | LSP hover tested |
coverage.ts is implemented | No “not yet implemented” placeholder |
At least 8 doc pages | Comprehensive documentation — recommended topics: overview, getting-started, resources, intrinsics, pseudo-parameters, composites, lint-rules, importing |
At least 15 post-synth checks | Covering security, correctness, and best practices (see Post-Synth Check Guide) |
At least 3 skills | Core patterns, cloud/platform-specific, advanced patterns (see Skills Authoring Guide) |
At least 3 initTemplates | Default, domain-specific variant 1, domain-specific variant 2 |
Tier 3 — Thoroughness
Section titled “Tier 3 — Thoroughness”Informational — tracks depth of testing and feature coverage.
| Check | What it verifies |
|---|---|
Each lint rule has a .test.ts | Per-rule or consolidated coverage (e.g. rules.test.ts) |
Each post-synth check has a .test.ts | Per-check or consolidated coverage (e.g. post-synth.test.ts) |
typecheck.test.ts exists | Type-level verification |
roundtrip.test.ts exists | Serialize/deserialize round-trip |
At least 5 composites | Rich composition library |
src/actions/ with at least 1 action | Automation actions |
validate.ts checks at least 30 required names | Deep artifact validation across resources, property types, and bundle files |
Composite test file exists | composites.test.ts covering props, types, defaults, dependencies |
At least 5 examples with tests | Per-example or consolidated root test |
What the tool does not check
Section titled “What the tool does not check”The three tables above are the whole of chant dev check-lexicon, and a test
asserts that — a row here with no matching check, or a check with no row, fails
the build (chant #1343). Several things worth doing are consequently absent from
them, and were previously listed as though they were verified:
| Not checked | Where it lives instead |
|---|---|
exportResources() implemented | Implementing Live Export |
import/parser.test.ts, import/generator.test.ts, import/roundtrip.test.ts | Importing Templates |
default-labels.test.ts, coverage.test.ts | Testing Your Lexicon |
A capability counts as present when the plugin exposes it, not when a file
with the right name exists (chant #1342). The checks above load the lexicon and
ask it. That is what caught helm shipping src/lsp/completions.ts and
src/lsp/hover.ts — with tests — while registering neither provider, so its
LSP support was unreachable in an editor for as long as it has existed.
Recommended Post-Synth Check Categories
Section titled “Recommended Post-Synth Check Categories”When designing post-synth checks, aim for coverage across these categories:
| Category | Examples |
|---|---|
| Security | Encryption enabled, TLS version, HTTPS-only, access control, identity configuration |
| Correctness | Required fields present, valid values, correct dependencies |
| Best Practices | Naming conventions, tagging/labeling, resource configuration defaults |
| Deprecation | Outdated API versions, legacy features, deprecated properties |
See Testing Your Lexicon for patterns, mock helpers, and checklists for each test file.
Complete lexicon file tree
Section titled “Complete lexicon file tree”Use the AWS lexicon as reference for full coverage:
lexicons/my-lexicon/├── src/│ ├── plugin.ts # LexiconPlugin entry point│ ├── plugin.test.ts│ ├── serializer.ts # Build output serializer│ ├── serializer.test.ts│ ├── index.ts # Re-exports│ ├── coverage.ts # Coverage analysis│ ├── validate.ts # Artifact validation│ ├── validate-cli.ts│ ├── codegen/│ │ ├── generate.ts # Code generation pipeline│ │ ├── generate-cli.ts│ │ ├── naming.ts # Naming strategy│ │ ├── package.ts # Bundle packaging│ │ └── docs.ts # Docs generation│ ├── spec/│ │ ├── fetch.ts # Upstream schema fetching│ │ └── parse.ts # Schema parsing│ ├── lint/│ │ ├── rules/ # Lint rules + tests│ │ └── post-synth/ # Post-synthesis checks + tests│ ├── lsp/│ │ ├── completions.ts # LSP completions│ │ ├── completions.test.ts│ │ ├── hover.ts # LSP hover│ │ └── hover.test.ts│ ├── composites/ # Composite resources│ ├── actions/ # Automation actions│ ├── import/ # Template parser + generator│ └── generated/ # Generated artifacts (do not edit)├── dist/ # Built bundle├── examples/ # Usage examples with tests├── docs/ # Starlight docs site├── package.json├── tsconfig.json└── justfileSuggested implementation order
Section titled “Suggested implementation order”After scaffolding with chant init lexicon:
- Implement
src/spec/fetch.tsandsrc/spec/parse.ts - Implement
src/codegen/generate.tsandsrc/codegen/naming.ts - Run
just generateto produce types - Implement
src/serializer.ts - Write lint rules in
src/lint/rules/ - Add post-synth checks in
src/lint/post-synth/ - Implement LSP completions and hover
- Build examples
- Generate docs
Reference implementations
Section titled “Reference implementations”Counts below are what chant dev check-lexicon reports at chant 0.57.0, and
they move with every lexicon change, so run the tool rather than trusting the
table for anything that matters.
| Lexicon | Post-synth checks | Skills | Composites | Doc pages | Tier-3 required names |
|---|---|---|---|---|---|
| k8s | 40 | 10 | 50 | 37 | 30, passes |
| aws | 62 | 3 | 40 | 24 | 6, fails |
| azure | 24 | 4 | 19 | 25 | 25, fails |
k8s is the most complete of the three and the one to read first. aws has the
broadest resource surface and the only per-rule test layout. Its validate.ts
names six required artifacts (lexicons/aws/src/validate.ts), which is below
the tier-3 threshold of 30, and azure’s 25 is below it too. Both are
informational failures, not tier-1 ones.