OTO
deployment · from ARCHITECTURE.md at v0.6.1

A project as a repository

push to inbox/a document arrives in the repository
→
ingest workflowextracts it into the corpus
→
author workflowan agent drafts on a branch
→
pull requestthe gate: checks run, a person reviews
→
deploy workflowNeo4j, the query store, the site
Shipping knowledge like code: the repository is the source, the deployed graph is the living system.
oto init --repo

lays a project out to live on GitHub. It adds an .mcp.json so Claude Code has the query tools when it opens the repository, a CLAUDE.md saying what the repository is and what the rule is, and six workflows:

Workflow Trigger What it does
oto-ingest a push to inbox/ claims the inbox into a run, extracts, commits the outcome, opens an issue for what it could not extract
oto-author after a successful ingest an agent, running the Claude Code Action with this engine's plugin, drafts the run's proposals on a branch oto/run-<id>, applies them through the curate gates with a ledger note, builds, evaluates, and writes runs/<id>.report.md; the workflow commits the branch and opens a pull request with that report as its description, labelled blocked if the agent stopped
oto-checks a pull request the gates as status checks: status, candidate check, pre-flight and build, vocabulary, gold set, provenance
oto-review @claude in a pull request comment the same agent revises on the branch and pushes; the checks run again
oto-deploy a merge to main builds the store and keeps it
oto-actions a daily cron invokes the due read-only actions through the script under .github/scripts/ (the caller, never Oto), records the responses, takes the proposals through the gates and opens a pull request

The corpus under build/documents/ is committed in a repository, because it is an input to the build and to every review. Nothing reaches graph.json on main except through a pull request: that is the human gate in this mode, and every confirmation a playbook would ask a person for is a section of the report the pull request carries.

The unattended rules the agent follows are in pipeline-run.md. The authoring and review workflows need the repository secret ANTHROPIC_API_KEY; OTO_MODEL and OTO_ENGINE are optional repository variables.

Everywhere, the engine installs from its git repository rather than being assumed on a PATH: uvx on a machine, pip in a workflow, one URL in repo.py overridable with --engine or the repository variable OTO_ENGINE.

The deploy workflow has two targets. The self-hosted Neo4j is the production store (below). The query repository, when the repository variable OTO_QUERY_REPO names one and the secret OTO_QUERY_REPO_TOKEN can write to it (and the static site beside it when OTO_SITE_VIEW names a view), receives the built SQLite store on every merge through oto publish (publish.py): the database, the project's identity marked store_only, a manifest with the build sequence, hash and source commit, and a README.

Readers need access to that repository and not to the documents. oto sync --repo <it> clones or fast-forwards it into the store's cache directory (~/.<slug>-kg, or --dest), and oto serve, oto query and oto status recognise such a checkout and serve it under the project's own server name.

This is the offline and fallback path beside Neo4j: the two stores answer alike, so a reader who cannot reach the database loses freshness and nothing else. Git is the transport; the token lives in the environment for the length of the call and is never written or printed.