Dictionary ids are kebab-case, and id equals filename
Every corpus id — terms, entities, rules, proposals — is a stable lower
kebab-case slug: lowercase words joined by hyphens. The id is the
filename (sans extension) and the URL path segment, so the three can never
drift apart; the loader enforces the id/filename match at build time.
Rule ids prefix the slug with their number (R-005-ids-kebab-case) so
terms can cite them and the rulebook sorts naturally.
Evidence
This repo: scripts/lib/load.js rejects any YAML or rule file whose id does not match its filename ("id … must match filename"); every id in terms/, entities/, and conventions/ is a lower kebab-case slug (current-loan-balance, scenario-card, R-001-field-names-snake-case); scripts/lib/render.js builds every page URL directly from the id (/terms/<id>/, /rulebook/<id>/); the design spec (docs/ 2026-07-16-data-dictionary-design.md) defines id as the "stable kebab-case slug → the URL."