Ensemble · h5i-orchestra

Programmable Agent Orchestration: the h5i-orchestra eDSL

One topology was never going to be enough. h5i team ships a single shape: N agents on one task, a review round, a neutral verdict. h5i-orchestra makes the shape yours to write. A run is a plain async Rust program. Every agent turn is journaled on a Git ref, so a killed run resumes without re-paying a single turn.

Key takeaways
  • A score is define-by-run: the orchestration graph is a trace of what executed, not a graph you build up front. if, for, and tokio::join! are the control flow.
  • Every effectful step is journaled on the team event log (refs/h5i/team/<run>). Resuming replays completed steps from the journal, so agent turns are never re-run.
  • The journal is a Git ref, so a run is shareable and resumable across clones with h5i share push. The handoff is a git push, not a hosted runtime.
  • Agents stay in sandboxed h5i env boxes. The score is host-side code. The eDSL adds orchestration, not a new trust surface.

An agent ensemble has one fixed answer to "what should happen next": everyone attempts the task, the round is sealed, peers review, a verifier decides. That is a good default, and h5i team ships it. But the real space of useful topologies is larger. Sometimes you want a designer agent to hand a plan to two implementers. Sometimes you want three independent attempts ranked in an arena. Sometimes you want one integrator to merge the work of many. Each of those is a different program, and a fixed protocol cannot express them.

h5i-orchestra is that program layer. It is an embedded DSL in Rust: you write an ordinary async function, you are handed a Conductor, and you drive the run by calling methods on it. There is no graph builder. There is no compile() step. The orchestration is whatever your code did, recorded as it ran.

Define-by-run: the graph is a trace, not a prerequisite

This is the one design decision everything else follows from, and it is not a new idea. It is the decision that settled the deep-learning framework wars a decade ago. Theano and early TensorFlow asked you to describe a computation to a smarter executor, then hand it over. PyTorch let you perform the computation and quietly recorded it. The recorded-execution side won on the things that actually matter day to day: errors surface where you wrote the code, the host language is the control flow, and you can drop a breakpoint anywhere.

Agent orchestration is more dynamic and more failure-prone than a training loop, so the lesson transfers with force. In h5i-orchestra, the classic ensemble is a loop you can read:

a score, in ~15 lines
// hire two agents, each into its own sandboxed env
let claude = c.agent("claude").runtime("claude").hire().await?;
let codex  = c.agent("codex").runtime("codex").hire().await?;

// fan-out is just host-language concurrency
let (a, b) = tokio::try_join!(claude.work(&task), codex.work(&task))?;
c.freeze().await?;                       // seal the independent attempts

// cross review, a plain loop
let (ra, rb) = tokio::try_join!(codex.review(&a), claude.review(&b))?;

// neutral verification in a fresh sandbox, then a pluggable verdict
let verified = c.verify([&a, &b]).command("cargo test").await?;
let verdict  = c.judge(verified, policy::tests_then_smallest_diff()).await?;

There is no framework vocabulary here. No executors, no edges, no supersteps. To add a condition, you write an if. To retry, you write a loop. To run two agents at once, you use the concurrency your language already has. The DAG that a reviewer will later want to see is derived from the trace after the fact, with h5i team trace --dot. It is a view over what happened, never a thing you had to construct before anything could happen.

Not a graph engine. Not an actor system. A thin eDSL over a Git event log. The frameworks that asked users to describe computation to an executor lost to the ones that let users perform it and observed the result. h5i-orchestra builds the observed-execution layer and bolts the audit graph on underneath, never in front.

Durability without a server: journaling on a Git ref

A coding-agent turn costs minutes and real money. So the property that matters most in an orchestrator is not speed, it is this: if the process dies at step forty, restarting must not re-run the first thirty-nine. That is durable execution, and the industry has three designs for it. Temporal replays your workflow code against an event history. Restate journals each named step's result and skips it on recovery. Graph frameworks checkpoint at a barrier and re-execute forward, which can re-pay LLM calls.

h5i-orchestra takes the journaling design, because for agent turns it is the only one where a resume is free. Every effectful operation, an agent().hire(), a work, a verify, an arbitrary step, executes once and appends its serialized result to the run's event log at refs/h5i/team/<run>. Each step carries a stable key, label#seq. Re-running the score consults the journal by key: a hit returns the recorded result instantly, a miss executes live and records. Kill the run at any point, run the same binary again, and it fast-forwards through everything already done and picks up exactly where it stopped.

Because the journal is a Git ref, durability costs nothing to operate and it travels. There is no database to run and no checkpoint store to configure. h5i share push moves a live run to another clone. One machine can drive a score up to a human approval gate, a reviewer on a different machine can answer, and either side can resume. The cross-machine handoff is a git push. None of the general-purpose orchestration frameworks can do that without a hosted runtime, because their state does not live in your repo.

resume is free
$ h5i team run fix-auth --task-file task.md --verify-cmd "cargo test"
➜ driving team 'fix-auth': 2 agents, 1 review round
# ...process killed at the verify step...

$ h5i team run fix-auth --task-file task.md --verify-cmd "cargo test"
➜ resuming: 6 journaled steps replay without re-execution
# the two agent attempts and the reviews are NOT re-run: they replay from the ref

The primitives

The surface is deliberately small. A score composes a handful of methods on the Conductor and on the Agent handles it hands you. Everything else is a pattern built from these.

  • c.agent(name)...hire() creates or binds a sandboxed h5i env and enrolls the agent on the roster.
  • agent.work(task) dispatches a work turn and resolves to the frozen candidate. with_materials(&parts) grants it sight of teammates' diffs for integration work.
  • agent.ask::<T>(prompt) returns typed data instead of code: the reply must deserialize as T, so judges and routers are ordinary functions.
  • agent.review / agent.revise drive the peer-review loop.
  • c.verify, c.judge, c.apply run the neutral verifier, decide a verdict through a pluggable VerdictPolicy, and land the winner. Apply stays mediated and human-gated.
  • c.gate(question) is durable human-in-the-loop: it asks over the i5h message bus, and a score can exit and resume after the answer arrives, even the next day.
  • c.step(label, f) is the universal escape hatch: run any side effect exactly once, journaled.

The one discipline the eDSL asks of you is stable step identity: parallel steps must carry distinct labels, so a resume pairs the right recorded result with the right call. Agent operations get this for free, since their labels embed the agent id. For your own parallel loops, Conductor::scope gives each branch its own label namespace, and the journal fails closed if two concurrent steps ever collide on a label. That is the analog of the one constraint PyTorch borrowed from JAX: demand discipline only where it buys something users cannot get otherwise. Here it buys a free resume.

Where this sits

It would be a mistake to sell h5i-orchestra as a better LangGraph or a better Microsoft Agent Framework. Those orchestrate arbitrary in-process LLM calls, they have hosted observability, and they have ecosystems this does not. If you are building a general multi-agent application, use one of them.

What h5i-orchestra owns is the layer none of them touch: the agents are semi-trusted coding agents that need kernel-enforced isolation, their outputs need provenance, their cross-influence needs to be auditable, and their merged result needs a mediated, evidence-gated path back to the main branch. That is not a feature you bolt onto a general framework. It is the substrate underneath, and h5i already had it. The orchestrator is the thin part. The isolated envs, the capture evidence, the neutral verifier, and the Git-native event log are the parts that are hard to build and easy to depend on.

The result is an orchestrator with a different center of gravity. Not "describe a graph to a runtime," but "write a program, and the runtime records it into a Git ref you can share, resume, and audit." The score is yours. The proof travels with it.

FAQ

Do I have to write Rust to use this? No. The CLI drives the common cases: h5i team run executes the full classic cycle over the ensemble pattern, with --rounds, --verify-cmd, --gate, and --manifest team.toml to parameterize it. You reach for a hand-written score when you want a topology the built-in patterns do not cover.

How does the score talk to the agents? Through the same wire an h5i team uses: an i5h message plus a per-env inbox, delivered to a warm resident session that the Stop hook keeps alive between turns. The score is a coordinator, not an LLM client. It holds no model connection and no agent state.

What runs the agents, then? A RuntimeLauncher. The default, Attach, expects a resident interactive session (started by team-launch.sh) to pick the turn out of its inbox. LaunchResident spawns that same warm session itself in tmux. A headless per-turn claude -p is deliberately not the default, because cold boots and stateless turns defeat the resident-session model.

Is the run really reproducible? The journal is. Re-running the same score against the same run replays every recorded step. A changed binary is detected by a recorded score digest and warns loudly, and a patched("change-id") marker lets you upgrade a live run deliberately.

Where is the code? The eDSL is the h5i-orchestra crate; the design and rationale live in roadmap/orchestra-design.md in the repo.

Write your run as a program

Drive a full agent cycle with h5i team run, or write a score for a topology of your own. Every turn journaled, every run resumable.

Read the manual Star on GitHub