Architecture map
UH is layered so that each layer only talks to the one below it, and everything that persists goes through a Zod schema. The rule from AGENTS.md: the CLI dispatches, src/harness/ owns lifecycle behavior, src/schema/ owns persisted contracts, src/adapters/ owns runtime-specific execution.
.harness/ through the same CLI-safe primitives; they never define contracts of their own.For a generated, file-by-file view of the same structure, see the Code map and the interactive explorer.
Who owns what
Section titled “Who owns what”| Area | Owner | Key entry points |
|---|---|---|
| Command parsing | src/cli.ts |
RUNTIME_WIRINGS maps each runtime id to {dryRun, run, surfaceBlocked}; most actions lazy-load their harness module with await import(...) |
| Persisted contracts | src/schema/*.ts |
MissionSchema, ProjectSchema, AdapterSchema, RuntimeResultSchema, ToolGuardPolicySchema, … |
| Lifecycle | src/harness/ (about 100 modules on v0.11) |
initializeHarness, proposeMission, checkMissionPackets, verifyMission, promoteMission, landWorkerBranches |
| Runtime execution | src/adapters/<runtime>.ts |
each registers with runtimeRegistry and exports check*, plan*Run, dryRun*, run* |
| Capability manifests | src/adapters/capabilities/*.ts |
uh.adapter-capabilities.v0: cost class, context window, sandbox support, tool surface |
| Guard hooks | src/extensions/tool-guard/ |
compiled to dist/extensions/tool-guard/*.js, snapshotted per content into a user cache before a run |
| Memory | src/extensions/honcho-memory/ |
optional Honcho memory for codex, hermes, oh-my-pi and pi |
| TUI | src/tui/ |
run from source by Bun: bun --preload @opentui/solid/preload src/tui/index.tsx |
| Library API | src/index.ts |
exports only init, status, validate, verify, promote, paths and registry |
| Build | scripts/build.mjs (v0.11) |
builds into dist.next, swaps it into dist, keeps dist.old, so a failed build never leaves a broken CLI |
A command’s path, end to end
Section titled “A command’s path, end to end”Take uh mission run .harness/missions/m1/mission.yaml --runtime oh-my-pi:
- CLI. Commander parses the flags;
src/cli.tsloads the mission file throughMissionSchema(a typo fails here, naming the field). - Admission. Template adoption, routing, capability and requirement preflight, sandbox routing and fleet admission run in order (lifecycle, step 3).
- Recovery wrapper.
runWithRuntimeRecoveryowns resume, steer and deadline grace, and calls the oh-my-pi adapter. - Adapter.
src/adapters/oh-my-pi.tsallocatesruns/<run-id>/, claims a live-run entry at the project root, builds the dispatch context (mission, workflow, project brief, verified hive facts), renders the prompt with the final-message sentinel, writestool-guard.json, installs the guard hook snapshot, arms the guard with two synthetic probes, writes a per-runomp-overlay.ymlthat pins every OMP model role to the assigned model, and spawnsomp --print --mode json. - Execution core.
runRuntimeProcessstreams native events toRuntimeSupervision(limits, stop codes, route attestation), the run digest builder, the loop watchdog (shadow mode) and the intervention ledger. Inside the runtime, every tool call hits the guard hook, which fails closed. - Settlement. On exit, the control file and result are reconciled, the diff is captured, cost is resolved against
.harness/prices.yaml, the live-run entry settles, notifications fire, and the CLI printsUH_RESULT.
Design rules that shape the code
Section titled “Design rules that shape the code”- Filesystem first, daemon never. Coordination between processes (live runs, steer requests, cancellation, the hive) is done with files and atomic renames, retried on Windows where open handles block renames.
- Fail closed. The guard hook denies on any internal error; arming failure stops the run before spawn; an unknown model is refused; an unknown cost stays unknown instead of becoming zero.
- Deterministic before semantic. Model judgment (routing Level 1, System One verification) only ever chooses among options that deterministic code already allowed, and cannot overturn a deterministic failure.
- Evidence over claims. Hive facts must cite evidence and are hash-chained; land decisions and interventions are hash-chained; acceptance evidence is bound to an input digest.
Where the complexity is
Section titled “Where the complexity is”The 20 largest files on the v0.11 line, which is also where the refactoring budget should go first:
| File | Lines | Note |
|---|---|---|
src/cli.ts |
3,709 | Should be a thin dispatcher. See debt. |
src/harness/team-run.ts |
2,407 | Planning, git, salvage, integration and verdict in one file |
apps/hermes-plugin/dashboard/plugin_api.py |
1,907 | FastAPI router for the dashboard |
src/harness/acceptance.ts |
1,685 | Acceptance campaign runner and report |
src/adapters/oh-my-pi.ts |
1,439 | Most complete adapter: guard, overlay, resume |
src/adapters/openrouter.ts, hermes-proxy.ts, anthropic.ts |
about 1,000 each | Three near-parallel HTTP adapters that could share one client |
src/harness/run-digest.ts |
1,038 | Live run digest |
src/tui/dashboard.tsx |
1,001 | TUI main view |
src/harness/notifications.ts |
991 | Sinks and presets |
src/adapters/pi.ts, hermes.ts, codex.ts, acp.ts |
800 to 920 each | |
src/harness/live-runs.ts, kill.ts |
about 840 each | Run registry and kill proof |
src/harness/runtime-supervision.ts, verify.ts |
about 750 each |
src/ is about 53,000 lines on the v0.11 line, with 147 test files.