Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Consuming a vocabulary across a package boundary

Area: Vocabulary & packages Teaches: a modeler package depends on a separate vocabulary package, imports its introducer metatypes/metarel, and uses them as its own declaration keywords — and the vocabulary’s catalog check fires on this package’s catalog at ox check. Prerequisites: the vocabulary author side — read that first. Run: ox build examples/vocab_consumer_v0 && ox check examples/vocab_consumer_v0

This is the consumer side. vocab_consumer_v0 owns no vocabulary of its own; it declares a path dependency on vocab_pkg_v0 and models its domain entirely with imported keywords. This is the property that makes vocabulary packages real: the modeler classifies with words it doesn’t own, and the introducer gate resolves them across the dependency boundary.

What to read

ox.toml declares the dependency. The key is the path root the consumer imports under, and it must equal the dependency’s package name:

[dependencies]
vocab_pkg_v0 = { path = "../vocab_pkg_v0" }

root.ar imports the vocabulary and declares with it. The introducer metatypes (category, kind) and the metarel (characterization) come from the dependency — this package never declares them:

use vocab_pkg_v0::{ category, kind, characterization };
use vocab_pkg_v0::{ Endurant, Substantial, Detached };

pub kind Person <: Substantial { name: String }
pub category Dwelling <: Endurant;
pub characterization Inhabits(p: Person, d: Dwelling);

Person is declared with the dependency’s kind keyword and specializes the dependency’s Substantial — well-formed.

One declaration deliberately trips the vocabulary’s check. Ghost is a kind that specializes Detached, which is exactly what vocab_pkg_v0’s shipped OrphanKind check warns about:

pub kind Ghost <: Detached;

Running it

ox check resolves the dependency, declares Ghost with the imported kind, and the imported OrphanKind check fires on it — a non-fatal warning that names the offending type and the check that fired:

$ ox check examples/vocab_consumer_v0
UFO::W001

  ⚠ UFO::W001: a `kind` specializes `Detached` — specialize `Substantial`
  │ instead [Ghost]
  help: fired by check `vocab_pkg_v0::OrphanKind`

ok

The decisive detail is fired by check \vocab_pkg_v0::OrphanKind`: the check the modeler is being held to was authored in a package it merely depends on. The build still completes — UFO::W001is aWarning`, not an error:

$ ox build examples/vocab_consumer_v0
workspace: elaborated 2 module(s) into one artifact
UFO::W001
  ⚠ UFO::W001: a `kind` specializes `Detached` — specialize `Substantial` instead [Ghost]
  help: fired by check `vocab_pkg_v0::OrphanKind`
wrote examples/vocab_consumer_v0/target/root.oxbin (13 events, 7182 bytes)

Honest caveats (what runs today)

  • UFO::W001 is a Warning, so ox check --codes prints ok (no error codes) even though the warning is emitted. Read the full ox check output (not --codes) to see the warning text.

This consumer and its vocabulary are driven through the real ox binary by a pipeline test (oxc-driver/tests/cli_pipeline.rs): the test pins that this package elaborates against the dependency and that the vocabulary-shipped OrphanKind check fires on Ghost, so the cross-package check can’t drift from the language.