Skip to content
docs
Arxo ↗

Vocabulary contracts: kinds, keys, and templates

For LLMs4 sections

A vocabulary declaration is a promise to its consumers. This page covers the three ways authors sharpen that promise: relation kinds, keys, and predicate templates. All three are checked by tooling (S).

No commands are needed to follow this page. Each claim carries a status in words with a letter mark; the full legend is on the topic index.

Every relation may declare a kind — optional metadata saying where its rows come from (S). The vocabulary is closed: six values exist, and anything else is refused at compile time.

Intent — what each value promises:

  • empirical — rows observed in the world, submitted by the case.
  • institutional — rows constituted by records: holdings, recorded kinds, registrations. The lab fixtures mark the holding link and the recorded parcel kind this way.
  • evaluative — rows whose content is a judgment call: standards such as reasonable, good faith, or substantial.
  • derived — rows produced by rules.
  • normative_auxiliary — helper rows computed on the way to a normative conclusion.
  • external — rows owned by an outside system rather than by the case or the rules.

Mechanical checks — what tooling enforces, by name. The compiler rejects unknown kinds outright. The structural catalog adds two questions and three lints over the content channels.

The producers question lists the rules that feed a predicate. The readers question lists the rules, norms, and constraints that consume it.

ProblemLint that catches it
Evaluative content is submitted as a case fact, with no producer rule and no judgment channelevaluative-fact-without-producer
An evaluative standard is computed only from non-evaluative premisesevaluative-head-from-nonevaluative-body
A rule head is filled by an aggregate, but the relation declares no keyaggregate-head-without-key

Which configuration runs the lints: running them requires a source checkout (I). In the full checkout build, the audit command runs all sixteen catalog lints over a fresh snapshot as its form section. The public release also has law audit, but it ships no lint catalog, so its audit reports that section as not_run. See Sixteen shape checks on every audit and the audit surface.

Usage contract — what authors sign. Submit case facts only through empirical or institutional relations; give every derived relation a rule producer — a derived relation with no producer is a modeling gap; route evaluative content through a producer or the judgment channel, never as a bare case assertion; and when the kind is omitted, promise nothing — readers must inspect the producers and readers themselves before trusting the rows.

The judgment channel itself is a separate construct, not a kind: external judgment relation declares a decision input with a named authority, and it is that declaration — not any kind value — that carries decisions made by a named body (S).

A key(...) annotation names the parameters that functionally determine a relation’s remaining parameters (S). Keys matter most for aggregation: when a rule head is filled by an aggregate, the relation must declare the key the aggregate groups by, otherwise the submitted and recomputed values can both hold at once. A dedicated lint, aggregate-head-without-key, catches exactly that shape (S).

When two different values arrive for the same key, evaluation does not pick one silently: both stay true and the result reports KEY_CONFLICT (S). Treat a key conflict as a modeling signal — either the key is too narrow or the two producers disagree and a priority is missing.

Arxo Law
relation parcel_fee(parcel: Parcel, amount: Text) {
key(parcel);
}

Relations with labels can carry a template "…{param}…" that shows how to verbalize the predicate with its parameters filled in (S). The template is total: every parameter must appear at least once, and the compiler reports a template that names an unknown parameter or omits a known one. Answer rendering uses templates to turn derived rows back into readable sentences.

Templates live on relation labels only, and they follow the same multilingual status rules as labels themselves — see the companion page on languages for the status vocabulary.

Documentation for Arxo. Writings — blog.arxo.io.

Anonymous visit counts on stats.arxo.io, no cookies.