# Glossary Slash Commands & Extension Pattern (migration 0019) Three Claude Code slash commands that surface the Ontoref glossary in any session opened inside an onboarded project, plus the canonical pattern for extending the glossary with project- or domain-specific terms. ## Layout ```text glossary/ ontoterm.md ← /ontoterm — query a term ontoterm-propose.md ← /ontoterm-propose — draft a new term (verified=false) ontoterm-update.md ← /ontoterm-update — edit an existing term README.md ← this file ``` ## Install Migration 0019 copies these into `/.claude/commands/`: ```sh cp $ONTOREF_ROOT/install/resources/templates/glossary/ontoterm.md .claude/commands/ cp $ONTOREF_ROOT/install/resources/templates/glossary/ontoterm-propose.md .claude/commands/ cp $ONTOREF_ROOT/install/resources/templates/glossary/ontoterm-update.md .claude/commands/ ``` Each command runs `./ontoref describe term ` under the hood, so the project must have ontoref installed and the `./ontoref` bash wrapper present. ## What gets resolved - **Protocol seed** (from `reflection/defaults/glossary.ncl`, shipped with ontoref): `ondaod`, `espiral`, `colapso-yin-yang`, `sintesis`, `gate`, `on-re`, `ore`, `pap`, `anti-pap`, `adr-question`, `dag-knowledge`, `glossary-extension-pattern`. - **Project-specific terms** appended to `.ontology/glossary.ncl::project_terms` in each consumer project. ## Bilingual The CLI accepts `--lang en|es`. Slash command default is EN (project rule); override by passing `--lang es` as argument. --- ## Extension pattern — three levels Vocabulary lives in three layers. Every project gets the first two automatically; the third is opt-in for projects with formal sub-domains. ```text ┌──────────────────────────────────────────────────────────────────┐ │ Level 0 — PROTOCOL │ │ /reflection/defaults/glossary.ncl │ │ Shared across the whole ecosystem. NEVER edit locally. │ └──────────────────────────────────────────────────────────────────┘ ▲ import ┌──────────────────────────────────────────────────────────────────┐ │ Level 1 — PROJECT │ │ /.ontology/glossary.ncl │ │ Project-specific jargon, drafted via /ontoterm-propose. │ └──────────────────────────────────────────────────────────────────┘ ▲ optional split ┌──────────────────────────────────────────────────────────────────┐ │ Level 2 — DOMAIN (optional, ~30+ terms) │ │ /.ontology/glossary/.ncl │ │ Only when the project has formal sub-domains. │ └──────────────────────────────────────────────────────────────────┘ ``` Query with `ore describe term glossary-extension-pattern` for the in-CLI authoritative reference. ### Rules | Rule | Why | |---|---| | **Never edit the protocol seed locally** | It lives in the installed ontoref package and is overwritten on every `just install-daemon`. Improvements go upstream as PRs. | | **Never redefine a protocol id locally** | The `glossary-drift` pre-commit hook catches duplicate ids and fails the commit. Pick a different id (e.g. `provisioning-discipline`) and link via `related_terms`. | | **Use `related_terms` to weave levels** | A local term linked to a protocol term documents how the local concept sits within the shared vocabulary — that's `ondaod` applied to the glossary itself. | | **Don't promote prematurely** | Terms only ascend to the protocol seed when ecosystem-wide. Otherwise they pollute consumers that don't need them. | ### Forbidden - Editing `reflection/defaults/glossary.ncl` in a consumer project - Redefining `ondaod`, `espiral`, etc. locally with a different meaning - Copying the protocol seed into the project instead of importing it - Splitting into `.ontology/glossary/.ncl` files for a project with <30 terms --- ## Worked example — `provisioning` project A project that owns its own domain ("provisioning") with concepts that emerged during ADR review: `lifecycle-plane`, `data-plane`, and the antipattern of `pole-flip` (a synonym for `colapso-yin-yang` in the provisioning idiom). ```nickel # provisioning/.ontology/glossary.ncl let d = import "reflection/defaults/glossary.ncl" in # ← inherit protocol seed let s = import "reflection/schemas/term.ncl" in let project_terms = [ d.make_term { id = "lifecycle-plane", name = { en = "Lifecycle plane", es = "Plano de ciclo de vida" }, category = 'Concept, definition = { en = m%" Centralized control surface where bring-up, tear-down and state transitions happen. Intentionally Yang-pole: one source of truth for what should run where and in what order. "%, es = m%" Superficie de control centralizada donde ocurren arranque, parada y transiciones de estado. Deliberadamente polo Yang: una sola fuente de verdad de qué debe ejecutarse, dónde y en qué orden. "%, }, origin = { kind = 'Adr, ref = "adr-NNN-provisioning-planes" }, related_terms = ["data-plane", "espiral", "sintesis"], # ← link to protocol terms }, d.make_term { id = "data-plane", name = { en = "Data plane", es = "Plano de datos" }, category = 'Concept, definition = { en = m%" Distributed surface where traffic flows once provisioning has completed. Intentionally Yin-pole: scripted, local, without a central coordinator on the request path. "%, es = m%" Superficie distribuida donde fluye el tráfico una vez completado el aprovisionamiento. Deliberadamente polo Yin: scripted, local, sin coordinador central en el camino de petición. "%, }, origin = { kind = 'Adr, ref = "adr-NNN-provisioning-planes" }, related_terms = ["lifecycle-plane", "colapso-yin-yang", "sintesis"], }, d.make_term { id = "pole-flip", name = { en = "Pole flip", es = "Flip de polo" }, aliases = ["yang-yin-flip", "yin-yang-flip"], category = 'Antipattern, definition = { en = m%" Within a Spiral tension, swinging from one pole to the opposite in a single decision instead of pursuing synthesis. In provisioning, the canonical example was the first draft proposing full systemd when the previous design was full Kubernetes. "%, es = m%" En una tensión en Espiral, oscilar de un polo al opuesto en una sola decisión en lugar de buscar síntesis. En provisioning, el ejemplo canónico fue el primer borrador proponiendo full systemd cuando el diseño previo era full Kubernetes. "%, }, origin = { kind = 'External, ref = "" }, related_terms = ["colapso-yin-yang", "espiral", "sintesis", "ondaod"], forbidden = { en = ["Treating a pole-flip as 'finally getting clarity'"], es = ["Tratar un pole-flip como 'al fin tener claridad'"], }, verified = false, # ← project-fresh draft until reviewed }, ] in { terms = d.seed_terms @ project_terms, } | s.Glossary ``` After this: ```sh ore describe term lifecycle-plane # resolves locally ore describe term pole-flip --lang es # also local ore describe term ondaod # still resolves to protocol seed ore describe term --list # shows all 12 protocol + 3 project terms ore sync diff --glossary --fail-on-drift # validates refs across levels ``` ### When to promote to domain split (level 2) Only when the project crosses ~30 terms AND has formal sub-domains declared in its manifest (per ADR-018 levels). Until then, sectioned comments inside a single `.ontology/glossary.ncl` are more readable than multi-file fragmentation.