Codebase orientation
apomesh is a Cargo workspace of Rust crates plus a Python SDK and a Tauri console. This page is the code map for someone about to work on the substrate itself: the mental model, a walk up the layers with the one thing to understand before touching each, the discipline contracts a change must respect, and a reading order that gets you productive fast.
Crate names and entry points below are verified against the workspace at
HEAD. The in-repo
docs/architecture.md
carries the exhaustive per-crate deep-dives; where its inventory and the
code disagree, the code wins.
The mental model
Section titled “The mental model”apomesh is two runtime planes — a control plane (the orchestrator that decides) and a distributed execution plane (the workers that execute) — with a set of operator-facing planes layered over them: agent configuration, context, memory, credentials, identity, and the orchestration strategies that drive a session. Concepts explains why each plane exists and how they fit; this page maps each one to the code that implements it.
| Plane (the why) | Concept home | Where it lives in code |
|---|---|---|
| Control + execution | /concepts/control-and-execution/ | apomesh-orchestrator, apomesh-worker |
| Orchestration strategies | /concepts/loops/ | orchestrator VMAO coordinator + verticals |
| Agent configuration | /concepts/agent-configuration/ | apomesh-substrate-catalog |
| Context (prompt + compaction) | /concepts/context-plane/ | apomesh-substrate prompt composition + catalog |
| Memory | /concepts/memory-plane/ | apomesh-substrate-state + the state stores |
| Credentials | /concepts/credential-plane/ | apomesh-substrate credential store, resolved by the orchestrator |
| Identity + authorization | /concepts/identity-authorization/ | apomesh-auth-providers |
| Sessions + events | /concepts/sessions-and-events/ | orchestrator event log + the state stores |
The layer walk
Section titled “The layer walk”The workspace stacks bottom-up. Each row names the layer’s primary crates (linked to their reference pages) and the one thing to understand before you change them. The full per-crate role inventory lives in the crate reference; this walk is the value-add on top of it.
| Layer | Crates | Know this first |
|---|---|---|
| Wire | apomesh-protocol | The Envelope.payload oneof in proto/apomesh.proto is the substrate’s external API. Any change here sweeps every mirror — see contract parity below. |
| Substrate types | apomesh-substrate-types | The dependency-light vocabulary: closed enums, boundary types, and the port + plugin traits every plane binds to. Nothing here depends on a plane; change a trait signature and every implementation must follow. |
| Substrate core | apomesh-substrate | The policy core built on the -types vocabulary — supervisor strategies, routing, the predicate evaluator, the credential store. It carries semantics, not I/O. |
| Implementation planes | -llm, -mcp, -sandbox, -state, -tools, -catalog, -net | Each plane provides one implementation family behind a -types port. A plane depends on -types; the core never depends on a plane. Add a provider or adapter here, not in the core. |
| Orchestrator (control plane) | apomesh-orchestrator, -bin | The daemon: per-session actors, the VMAO coordinator, routing, cost rollup, the event bus, HITL. session_entry.rs is the seam where a session’s coordinator is chosen; -bin wires the registry to concrete strategies. |
| Worker (execution plane) | apomesh-worker, apomesh-tool-runner | The execution endpoint: per-agent working memory and the tool-use loop. tool-runner is the subprocess that runs one tool inside the OS sandbox and exits — the sandbox boundary is a process boundary. |
| Stores | -postgres, -redis, -smartchat-postgres | Production adapters behind the StateStore port. The append-only event log is the source of truth; snapshots are derived. |
| Transports + surfaces | apomesh-rest-api, apomesh-auth-providers, apomesh-config, apomesh-smartchat | REST/JSON + the SSE tail, the auth backends, daemon config, and the operator-chat layer. Each projects the same substrate the gRPC wire exposes — it never adds a parallel code path. |
| Verticals | deep-research, coding-assistant, projection | End-to-end use-cases that plug into the strategy and tool seams beside the substrate — never absorbed into it. A vertical specializes the loop without changing the core. |
| SDK | sdks/python | The Python client, with full wire parity to every Payload variant and closed enum. |
| Console | apomesh-control-plane | A Svelte 5 webview over a Rust bridge (src-tauri/src/commands/) that proxies typed IPC to the daemon’s gRPC surface and projects responses through an exhaustive events.rs match. |
A handful of crates sit beside these layers as tooling: apomesh-bump
(workspace version bump), apomesh-reseal (sealing-key rotation),
cassette-refresh (wire-drift detection — see Testing),
and samples/tail-consumer-prometheus (a reference event-bus consumer).
The discipline layer
Section titled “The discipline layer”apomesh defends its architecture with always-loaded rules under
.claude/rules/,
each declaring a tier. Invariant rules are correctness contracts —
never violated; a breach is a bug, not a trade-off. Default rules are
heuristics that yield to a technically-defended better shape. These are the
Invariant contracts a change must respect, each named by its rule path:
- Closed enums + canaries —
closed-enum-discipline.md. The substrate’s semantic vocabularies (supervisor strategies, failure classes,Payloadvariants, capability tiers) are closed Rust enums matched exhaustively — no_ =>wildcard. Adding a variant is welcome and additive; the discipline is that a compile-time canary (an exhaustivematch, aconst _: neverguard) forces every mirror site to handle it, so a new variant can’t reach the wire without a projection. The closed enum is the external API at the semantic level. - Boundary types —
boundary-type-vocabulary.md. Each interface is named with a precise term that carries its extensibility contract: a hexagonal port (StateStore— the deployment picks one adapter), a plugin (LLMProvider,Tool,SessionAuth— many coexist), a platform abstraction (ToolSandbox— per-OS), a transport (WorkerDispatch— gRPC or in-process), a configuration surface, and substrate-shipped policy (the closed enums). The name tells you where a new implementation may plug in; mixing the terms up loses that information. - Tenant isolation —
tenant-isolation.md. Every stateful operation is scoped byTenantContext; no query, cache key, or store read crosses a tenant boundary except the single audited cross-tenant agent resolve. A leak here is a cross-tenant data breach, so the boundary is enforced, not assumed. - Secret handling —
secret-handling.md. Every secret lives in the one per-tenant credential store, is never readable by an agent, is resolved server-side per tenant, and is forwarded to a sandboxed tool only over a fail-closed secure hop — never on the event log, a checkpoint, the prompt, or SSE. One ubiquitous pattern keeps every new secret automatically correct; a second store is the next leak. - Event-sourcing —
event-sourced-observability.md. The append-only event log is the single source of truth for a session; live state is a fold over events, snapshots are derived optimizations, and resume and replay reconstruct from the log. Durability, inspectability, and reproducible replay all rest on the log being authoritative — never the in-memory state. - Contract parity —
contract-parity.md(Default, but the rule every wire change hits). When a shared boundary contract changes — the proto, a closed enum, a mirrored boundary type — every hand-mirror (SDK stubs and models, the Tauri Rust projection, the TypeScript union, the round-trip tests) changes in the same PR. The Invariant canaries above enforce the correctness; this rule names which surfaces to sweep and requires they land together, because a variant that reaches the wire but not a consumer’s projection is silent drift.
Two more Invariant rules govern the shapes above without needing their own
paragraph here: layer-role-discipline.md (orchestrator decides, worker
executes, dependency direction points inward) and sandbox-by-default.md
(tool execution is OS-isolated unless a boundary is proven secure).
Reading order
Section titled “Reading order”Read the concept first, then the code it maps to. A productive path:
- The runtime model — architecture overview and Control & execution planes, so the crate walk above has a shape to hang on.
- Substrate types —
apomesh-substrate-typesfor the closed-enum vocabulary and the port/plugin traits, thenapomesh-substratefor the policy core built on them. - Wire —
apomesh-protocol/proto/apomesh.proto. TheEnvelope.payloadoneof variants are the substrate’s external API at the protocol level. - Worker —
apomesh-worker’s executor and tool-use loop, the most concrete thing happening in the substrate. - Orchestrator + a strategy —
apomesh-orchestrator/src/lib.rsand thesession/tree, then readverticals/deep-research/src/strategy.rsagainst the VMAO loop to see how a use-case specializes the loop without touching the core. - Sandboxing —
apomesh-substrate-sandboxplusapomesh-tool-runnerfor the full OS-isolation boundary. - Persistence — the
StateStoreport inapomesh-substrate-types, then an adapter (apomesh-substrate-statefor in-memory/SQLite; the state-store crates for production), against Sessions & events. - The SDK as a user surface —
sdks/python/apomeshshows what consumers actually see.
Where things happen
Section titled “Where things happen”Starting points for the most common changes, verified against HEAD:
| I want to… | Start at |
|---|---|
| Add a leaf tool | Implement the Tool trait (apomesh-substrate-types/src/tool/mod.rs) beside the shipped tools in apomesh-substrate-tools (web, file-ops, git, shell). |
| Add an LLM or embedding provider | Implement LLMProvider (apomesh-substrate-types/src/llm_provider/mod.rs) or EmbeddingProvider, with the impl in apomesh-substrate-llm. |
| Add a coordination strategy | Implement the orchestrator’s SessionStrategy seam; the shipped worked example is verticals/deep-research/src/strategy.rs. Concept: /concepts/loops/. |
| Change the wire | Edit apomesh-protocol/proto/apomesh.proto, then run the contract-parity sweep — SDK regen, the UI mirror, the round-trip canaries. See Testing for cassette drift. |
| Add a console surface | Add a #[tauri::command] in ui/control-plane/src-tauri/src/commands/ and its Svelte component under ui/control-plane/src/components/; the bridge projects gRPC responses through events.rs. |
| Add a vertical | A new crate under verticals/ that plugs into the strategy and tool seams; worked examples are deep-research and coding-assistant. |
Dev workflow
Section titled “Dev workflow”A source edit only reaches a running container through an image rebuild —
bringing the stack up does not rebuild stale images. Dev sessions often run
in a git worktree so the running artifacts provably reflect that branch’s
code rather than the main checkout’s. The full lifecycle — compose profiles,
~/.apomesh/env, rebuild-and-recreate — lives in
Local stack.
Before you push, run the checks in Testing: the
cargo nextest workspace run, doc tests, cassette replay, and the
testcontainers tiers. Improving these docs is covered in
Working on the docs.
Next steps
Section titled “Next steps”- Run the checks: Testing.
- Understand the runtime concepts a crate implements: Concepts.
- Look up an individual crate: the crate reference.