Skip to main content
Kodelyth ECC
pillar

Autonomous Agent Orchestration — The 2026 Reference

Complete reference for autonomous agent orchestration: the five hard problems (decomposition, dispatch, integration, verification, budget), the tokenless state machine pattern, dependency DAGs with cycle detection, git merge-tree conflict checking, resumable runs, and honest comparison to LangGraph, AutoGen, CrewAI, and OpenHands.

By Kodelyth · updated · v2.30.0

Autonomous Agent Orchestration

Orchestrating an autonomous agent to drive a non-trivial objective is harder than it looks from the first prototype. Five problems intersect — decomposition, dispatch, integration, verification, and budget — and most frameworks handle one or two cleanly. This is the 2026 reference: the problems, the patterns that solve them, the shipped tools, and the honest comparisons.

The five hard problems

Any orchestrator worth using has to answer these five, and the wrong answer on any one of them sinks the run:

1. Decomposition

Break the goal into steps. Each step needs:

  • A clear exit criterion (how do we know this step succeeded?)
  • An honest dependency on earlier steps (what must land before this can start?)
  • Enough context brief that a fresh agent can execute it cold (no implicit knowledge of the whole plan)

Bad decomposition shows up as: steps that depend on things the plan didn't capture, steps that can't be verified, or one giant step pretending to be three.

2. Dispatch

Run the steps. For a linear plan this is trivial; for a DAG it means:

  • Identify the ready set — steps whose dependencies are all complete
  • Launch them in parallel, each on its own branch (or sandbox) so they don't fight
  • Collect their results as they finish

Bad dispatch shows up as: sequential execution of work that could have run in parallel (wasted wall-clock), or parallel execution without branch isolation (two agents editing the same file).

3. Integration

Merge the parallel results. This is where most hand-rolled orchestrators die. A clean integration needs:

  • A merge order that respects the DAG (dependents merge after their dependencies)
  • A conflict pre-check that doesn't touch the tree — git merge-tree --write-tree is the right primitive
  • A stop-on-conflict behaviour that reports the conflicting files and waits for a human, instead of forcing the merge or silently discarding one side

Bad integration shows up as: silently discarded work, false success reports, or runs that destroy clean state when a conflict appears.

4. Verification

Know when it actually succeeded. "The last step returned OK" is not verification. Real verification is:

  • A gate that runs the actual check (tests, build, type-check, lint)
  • A binary pass/fail result with evidence the human can inspect
  • A refusal to self-report success when the gate didn't run or failed

Bad verification shows up as: the orchestrator declares the run done, and nothing works.

5. Budget

Stop before cost runs away. A real budget is:

  • A step cap or token cap chosen before the run starts
  • A hard halt when the cap is reached — no "just one more step"
  • A honest cost ledger the user can inspect after

Bad budget shows up as: $140 overnight run that produced nothing usable.

The pattern that solves all five: tokenless state machine

The breakthrough pattern — not original to ECC but underused in the ecosystem — is to put the control flow in deterministic code and the work in the agent. The LLM decides how to write a function; it does not decide whether the run is done. Concretely:

┌─────────────────────────────────────────────────────────┐
│  CONTROL PLANE — deterministic, tokenless, resumable    │
│                                                         │
│  State:  { runId, plan: DAG, step_statuses, budget }    │
│                                                         │
│  nextAction(state) → one of:                            │
│    • decompose    — use agent to produce DAG            │
│    • dispatch     — tell agent which steps are ready    │
│    • integrate    — merge completed branches            │
│    • verify       — run the real gate                   │
│    • halt         — budget hit                          │
│    • report       — done                                │
└──────────────────┬──────────────────────────────────────┘
                   │
                   ▼
┌─────────────────────────────────────────────────────────┐
│  AGENT — does the work the control plane dispatches     │
│  Reports back: step completed, failed, evidence         │
└─────────────────────────────────────────────────────────┘

Three consequences fall out of this split:

  1. Reproducibility. Same state → same next action. Debuggable without replaying expensive LLM calls.
  2. Resumability. The state is a file. A crash loses nothing beyond the step in progress.
  3. Budget safety. The control plane sees every transition; the budget check is one if-statement, not a plea to the LLM.

This is what ECC's Super Agent implements as scripts/super-agent/ — the full architecture is in the doc, with the DAG cycle detection in dag.js, the state store in state.js, the orchestrator loop in orchestrator.js, and git merge-tree conflict detection in integrate.js.

Dependency DAG decomposition in practice

The decomposition step produces a graph that looks like:

[
  { "id": "s1", "deps": [],            "contextBrief": "Design the rate-limit schema...",     "exitCriteria": "schema.sql + Zod type" },
  { "id": "s2", "deps": ["s1"],        "contextBrief": "Implement middleware against schema", "exitCriteria": "tests/middleware.test.ts passes" },
  { "id": "s3", "deps": [],            "contextBrief": "Implement login handler",             "exitCriteria": "handler + integration test" },
  { "id": "s4", "deps": ["s2","s3"],   "contextBrief": "Wire middleware into handler",        "exitCriteria": "e2e test passes" },
  { "id": "s5", "deps": ["s4"],        "contextBrief": "Load-test at 100 RPS",                "exitCriteria": "report at .orchestration/.../load.md" }
]

Two things to notice:

  • contextBrief is written for a fresh agent. The agent executing s2 does not get the full plan; it gets the brief. That means briefs must carry everything needed to execute cold. This is a quality bar: if you can't write the brief, the decomposition is wrong.
  • deps are honest. s2 and s3 have no dependency; they run in parallel. s4 depends on both; it waits for both to finish and verify.

The orchestrator's ready-set is computed from the deps + statuses. In a well-decomposed plan, the ready-set is often multiple steps — parallelism falls out of honest deps, not a parallel-at-all-costs flag.

Conflict-safe integration with git merge-tree

The right primitive for a conflict pre-check is git merge-tree --write-tree, which produces a tree object representing the merge without touching your working tree. Exit code 0 means clean; exit code 1 means conflict.

git merge-tree --write-tree --merge-base=main <branchA> <branchB>
# exit 0 = clean merge possible
# exit 1 = conflict; stderr enumerates the conflicting paths

This matters because the alternative — just git merge and see what happens — leaves the tree in a half-merged state when it fails, which an autonomous orchestrator has no clean way to recover from. With merge-tree, the orchestrator checks before touching; if clean, proceed; if not, stop and report.

ECC's scripts/super-agent/integrate.js wraps this: mergeOrder(plan) computes the DAG-respecting merge order; detectConflicts(order) runs the pre-check. A failing conflict check emits the paths and the run halts with action integrate --conflicts path/a,path/b.

Verification gates that don't self-report

A real verification gate is:

  • Separate from the agent that did the work. The agent that wrote the code doesn't grade its own output.
  • Runs the actual check. Tests, build, type-check, lint — whichever are defined for the project.
  • Reports with evidence. "693 tests pass (output: ...)" not "verification passed."

ECC's Super Agent requires an explicit verify --passed --detail "..." from the operator; the control plane cannot mark a run passed without that operator action, and the operator is expected to have run /verify (ECC's gate command) first. If tests failed, --failed --detail "..." is the honest submission — the run is marked failed and does not propagate downstream.

Budget governance — the one if-statement

The budget check is dead simple when the control plane sees every transition:

function nextAction(run) {
  if (run.stepCount >= run.budget.stepCap) return { action: "halt", reason: "step cap reached" };
  if (run.tokenCount >= run.budget.tokenCap) return { action: "halt", reason: "token cap reached" };
  // ... rest of the state machine
}

The hard part is not writing the check — it's committing to stop when it fires. An orchestrator that lets the agent argue past the cap doesn't have a budget; it has a suggestion. ECC's Super Agent treats halt as terminal; the run status flips to budget-exhausted and the operator decides whether to raise the cap and resume or stop entirely.

Honest comparison to other orchestration frameworks

Different projects live at different layers of the stack. Not competitive; you often want more than one.

ProjectLayerLanguageYou writeYou get
ECC Super AgentShipped orchestrator you invokeCLIA goal in natural languageA run through the full 5-problem loop
LangGraphFrameworkPythonGraph of nodes + edges + stateA framework for building orchestrators
AutoGenFrameworkPython / .NETConversation loops between agentsA framework for agent-to-agent conversations
CrewAIFrameworkPythonRole-based teams, tasks, processesA framework for role-based orchestration
OpenHandsEnd-to-end autonomous engineerPython agent in a sandboxA taskA sandboxed autonomous run
TemporalDurable workflow engineGo / Python / TS / JavaWorkflows + activitiesGeneral-purpose durable execution (not AI-specific)

Combination patterns:

  • LangGraph consuming ECC's catalog via MCP — your LangGraph nodes call recall_memory, route_intent, and specialist tools from ECC through the MCP server. LangGraph owns the graph; ECC provides the specialists.
  • ECC Super Agent dispatching to specialist agents inside your IDE — the orchestrator in scripts/super-agent/ drives the loop; each dispatched step runs as a specialist agent (code-reviewer, debug-detective, etc.) in your interactive AI tool.
  • OpenHands + ECC — run OpenHands overnight on a well-specified task; use ECC in your IDE the next morning for the specialist review.

When autonomous orchestration is the wrong answer

  • Single edit, one-file change, quick fix. Just do it, or call the specialist directly. Orchestration overhead buys nothing.
  • No real internal dependencies. A parallel swarm (one agent per independent subtask) is lighter. ECC ships /swarm for exactly this case.
  • Task that needs tight human feedback at every step. Autonomous means the human reviews after; if you want to steer every move, interactive specialist work is faster.
  • Budget for an unattended run isn't worth the time saved. A $50 overnight budget for a task you can finish in an hour of interactive work tomorrow isn't a win.

Honest limits of ECC's Super Agent specifically

  • Beta. Working, resumable, budget-safe — but the UX around resume + budget raise is still rough. Expect to use the CLI not the slash command for recovery today.
  • Quality of the decomposition is still the agent's job. The control plane is deterministic, but if the DAG the agent produces is wrong, the parallelism and integration are optimising for the wrong thing. We lean on the blueprint skill to constrain this.
  • Parallel dispatch wants a clean working tree. The orchestrator branches off whatever is checked out. Dirty working tree → undefined behaviour.
  • Coordinates work; does not replace specialists. Super Agent dispatches to the existing debug-detective, code-reviewer, etc. It's not a new model; it's a new control loop over them.

Related reading

One-command start

npm i -g kodelyth-ecc
kodelythecc --target claude-code
# Then in your AI tool:
# /super-agent build a rate-limited login API with tests

The orchestrator takes over from there. Resume a crashed run with kodelythecc super-agent list → super-agent next <runId>.

Last updated: 2026-11-11T00:00:00.000Z · v2.30.0