Ontologies: the unit a project starts from
manifest.jsonname, release, domain, what it extends and carriesontology.config.jsonthe vocabulary; ontology_version rises on a breaking changeontology.rationale.jsonthe question each class answers, and who confirmed itrules.json · actions/what is derived and forbidden; what can be donesample.graph.json · guide.md · gold/a graph that builds on day one, a guide, questionsAn ontology is a directory: the vocabulary, its rationale, rules, a sample graph and a README, and optionally a seed lexicon, the interview questions for the domain, a guide to reading the domain's graph (installed as GUIDE.md, quoted by the concierge skill), the actions the domain declares (actions/<id>.json, merged by id with the extender's winning, checked against the composed vocabulary and the sample, installed as the project's actions/), gold question patterns, and a manifest, manifest.json, that names it, versions it and says what it extends.
A directory without a manifest is still an ontology with defaults, so nothing exported before manifests existed breaks. model/ontology_manifest.py reads and checks the manifest; model/ontology_compose.py resolves extends (bases first, each once, cycles refused) and applies the parts in order: the extender wins a class description or an attribute type and the report says so, it may widen a relation's domain or range and never narrow it, rules merge by id and one id means one rule, the rationale of an inherited class stays the declaring ontology's, samples merge by node id, and the temporal vocabulary comes from the first part that declares it and is never merged.
ontologies.loadreturns the composed form, which is what a project gets; load_raw an ontology's own files.
The four shipped ontologies extend oto-core, which holds the temporal fields and Document, the class every fact cites. oto ontology show <name> prints an ontology's manifest, its composition and what the composition changed, and the self-check, which now covers the manifest, the optional files, and publishability: deny terms from OTO_DENY_TERMS found in any part, or personal data in the sample, make an ontology unusable.
oto initrecords in project.config.json which ontology and release the project started from (and the pack, when it came from one), and installs the lexicon seed, the interview (INTERVIEW.md) and the gold patterns beside the vocabulary.
A registry distributes ontologies: a git repository with an index, registry.json, and usually the ontologies beside it, private or public (model/registry.py).
oto registry add <url>fetches the index and records the registry in ~/.oto/registries.json (OTO_REGISTRIES overrides) with a cached copy of the index, so oto ontology lists what a registry offers without touching the network again.
oto ontology add <name>fetches an ontology into the user directory beside exports, with its provenance (registry, source, ref, commit) written into its manifest, so it works offline afterwards and oto ontology update knows where to look.
A name resolves in this order: an explicit path, the user directory, the registries in the order they were added, the built-ins. name@3 pins a version: the registry's current version comes from its index, an older one from the tag <name>/v3.
oto initnever fetches on its own; it names the registry and the command when an ontology is only there, and refuses a pin the local copy does not match. oto registry check is the registry's own gate: the index must match the directories beside it.
Transport is git, as for the engine and the query repository; the token OTO_REGISTRY_TOKEN goes into an https URL for the length of a call and nowhere else (gitx.py).
oto ontology publish --to <registry url>puts an ontology into a registry: exported from the project (--name, --summary, --from-graph) or copied from this machine (--ontology).
It bumps the version past what the index holds, writes the changelog entry (--note) on top of the registry's own history of that ontology, runs the self-check with the registry checkout as a root so siblings it extends resolve, regenerates the index, checks the index against the directories, commits, tags <name>/v<version> and pushes; on any problem nothing is pushed.
A registry that is registered on this machine has its cached index refreshed. oto ontology diff --project <root> reads the project's recorded ontology, fetches the upstream current version, and compares it with the version the project started from (the tag) or, when no tag exists, with the project's lock: changes with the same severities as oto ontology check, each with how many of this project's nodes or edges it touches, rule ids added, removed or changed, and the changelog entries the project has not seen.
It never writes. oto status prints one line when a newer version is known from the local cache or the engine's shipped copy.
The first publish into an empty repository also writes the registry's README and its check workflow, which runs oto registry check, every ontology's self-check and every pack's check on each push.
This is the plan, delivered, in the words of the ontology plan.
An ontology declares a domain, one lowercase slug: the category it belongs to, for grouping a
listing or a catalogue, never the artefact's name (a relation's domain and range live inside the
vocabulary and keep their names). The engine notes a domain it has not seen and never refuses one.