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

What a project holds

inbox/ · processing/ · corpus/where documents wait, are worked, and rest as dated sources
ontology.config.json · ontology.rationale.json · rules.json · actions/what the vocabulary is, why, what it derives and forbids, what can be done
graph.json · proposals/ · candidatethe curated graph, and the changes waiting at the gates
build/everything the compiler writes; deleted and rebuilt at will
gold/ · feedbackthe questions the graph must answer, and what readers said
A project is files. Nothing in it needs the engine to be read.
<root>/
  project.config.json     identity: slug, name, namespace, database name
  ontology.config.json    the vocabulary: classes, properties [domain, range, inverse, description],
                          attributes per class [type, description]
  ontology.rationale.json why each class exists and who confirmed it (optional, reviewable)
  rules.json              rules over the graph: derive (positive patterns) and policy (may negate)
  ontology.lock.json      the last accepted vocabulary and rules, written by `oto ontology accept`
  graph.json              the curated graph: the source of truth
  graph.candidate.json    an open `oto curate` session, if any
  proposals/              one file of proposed nodes and edges per source document (authored)
  actions/                one file per action: what can be done about an entity, in MCP tool
                          shape, bound to the graph; becomes an Action node at build (authored)
  assertions.jsonl        append-only log of things people said, citable as sources
  changelog.jsonl         append-only ledger: one entry per apply, with what was retired and why
  lexicon.json            optional: {"entries": [{"term", "aka": [...], "targets": [node ids], "status", "note"}]}
                          so a question in the reader's words resolves to an entity
  gold/questions.jsonl    the benchmark question set, with its own provenance
  feedback.jsonl          what readers said about answers
  notes/                  AUTHORED narrative markdown, indexed alongside the corpus
  notes/themes/           authored readings of the graph, dated, each naming the facts it rests on
  inbox/                  raw sources, unclaimed
  processing/             claimed by an ingest run and extracted; the graph does not hold them yet
  errors/<run>/           files a run could not extract, each with a .error.json beside it
  archive/                the graph holds them; only `oto ingest complete` moves files here
  runs/                   one manifest per run: files, content hashes, outcomes; index.json
  build/                  GENERATED. `oto clean` deletes it whole.
    documents/            the corpus, extracted to Markdown
    entities/  cards/  ontology/  graph/  <slug>.db

project.py resolves the identity and the graph path. layout.py resolves every generated path and says which directories the build owns.

This is the only layout, and oto init creates it. The pre-Oto layout, which mixed authored and generated files, was read through a --legacy flag until it had no users left; a project from that time is moved once with oto init and a copy of its graph.