OTO

Getting started

OTO turns the documents and conversations a team already has into a knowledge graph it can trust: every fact with its date, its source and the sentence it came from, nothing overwritten, and an agent that answers from it with citations instead of guesses.

What you get. Questions like what is the deductible, and what was it in March? answered with the document and the date. A correction said in a meeting recorded as a fact that supersedes the old one, without losing it. A graph an agent can read, so its answers cite rather than invent. A measurement of how well it answers, honest about what it could not measure.

Where it is useful. Anywhere the knowledge is real but scattered: a claims department's procedures and bulletins, a platform team's systems and decisions, an organisation's roles and policies, a product through its lifecycle. One graph per domain, started from a pack for that domain. The examples show six.

How it works, in four moves. You install a pack in Claude Code, the harness OTO is tested with; the skills and the tools are standard, so your preferred harness can load them, and more are being tested. The agent reads your documents and proposes the facts, one document at a time. The engine gates what it proposes, refusing what the vocabulary does not declare, what has no source, and what would overwrite a fact, and you decide at each gate. Then you see the graph, ask it, correct it, and measure it.

The rest of this page does exactly that, in eight steps, in about thirty minutes. It was run before it was published: the replies quoted are what the agent said, on 2026-09-26, on five short documents about a fictional motor insurer.

1 Install2 Start3 Documents4 The gates5 See it6 Ask7 Correct8 Measure

1. Install

Two things on the machine: uv, and the engine's command line, which the agent's skills call as oto.

uv tool install "oto-kg @ git+https://github.com/Cynergis/oto"

Then, in Claude Code, add the registry as a marketplace and install a pack. The engine plugin comes with it.

/plugin marketplace add Cynergis/oto-registry
/plugin install auto-claims@cynergis
✔ Successfully added marketplace: cynergis
✔ Successfully installed plugin: auto-claims@cynergis (scope: user) (+ 1 dependency: oto)

From now on the agent has the pack's start skill, the engine's ten skills, and the fourteen query tools as an MCP server for whatever directory Claude Code opens. Install in Claude Code has the details.

2. Start a project

Open Claude Code in an empty directory, with your documents in a folder beside it. Say what you want.

You: Start a knowledge project for Meridian Auto Insurance from the installed auto-claims pack, here in this directory, named "Meridian Claims".

The agent loads the pack's start skill and runs one command, oto init --pack with the installed pack's directory.

The agent: The project "Meridian Claims" is initialized here, seeded from the auto-claims pack (ontology: Policy, Coverage, Claim, Incident, Vehicle, Party, Role, Task, Assessment, Decision, Payment, Recovery, Procedure, Regulation, Document).

Next steps, when you're ready: fit the vocabulary to your documents with the ontology-interview skill, or add documents and hand off to the build-knowledge-base skill. Do you have documents ready to bring in now?

3. Documents

Five documents, in a docs folder: an operations handbook, a total loss procedure, a glass claims procedure, a regulatory note, and a March bulletin that raises a limit the handbook states. Say where they are and that you want to stop at the gates.

You: Build a knowledge base from the documents in the docs folder. Stop at each gate and ask me.

The agent loads the build-knowledge-base skill, ingests the folder, surveys it, and reads every document in full. The engine's report of the ingest:

run 20260926-083100: claimed 5 file(s) into processing/ (copied from ./docs; the originals are untouched)
  bulletin-2026-03.md -> documents/bulletin-2026-03.md (text)
  claims-operations-handbook.md -> documents/claims-operations-handbook.md (text)
  ...
run 20260926-083100: extracted 5, blocked 0, unsupported 0, missing parser 0, failed 0

4. The gates

Gate 1: what must this graph answer? Before proposing a single fact, the agent lists the questions and checks the vocabulary against them.

The agent: Here's Gate 1: the questions this knowledge base should answer, derived from what the documents actually say.

  1. What is the claims adjuster's current authority limit, and when did it last change? (handbook, bulletin)
  2. Above what amount does a settlement need the claims lead's approval?
  3. What is each coverage's deductible (collision, comprehensive, liability)?
  4. When is a vehicle declared a total loss, and who takes over the claim then?
  5. What regulatory timelines govern claim acknowledgment and coverage decisions, and who is accountable? (thirteen in all)

Vocabulary fit: the project's existing 17-class ontology already covers everything these 5 documents assert. I'd add two small attributes to make key figures directly queryable: Role.authority_limit and Coverage.deductible.

One cross-document wrinkle to flag now: the handbook (2026-01-15) states the adjuster's authority limit is $25,000; the March bulletin raises it to $30,000 effective 2026-03-01. That's a genuine supersession, not a contradiction. I'll model it as such, not an overwrite.

Confirm this question list and the two attribute additions, and I'll move to drafting the per-document proposals.

You: Confirmed: the question list and the two attributes. Go ahead with the proposals, and stop at gate 2 with the diff.

The agent writes one proposal per document, in date order, and merges each through the engine's dry run before the real merge. It reuses ids the graph already holds, checking with oto curate resolve before inventing one. Then it runs the check and shows you the diff.

Gate 2: the diff, before anything is applied.

The agent: What the candidate graph will hold: 21 nodes, 9 edges. Document 5, Role 6 (5 current + 1 superseded), Procedure 5, Coverage 3, Regulation 1, Party 1.

bulletin-2026-03 (2026-03-02): one real supersession: adjuster authority limit $25,000 → $30,000 (old node marked superseded, new node cites the bulletin, change note recorded); new party Northgate Body Works joins as an approved repairer.

One thing to flag and decide on: oto curate check reported a "contradiction". The auto-claims pack ships a fictional demo graph. I cleared that placeholder data out of the candidate since none of it comes from Meridian's actual documents. One node, coverage.collision, shares an id with the real Collision coverage I authored from the handbook, so the tool sees it as "same id, changed value". Confirm you're OK with treating that as discarding placeholder content, or I can instead formally supersede it.

Left out / not inferred: no document gives a deductible for liability cover, left blank rather than guessed. The ontology has no direct Role→Procedure relation, so "who performs which procedure" lives in each node's evidence, not as an edge.

This is what a gate looks like: the engine refused a changed value without a supersession record, the agent explained why this one is a sample being discarded, and the decision is yours. The engine's own line:

candidate would change the graph:
  nodes: +20  -13  ~1
  edges: +9  -20
    node changed  coverage.collision           (summary)

You: Confirmed, including the sample-data cleanup. Apply it as "A. Reader, claims operations", build, verify against the gate 1 questions, then start the explorer on port 8765 in the background and tell me the address.

The agent: Applied and built: the 5 documents' facts are now in the graph, ontology accepted as the baseline, provenance vetted clean, and the run archived. Ledger entry attributed to "A. Reader, claims operations."

Verified against all 13 Gate 1 questions. Every one resolves to a cited, dated fact. oto query stale confirms exactly one superseded fact in the whole graph, the deliberate authority-limit change, nothing accidental.

Explorer running in the background: http://127.0.0.1:8765

Apply needs a name, because an unattributed change cannot be followed up. The one superseded fact, as the engine lists it:

status_counts: current=20, superseded=1
Superseded (1):
  - Claims adjuster (role.claims-adjuster)  valid_to=2026-03-01 → role.claims-adjuster-2026-03

5. See it

Open the address. The explorer draws the graph: five documents on the left, the coverages, the party, the roles and the procedures they feed, the regulation. Click an entity for its card: status, dates, source, evidence, connections.

The explorer showing the Meridian Claims graph: documents, coverages, a party, roles, procedures and a regulation
The explorer, served by the engine, on the graph the agent just built.
The explorer with the claims adjuster's card open: current since 2026-03-01, its attribute, its source and its evidence from the bulletin
An entity's card. The claims adjuster as it is now: current since 2026-03-01, the authority limit as an attribute, the bulletin as its source, and the sentence.

Say --view reader and the same graph is served as pages. A pack can ship its own view.

6. Ask

Back in Claude Code, ask in your own words. The agent loads the query-knowledge skill and answers through the query tools, current facts only, with the source and the date, and says what the graph does not know.

You: What is the claims adjuster allowed to settle on their own, and was that the case in February? And who approves anything above it?

The agent: Currently: the claims adjuster may settle up to $30,000 on their own (current as of 2026-03-02, valid from 2026-03-01, bulletin-2026-03).

In February 2026: no, it was lower, $25,000 (valid 2026-01-15 to 2026-03-01, claims-operations-handbook). That fact is now superseded; the bulletin explicitly frames the change as "up from 25,000."

Above the limit: the claims lead approves any settlement above the adjuster's authority limit, stated the same way both before and after the March change.

Open: no document gives the claims lead their own settlement ceiling or says who approves above that. The graph is silent past the claims lead.

The last line is the Verifier's habit in the agent's mouth: what the graph does not hold is said, not filled in.

7. Correct

Knowledge changes in conversation before any document does. Tell the agent.

You: A correction from R. Osei, the claims lead, today: "The collision deductible went up to 750 dollars on the first of April. The handbook still says 500." Record it properly and take it through the gates; apply as A. Reader, claims operations, then tell me what the graph says the deductible was in March and what it is now.

The agent records the statement in the assertions log with the speaker's name and the date it refers to, writes a proposal that supersedes the old fact, and takes it through the same dry run, merge, check and apply.

recorded a-0001
  by   R. Osei, claims lead
  at   2026-04-01
  text The collision deductible went up to 750 dollars on the first of April. The handbook still says 500.

The agent: In March 2026: the collision deductible was $500 (valid 2026-01-15 to 2026-04-01, claims-operations-handbook).

Now: it's $750 (current as of 2026-04-01, sourced to R. Osei's assertion a-0001, recorded today).

One thing worth flagging, in Osei's own words: the handbook itself hasn't been updated. The graph now correctly shows $750 as current, but that rests on a spoken correction, not a revised document. It's worth getting the handbook amended so this fact has a written source again.

Nothing was overwritten. The March fact keeps its dates and its source, and a question about a March incident still gets the March answer.

8. Measure

You: Now measure it: make a gold question set from the gate 1 questions, with you as the author and me, A. Reader, as the checker, and run the bench. Show me the report.

The agent starts a gold set, writes the thirteen questions with the sources and entities each should return, validates it, and runs the bench. The report begins with where the questions came from, before any number:

WHERE THESE QUESTIONS CAME FROM
Questions authored by: Claude (Sonnet 5) (model)
MODEL-AUTHORED. A model does not remove author-as-evaluator bias if the same model
family authored the graph; it removes human effort. Treat this as an internal
measurement, not a published claim.
NOT human-audited.

RESULTS  (coverage at k=5)
system              cite F1  passage  surfaced   entity temporal  ms/query
lexical               0.417    0.917     0.917    0.000    0.000     0.284
oto                   0.861    0.917     1.000    0.692    1.000     0.843

NOT MEASURED:
  dense      numpy is not installed

The agent: Citation F1 more than doubles with the graph (0.417 → 0.861). Temporal: 1.000, the one temporal question resolved correctly past the March supersession. Dense baseline: not measured, so this isn't a full three-way comparison. Your part as checker: the gold set and this report are sitting unaudited. Worth walking through gold/questions.jsonl and marking audited_by once you've checked the 13 questions.

The engine says what it could not measure, and the agent hands the audit back to a named person. That is the loop: a reader's verdict on an answer becomes a test the next run measures.

What you have, and what next

A project directory that is data only: the documents, the vocabulary with its recorded reasoning, the graph with a ledger, the gold set, and a build. Commit it. oto init --repo lays the same project out for GitHub, where a push ingests and the pull request is the gate: knowledge shipped like code.