CLAUDE.md@crates/orbit-core · diff
git:20260829.e25929a to git:20260906.2c143e0
3 added, 3 removed. Audit A to A.
# orbit-core
Project instructions for the runtime composition crate.
## One job
Assemble every lower subsystem into `OrbitRuntime` and own the coordinated
use cases that need more than one of them. It is the authoritative place for
domain validation, authorization, auditing, and lifecycle decisions — the layer
that says *yes or no*, where transports only collect input.
It depends on the kernels below it and on nothing above: never `orbit-cmd`,
never `orbit-cli`/`orbit-web`, never `orbit-registry` (see
[orbit-cmd](../orbit-cmd/CLAUDE.md) for where Core and Registry meet), and never
`orbit-agent` (the engine's `cli_runner` owns that edge).
## The internal graph is enforced
`runtime <- application <- adapter`, with `composition` as the only joiner.
[`scripts/check-dependency-direction.sh`](../../scripts/check-dependency-direction.sh)
fails the build on a violation:
- [`runtime/`](src/runtime) — mechanisms: stores, event bus, audit, claims and
reservations, tool and process execution, root resolution, the workspace
catalog. It may not import `crate::application` or `crate::adapter`, and it
may not call `ResolvedConfig::load` or construct `ConfigRoots` — resolved
configuration is *handed to it* by composition.
- [`application/`](src/application) — shared use cases and their DTOs. It may
not import `crate::adapter`.
- [`adapter/`](src/adapter) — protocol translation only:
[`tool_host`](src/adapter/tool_host) for Orbit tools,
[`engine_host`](src/adapter/engine_host) implementing
`orbit_engine::RuntimeHost`, and [`command`](src/adapter/command) for command
dispatch. Adapters translate and delegate; a decision made in an adapter is a
decision in the wrong place.
- [`composition.rs`](src/composition.rs) — the only module that loads resolved
config and joins bootstrap, runtime construction, and adapter registration.
- [`bootstrap/`](src/bootstrap) — initialization, managed-asset seeding, policy
seeding, forward-only startup migrations. Runs once, at open.
- `auto_tasks`, `routines`, and `metrics` are domain kernels layered on the
- runtime: scheduling and derived measurement, each fired through the same v2 job
- machinery rather than through bespoke code paths.
+ `auto_tasks` and `routines` compose the scheduling domain in `orbit-automation`
+ with Core task/job lifecycle adapters [ORB-11330]. `metrics` owns derived
+ measurement. All use the existing v2 job machinery.
The guardrail also fails if a retired path reappears: `src/command`,
`src/runtime/orbit_tool_host`, `src/runtime/engine/runtime_host.rs`. Do not
recreate them; their successors are `orbit-cmd`, `adapter/tool_host`, and
`adapter/engine_host`.
## Root re-exports are justified, not convenient
Every `pub use` at [`lib.rs`](src/lib.rs) must correspond to a real import in a
consumer crate (`orbit-cli`, `orbit-web`, `orbit-cmd`). Do not add one to
shorten a path. Anything else is imported from its owning module
(`orbit_core::application::…`, `orbit_core::runtime::…`) or, when the type is
not Core's, from its owning crate (`orbit_common`, `orbit_store`,
`orbit_engine`). When you remove a consumer, remove the re-export with it.
## Crate-specific invariants
- **Core decides; MCP and the CLI ask.** New authorization, quota, or
validation logic belongs here even when the caller is a transport — do not
mirror a Core rule as client-side orchestration.
- **Operation handlers are joined by the verb enum.**
[`adapter/tool_host/friction_tools.rs`](src/adapter/tool_host/friction_tools.rs)
matches exhaustively on `FrictionVerb`, whose spec table lives in
`orbit_common::governance::friction`. The compiler is what proves every
declared verb is wired, so a new verb must never get a default arm.
- **Redaction stays shared.** `scripts/check-artifact-redaction-guardrail.sh`
forbids surface-local `fn redact_*` in
[`adapter/tool_host`](src/adapter/tool_host) and
[`application/task/add.rs`](src/application/task/add.rs).
- **Two roots, always.** Runtime resolution is a global root (`~/.orbit/`) plus
a workspace root (nearest ancestor `.orbit/`). Scope decisions follow the
table in [`ARCHITECTURE.md`](../../ARCHITECTURE.md) §Scoping Rules; do not
invent a third root or read one root's artifact from the other's path.
## Tests
Sibling `tests/` directories per module
([`test_layout.md`](../../docs/design-patterns/test_layout.md)). Crate-root
[`tests/`](tests) is reserved for integration tests that drive a composed
runtime end-to-end, such as the fake-agent backend smokes. Test a use case at
its owning boundary — an `application` operation through `application`, not
through an adapter that happens to call it.