Orbit / how it works / for review
Orbit is a self-hosted control layer for AI coding agents. This page explains how the pieces fit together, and the one piece that's missing โ a knowledge folder that lives in the repo and keeps itself current.
The problem
Every session starts from zero. Nothing an agent learns survives it.
An agent works out why a migration deadlocks on Tuesday. Thursday โ same project, maybe a different agent โ that reasoning is gone. It gets re-derived, or the same dead end gets walked again.
Why it persists: three memory stores that can't see each other โ Claude Code's, Codex's, and Orbit's โ two of them vendor-private. And the usual fix, a team wiki, dies of neglect.
The fix in one line: capture what every agent does through hooks that already exist, compile it once into shared project knowledge, and hand it back at the start of every session. The maintenance that kills human wikis is exactly the work a model does for free.
Graph 1
Five moving parts. Four exist today; the fifth is what's being proposed.
Human
One operator, several machines. Mostly on a phone, via Telegram.
Personal agent
Always-on assistant reachable on Telegram. Runs a PM profile per project that triages, proposes work, and asks Orbit to dispatch it.
Control layer
Mission control and system of record. Watches every session, ranks what needs attention, dispatches work, holds the state.
Workers
Claude Code and Codex CLI. Do the actual work, each in an isolated git worktree.
Reading surface
Markdown notes โ the human-readable layer where Sam reads plans, tasks and knowledge.
Proposed
docs/ folderThe project's own knowledge, living in the repo and versioned by git. The shared memory every project is missing โ everything below is about filling it.
Graph 2
One task, start to finish. Each step is done by a different player.
01
Sam messages Hermes on Telegram โ "get the deploy blocker fixed".
Sam โ Hermes02
That project's PM agent checks state, picks the task, and asks Orbit to dispatch it.
Hermes PM โ Orbit03
Orbit starts a coding agent in its own worktree, so parallel runs never collide.
Orbit โ Claude / Codex04
As it works, hooks stream what happened back to Orbit โ plans, tasks, progress, blockers.
Coding agent โ Orbit05
Orbit turns that raw evidence into project knowledge, and writes the human view into Obsidian.
Orbit โ knowledge + vault06
Sam gets progress and approval requests on Telegram. The next session opens already knowing all of this.
Orbit โ Sam, and โ next agentstep 06 feeds step 01 โ the loop closes, and each pass starts better informed than the last
Graph 3
The proposal itself, on one page. One rule shapes it: agents write evidence, one compiler writes knowledge โ and the compiler only runs on main, after a merge.
Orbit
Architecture / knowledge
๐ฐ orbit
Raw sources / immutable read, never edited
claude sessionscodex sessions dispatched runsagent memory files git historyEvidence log / append-only added to, never rewritten
what happenedwho claimed it plans + decisionsgaps are detectabledocs/ โ the project's knowledge written by the compiler, versioned by git
index.mdread first, every sessioncross-references, maintained by the compiler
The policy
Enforced by Orbit at every step โ not a convention agents are asked to honour.
โ governs the pages
A session
Lint / a periodic pass / keeps the pages honest
find contradictionsflag stale claims state what's missingfix broken linksCaptured by hooks, compiled at merge, versioned by git, read by every agent, kept honest by lint.
Why merge-to-main is the moment. It's not just tidy โ it's the correctness gate. Knowledge about code that never merged never becomes truth, and because the compiler only ever runs on main, two agents on two branches can't fight over a page. The thing that made this hard โ work stranded on branches that never land โ stops being possible.
Graph 4
What actually happens when a branch lands. The useful idea here is borrowed: documentation as a build artifact โ kept current by infrastructure, not by anyone's discipline.
Orbit
Pipeline / compile
๐ฐ orbit
A merge to main the only trigger
the code that landedthe evidence behind itWriters one page each, just enough context
docs/ committed on main, reviewable in a pull request
index.mdstatus.md decisions/timeline/Currency as infrastructure
Built from what landed and what happened, split across writers, kept current by the merge itself.
Where this differs from documenting a codebase. A tool that reads only your source can regenerate its output at any time โ nothing is ever lost. Three of the four writers above work like that. But why an approach was rejected is not in the code, and no future scan will recover it. That page is accumulated, never regenerated โ which is why the evidence log exists at all.
Graph 5
docs/Every project gets the same page set โ only the values differ. That's what makes it possible to ask one question across all of them at once. Standard templates organise by topic; this one organises by how each page stays true, because that decides who may write it and what a stale page means.
| Regime | Stays true by | Written by | A stale page means |
|---|---|---|---|
| Derived | Regenerated from code or data every compile | machine, no model | a bug โ it should have regenerated |
| Decided | Superseded explicitly by a later decision | model, from evidence | a missing decision record |
| Discovered | Never โ it's dated, and that's the point | append-only | nothing. It's history, not status |
The page set:
| Page | Regime | Answers |
|---|---|---|
index.md | derived | what exists here, and how to read it |
status.md | derived | tasks, blockers, next โ stamped with the merge |
architecture/overview.md | decided | what shape this system is, and what forced it |
architecture/backend.md | mixed | language, organisation, background work ยท + derived module inventory |
architecture/frontend.md | mixed | rendering approach, state, build ยท + derived route inventory |
architecture/data.md | mixed | stores, migrations, backup โ and when restore was last tested ยท + derived schema |
architecture/api.md | mixed | style, versioning, errors ยท + the derived endpoint inventory |
architecture/deployment.md | mixed | where it runs, how a change reaches prod, how it rolls back ยท + derived pipeline |
architecture/security.md | decided | who can do what, secrets, trust boundaries, accepted risks |
architecture/observability.md | mixed | how you'd know it broke ยท + derived alert inventory |
decisions/NNNN-*.md | decided | one decision each โ context, choice, alternatives rejected, consequences |
research/YYYY-MM-DD-*.md | discovered | spikes, benchmarks, dead ends โ the question, the numbers, the verdict |
timeline/YYYY-MM.md | derived | what happened, in order, from the event log |
Same schema, different values. Each architecture page carries typed frontmatter from a fixed vocabulary โ so one query answers across every project at once:
| Field | Pick from |
|---|---|
style | monolith ยท modular-monolith ยท microservices ยท serverless ยท event-driven ยท local-app ยท library ยท cli ยท hybrid |
runtime | bare-metal ยท vm ยท container ยท k8s ยท paas ยท faas ยท edge ยท on-device |
api.style | rest ยท graphql ยท grpc ยท trpc ยท websocket ยท mcp ยท none |
frontend.style | ssr ยท spa ยท ssg ยท islands ยท native ยท tui ยท none |
data.store | relational ยท document ยท kv ยท graph ยท vector ยท file ยท none |
auth | none ยท session ยท jwt ยท oauth ยท api-key ยท mtls |
deploy.strategy | manual ยท rolling ยท blue-green ยท canary ยท immutable |
envs | local ยท dev ยท staging ยท prod |
More than one value is often correct โ a public rest API alongside internal
trpc is a normal shape, not a contradiction. And extending a vocabulary is itself a
decision, so it gets an ADR.
Two rules that make it trustworthy. A page that doesn't apply โ deployment for a CLI tool โ
says applies: false with one line of reason, because an empty page is ambiguous:
not-yet-written and not-applicable look identical, and an agent can't tell them apart. And an accepted
decision is never edited to say something different โ a new one supersedes it. Having believed
something is itself information.
Graph 6
One store is the truth: the project's own docs/ folder. Everything else is either
something we read, or a copy we write out. Git provides the versioning, the history and the review โ so
there's no second knowledge database to keep in step.
| Store | What's actually in it | Owner | Its job |
|---|---|---|---|
docs/ in the repo the truth |
What happened, task status as of this merge, what's next, and what was tried and rejected. Plain markdown, committed with the code. | compiler writes git versions |
The source of operator truth. Every agent reads it, every agent feeds it, and it travels with the repo โ clone the code and you have the knowledge. |
Claude Code memory~/.claude/โฆ/memory/ |
An always-loaded index plus one small file per fact, written automatically at session end. | vendor | Read as raw material. Harvested at merge time, never edited. Keeps working exactly as it does now. |
Codex memory~/.codex/memories/ |
A global store โ a registry, a summary injected into every session, and one file per past session tagged with the folder it ran in. | vendor | Read as raw material, filtered to this project by that folder tag. |
| Orbit | Live task status, blockers, dispatch, attention โ plus the buffer of evidence waiting for the next merge. | Orbit | The pipeline and the live state. Not a second knowledge store: it holds what's happening right now, and stages what hasn't been written to docs/ yet. |
| Obsidian vault | A nightly mirror of every project's docs/, alongside Sam's own notes and the cross-project view. |
human + mirror | The reading surface โ one place to browse everything, and a backup. Delete it and nothing is lost. |
Two things live in Orbit rather than in docs/, on purpose:
| Live status | Tasks change state hourly; merges happen weekly. The docs/ status page is stamped "as of merge abc123" and is honest about that. Anything needing real-time state โ the dashboard, dispatch, phone approvals โ asks Orbit. |
| Work projects | Client repos can't be written to at all โ not one file. They get the identical pipeline, but knowledge is published to Orbit and the vault instead of a docs/ folder. Same machinery, different destination. |
What this simplification removes. An earlier draft kept versioned knowledge inside Orbit and synced copies out to each machine. Git already does versioning, history, diffing and review โ so that whole layer is gone, along with the sync protocol, the local cache, and the question of what happens when two machines edit the same page. Pull requests answer it instead.
Graph 7
The design works because each player has a narrow job and an explicit list of things it may not do.
Hermes โ per-project PM agent
May not: authorise its own dispatch, publish knowledge directly, or decide how much a claim is trusted.
Orbit โ control layer
May not: write anything inside a repository, or trust a trust-level an agent asserted about itself.
Claude Code ยท Codex CLI
May not: edit published pages, touch another project, or modify your instruction files.
Sam
Never has to: paste context, maintain a wiki, or tell one agent what another already learned.
Graph 8
Evidence is captured continuously, but docs/ is only rewritten at moments where the work is
settled. Three triggers, in order of how much they matter.
Primary
A branch lands. A hook fires, and the compiler reads everything that happened on that work โ evidence, plans, both agents' memory files โ and updates docs/ in one commit.
Catch-up
Not everything merges. Exploratory sessions, abandoned branches, research, long-running work โ a nightly pass folds in whatever the merge trigger missed.
so nothing is lostOn demand
Sam or a PM agent can ask for a refresh โ before a review, after a big change, or when the status page is visibly behind.
manualevidence is recorded the moment it happens ยท docs are rewritten when the work settles
Graph 9
Three agents can run on one project at once, on different machines. Collisions are prevented by construction rather than resolved afterwards.
| Moment | What the agent does | Why it can't conflict |
|---|---|---|
| Session opens | Receives the project briefing automatically โ no lookup, no prompt | Read-only, from a local copy |
| While working | Asks Orbit questions โ current status, open tasks, past decisions | Read-only, and always answered from one source |
| Makes changes | Edits code in its own isolated checkout | Nobody else is in that checkout |
| Learns something | Adds a new entry to the shared log โ never edits an existing one | Adding can't overwrite; two agents adding at once is fine |
| Session ends | Its evidence is already recorded, whether or not the branch is ever merged | Knowledge leaves by a route that doesn't depend on merging |
| Later | Nothing โ the compiler folds everything in | One writer means no page ever has two authors |
The whole trick: agents only ever add, and only one component ever rewrites. Everything else is a copy that can be thrown away and rebuilt.
Graph 10
Two commands total. One per machine, one per project โ and the repository is never touched.
Once per machine
orbit setupOne prompt you can't avoid: Codex asks you to trust the hooks. That's deliberate on their side.
Once per project
orbit project init .docs/ exportYou can skip this โ an unknown repo is noticed on the next session and offered for setup.
Every session, automatically
What that actually installs, and where:
| Location | What lands there | Reversible? |
|---|---|---|
| Claude's global settings | A few hook entries, merged into what's already there | yes โ backed up, and removable in one command |
| Codex's global settings | The same hook entries, in Codex's format | yes โ same |
~/.orbit/ | The event queue, the local knowledge copy, config | yes โ delete it and it rebuilds |
| Orbit's database | Live task state, and evidence waiting for the next merge | this is the operational state โ it's what gets backed up |
| A personal repository | One docs/ folder โ the knowledge itself, committed and reviewable. Nothing else: no config edits, no instruction files, no hooks in the repo. | yes โ it's just markdown in git |
| A work repository | Nothing. Not one file. Knowledge for these lives in Orbit and the vault. | n/a |
Why the split: half these projects are client work, where writing anything into the repo is unacceptable โ so those keep a zero footprint and publish elsewhere. Personal projects get the better deal: the knowledge lives with the code, versioned by git and reviewable in a pull request like any other change.
Status
The substrate is in daily use and covered by 645 tests. The knowledge layer is entirely unbuilt.
| Piece | State |
|---|---|
| Hooks capturing every Claude session (~7,856 events so far) | running |
| Event log with dedup and secret quarantine | running |
| Dispatch to Claude and Codex, with worktree isolation and phone approvals | running |
| Obsidian vault, search, nightly maintenance pass | running |
| Per-project Hermes PM agents | running |
| Same capture for Codex as for Claude | to build |
The compiler, and docs/ written on merge to main | to build |
Session-start briefing, read from docs/ on disk | to build |
| Completeness contract โ pages that admit what they're missing | to build |
Two rules that shape everything
| Work projects are untouchable | Every project is tagged personal or work. Nothing is ever written inside a work repository โ not a file, not a config line. So the knowledge has to live outside the repo. |
| Agents work in isolation | Dispatched runs happen in separate git worktrees. Anything written inside the repo only reaches the main branch if that branch gets merged โ and abandoned branches are kept, not deleted. So knowledge must leave by a route that doesn't depend on merging. |
If you're reviewing this
Detail
This page is deliberately high level. The full architecture โ content-class conflict policy, the authority model, the completeness fields, identity resolution, the 7-phase rollout, and the four corrections a prior review forced โ sits in the decision register and the plan document.
| Question | Short answer |
|---|---|
| Who can publish knowledge? | Four capabilities: view ยท contribute evidence ยท publish (curator) ยท set policy (admin). Contributors never publish. |
| What if two agents write the same thing? | Mostly impossible by design โ evidence is create-only, published pages have exactly one writer, caches are one-way. Only drafts need conflict handling. |
| How does a page prove it's current? | It carries the snapshot it reflects, how far each source was read, how many events are unprocessed or quarantined, and a plain verdict: complete, degraded, or unknown. |
| Who decides how much to trust a claim? | Orbit does, never the agent making it. An agent's claim is always recorded as "claimed"; only a human or verified system can promote it. |
| Does this touch my repo's config files? | No. Instruction files stay human-owned and hooks are installed globally, never in the repo. The only thing written into a personal repo is the docs/ folder itself โ and nothing at all into a work repo. |