OTO
inside the engine · from ARCHITECTURE.md at v0.6.1

The compile stages

preflightthe ontology gate: undeclared vocabulary stops everything
→
ontologythe vocabulary as RDF and SHACL
→
knowledgeone page per entity, with its facts
→
semanticretrieval cards for search
→
sqlitethe store the server reads
→
neo4j · siteoptional targets: a shared store, a static site
Every stage is deterministic: the same graph builds the same bytes.

Each stage is a module with one function, run(project). It asks the project where to read and write, and never derives a path from its own location or carries a default vocabulary.

Order Module Reads Writes
1 compile/knowledge.py graph.json knowledge-graph.json, entity-index.json, N-Triples, two CSVs, one entity page per node
2 compile/rules.py knowledge-graph.json, rules.json derived.json: derived edges and attributes with rule, premises and depth; policy findings. Skipped with a note when no rules are declared.
3 compile/ontology.py ontology.config.json, knowledge-graph.json ontology.md, Turtle, JSON-LD context. Reports any type or relation the vocabulary does not declare.
4 compile/semantic.py knowledge-graph.json one retrieval card per node, with neighbour context inlined so a thematic search hits the right entity
5 targets/sqlite.py knowledge-graph.json, derived.json, the indexed directories (targets/rows.py), lexicon.json, the ledger <slug>.db with FTS5 tables, built as .db.new and renamed into place
7, when targeted targets/site.py the SQLite store, a view directory build/site/: data.json, the graph payload /api/graph serves (serve/payload.py), and the app's files copied beside it, for hosting anywhere static; oto publish --site carries it into the query repository
6, when configured targets/neo4j.py the same inputs as stage 5 the graph in a self-hosted Neo4j: entities labelled by class with typed attributes, relations, evidence and source nodes, derived facts marked, findings, and everything serving reads besides (passages with a full-text index, lexicon rows, the ledger, the schema version); the previous load retired once the new one is in; --verify reads it back

The stages are deterministic: the same inputs produce the same bytes, and a test asserts that a clean-then-build round trip reproduces the database exactly.