A metarel with metatype-constrained endpoints
Area: Vocabulary & packages Teaches: an introducer
metarelcan constrain the metatype of each endpoint position, and that constraint travels with the published metarel — a consumer’s relation endpoints are verified against it across the package boundary. Prerequisites: publishing a vocabulary (introducer metatypes and metarels). Run:ox build examples/metarel_vocab_v0 && ox check examples/metarel_vocab_v0
A relation is not just a tuple of types — in a vocabulary it often carries an ontological constraint on what kind of thing may sit in each slot. UFO’s characterization relates a bearer to an aspect: the bearer must be a substantial kind, the second slot must be an aspect. metarel_vocab_v0 publishes exactly that shape, so a separate consumer that fills a slot with the wrong sort of thing is refused at its own ox check. (The refusal itself is the companion fixture, metarel_consumer_bad_v0.)
What to read in root.ar
An axis, then two introducer metatypes positioned on it. The axis names are pure user vocabulary — the compiler reads the lattice, never the meaning of the words:
pub metaxis sortality for metatype { sortal, non_sortal };
pub metatype kind = { sortality::sortal };
pub metatype aspect = { sortality::non_sortal };
A metarel whose endpoints are metatype-constrained. Position 0 (bearer) must be kind-sorted; position 1 (aspect_of) must be aspect-sorted. These position metatypes are part of the published metarel:
pub metarel characterization(bearer: kind, aspect_of: aspect);
When a consumer in another package declares a characterization relation, the endpoint metatypes of its relation are checked against these positions. An endpoint must be (a sub-metatype of) the position’s metatype, or ox check refuses it across the dependency boundary — the same refusal an in-package violation gets.
Running it
The vocabulary checks clean — it only publishes the constrained metarel, it doesn’t use it:
$ ox build examples/metarel_vocab_v0
wrote examples/metarel_vocab_v0/target/root.oxbin (4 events, 2393 bytes)
$ ox check examples/metarel_vocab_v0 --codes
ok
To see the constraint bite, point a consumer at this package and have it fill aspect_of with a kind — that is examples/metarel_consumer_bad_v0, which is refused OE0631.
Honest caveats (what runs today)
- This package declares no individuals and no
pub query; it is pure vocabulary. The endpoint constraint is enforced statically, at a consumer’sox check, not at runtime.
This vocabulary and its (deliberately failing) consumer are driven through the real ox binary by a pipeline test (oxc-driver/tests/cli_pipeline.rs): the test pins that this package checks clean and that a wrong-sorted endpoint in the consumer is refused OE0631, so the cross-package endpoint check can’t drift from the language.