Skip to main content

Module harnesses

Module harnesses 

Source
Expand description

Harness substrate — Rust port of packages/cli/src/harnesses/types.ts and friends.

burn run <harness> is a wrapper that spawns a coding-agent process (Claude Code, Codex, OpenCode, …), babysits its session log while it runs, and feeds the resulting turns into the relayburn ledger. Every adapter contributes the same five-step shape:

  1. plan — compute the spawn plan (binary + args + env). Per-harness transports inject session ids or hook arguments here.
  2. before_spawn — fire any pre-spawn side effect: stamp now if the session id is known up front (claude path), or drop a pending-stamp manifest the post-spawn ingest pass will resolve (codex / opencode).
  3. start_watcher (optional) — return a WatchController that drains a session-store directory while the child runs. Adapters that ingest a single pre-known session file (claude) return None here; adapters that share the pending-stamp shape (codex, opencode) wire the watch loop through pending_stamp::adapter.
  4. after_exit — run a final ingest pass after the child exits and return an IngestReport so the driver can fold it into the unified [burn] <name> ingest: … line.
  5. The driver itself owns step zero — collecting cwd, passthrough args, and any user-provided enrichment tags into a PlanCtx — and step six — joining the watcher and reporting summary stats.

§Where this fits

This PR (#248 part b) is the substrate. The Wave 2 PRs (#248-d/e/f) plug the three concrete adapters into registry and the burn run driver in commands::run consumes them. The CLI scaffold (#248 part a, sibling worktree) lands the clap entrypoint independently.

§Trait shape vs the TS sibling

HarnessAdapter is a Send + Sync trait object so the registry can hand out &'static dyn HarnessAdapter references. async fn in trait is mediated by async_trait::async_trait to keep adapter impls ergonomic; the desugared Pin<Box<dyn Future + Send>> matches the shape expected by the burn run driver, which tokio::spawns the result of plan / after_exit and joins them at the top level.

Re-exports§

pub use registry::list_harness_names;
pub use registry::lookup;

Modules§

claude
Claude harness adapter — Rust port of packages/cli/src/harnesses/claude.ts.
codex
Codex HarnessAdapter — Rust port of packages/cli/src/harnesses/codex.ts.
opencode
OpenCode HarnessAdapter — Rust port of packages/cli/src/harnesses/opencode.ts.
pending_stamp
pending_stamp::adapter factory — Rust port of packages/cli/src/harnesses/pending-stamp.ts’s createPendingStampAdapter.
registry
Lazy harness registry — Rust port of packages/cli/src/harnesses/registry.ts.

Structs§

PlanCtx
Driver-side context handed to every adapter call. Mirrors the TS HarnessRunContext shape one-to-one (cwd, passthrough, tags, spawnStartTs) plus the Rust port’s typed ledger-home override.
SpawnPlan
Spawn plan returned by HarnessAdapter::plan. The burn run driver owns the actual tokio::process::Command construction; this struct is the per-adapter contribution to it.
WatcherController
Wrapper around the SDK’s WatchController. Today this is just a newtype so callers don’t have to import relayburn_sdk directly to construct or stop a watcher; tomorrow it gives us a stable boundary to attach harness-side observability (e.g. a name, a per-adapter metric counter) without leaking through to the SDK.

Traits§

HarnessAdapter
HarnessAdapter — five-method contract every harness implements. The TS sibling lives at packages/cli/src/harnesses/types.ts and the shape mirrors it; see the module docs for what each step does.