Skip to main content
Kodelyth ECC
architecture

The Super Agent Is a State Machine That Can't Lie About Its Own State

ECC's new autonomous orchestrator drives a whole objective to done — decompose, dispatch in dependency order, integrate branches, verify — with a control plane that spends zero tokens and is fully testable without running a single agent.

By Kodelyth · · 8 min read

A five-phase state machine — plan, execute, integrate, verify, done — with a tokenless control plane deciding each next action and the LLM performing it. The execute phase loops to dispatch ready steps in dependency order, gated by a budget cap.

The Super Agent is ECC's autonomous orchestrator. You hand it one large objective, and it drives that objective to done — breaking it into a dependency graph, dispatching each step (in parallel where the steps are independent), merging the resulting branches, and verifying the whole thing against a real gate.

The interesting part is not that it runs agents. Plenty of harnesses run agents. The interesting part is what doesn't run a model: the decision of what to do next.

The control plane is tokenless

A naive autonomous loop asks the LLM, every turn, "given everything so far, what should I do next?" That is expensive, non-deterministic, and impossible to test — the thing deciding the control flow is the same stochastic thing you are trying to control.

ECC splits it. A pure function decides the next action; the LLM only performs the action it is told to.

plan ──decompose──▶ execute ──(all steps done)──▶ integrate ──▶ verify ──▶ done
                      │
                      └─ dispatch ready steps (deps satisfied), budget-gated

nextAction(run) is the whole control plane, and it never mutates anything. It reads the run's current phase and returns one of a small, fixed vocabulary of actions — decompose, dispatch, integrate, verify, halt, report. Because it is pure, the entire orchestrator is unit-tested without spawning one agent or spending one token. The expensive part (actually doing the work) and the decision part (what to do) are cleanly separated.

Start a run — with a budget

Everything is driven through one subcommand:

kodelythecc super-agent start --goal "Add rate limiting to the public API" \
  --step-cap 12 --token-cap 60000
{
  "runId": "f3cb152ecd2e",
  "next": {
    "action": "decompose",
    "goal": "Add rate limiting to the public API",
    "scope": "."
  }
}

The caps are not optional in spirit. An autonomous run with no budget is exactly how a bill runs away overnight, so the agent definition tells the driver to always set one. A single per-session token budget cannot bound a run that spans many sessions — so the Super Agent carries its own governor.

Decompose into a DAG

The first action is decompose. The driver turns the goal into a list of steps, each { id, description, deps, exitCriteria }, and installs it:

kodelythecc super-agent plan f3cb152ecd2e --file plan.json

The plan is validated as a real DAG before it is accepted — unique ids, every dependency exists, no self-dependency, and no cycles (Kahn's algorithm: if you can't topologically order every step, there's a cycle). An invalid plan is rejected, not run.

Once installed, asking what's next returns the first runnable step:

{
  "action": "dispatch",
  "parallel": false,
  "steps": [
    { "id": "1", "description": "Token-bucket limiter module",
      "deps": [], "exitCriteria": "unit tests pass" }
  ]
}

Dispatch in dependency order

This is where the DAG earns its place. A step is ready only when every dependency it names is done (or skipped — a skipped step didn't fail). The plan above has steps 2 and 3 both depending on step 1. So after step 1 reports done:

kodelythecc super-agent step f3cb152ecd2e 1 --status done \
  --branch sa/1-limiter --tokens 5200

the next action unlocks both dependents at once, and says so:

{
  "action": "dispatch",
  "parallel": true,
  "steps": [
    { "id": "2", "description": "Wire limiter into HTTP middleware",
      "deps": ["1"], "exitCriteria": "429 on overflow" },
    { "id": "3", "description": "Redis store for distributed counters",
      "deps": ["1"], "exitCriteria": "survives restart" }
  ]
}

parallel: true is the machine telling the driver these are independent — run them concurrently with the Task tool, or in isolated git worktrees via kodelythecc swarm. Each step does its work on its own branch, which is what makes the next phase possible.

A step that fails and that others depend on stalls the run deliberately:

halt — the plan stalled: a dependency failed, so no remaining step can run.

That is the machine refusing to let the driver build on a broken foundation. The agent is told never to fabricate a step result — a step that didn't actually succeed is submitted --status failed, and the machine handles the consequence honestly.

Integrate the branches

When every step is done, the phase advances to integrate, and the action carries the branch list in merge order:

{
  "action": "integrate",
  "branches": [
    { "step": "1", "branch": "sa/1-limiter" },
    { "step": "2", "branch": "sa/2-middleware" },
    { "step": "3", "branch": "sa/3-redis" },
    { "step": "4", "branch": "sa/4-docs" }
  ]
}

Two parts matter here. mergeOrder topologically sorts the branches so a dependency merges before anything built on top of it. And detectConflicts checks whether any two branches would collide without touching the working tree — it uses git merge-tree --write-tree, which computes the merge result as an object and exits non-zero on conflict, side-effect free:

const r = spawnSync('git', ['merge-tree', '--write-tree', branchA, branchB],
  { cwd: repoRoot, encoding: 'utf8' });
if (r.status === 1) return { conflict: true, files: parseConflictFiles(r.stdout) };

Clean → merge in order and report it. Conflicting → don't force it. The driver reports the conflicting files and stops for a human:

kodelythecc super-agent integrate f3cb152ecd2e --conflicts src/app.ts,src/mw.ts

The swarm that fans out but never merges is a common failure in agent harnesses. This is the fan-in, with the one check that keeps a parallel merge from quietly corrupting the tree.

Verify against a real gate

A clean integration advances to verify. This is not a vibe check — it runs the actual tests, build, and type-check (ECC's /verify), and only --passed with evidence moves the run to done:

kodelythecc super-agent verify f3cb152ecd2e --passed --detail "693 tests pass"
{
  "action": "report",
  "reason": "done",
  "run": {
    "status": "done", "phase": "done",
    "progress": { "total": 4, "done": 4, "failed": 0 },
    "budget": { "tokenCap": 60000, "tokensSpent": 18700,
                "stepCap": 12, "stepsRun": 4 }
  }
}

A failed verification sets the run to failed and records the detail. The gate is the last thing standing between "the agent says it's done" and "it's done."

The budget actually halts

Caps are checked before every dispatch. When the step cap or token cap would be exceeded, the next action is halt, not another dispatch:

{ "action": "halt", "reason": "budget: step cap reached (2/2)" }

The driver is told, in plain terms, not to work around the cap. The stop exists on purpose.

It resumes from exactly where it stopped

The run is persisted atomically after every step — a crash mid-write cannot corrupt a resumable run, because the state file is replaced, not edited in place. To pick up a crashed or earlier run:

kodelythecc super-agent list
kodelythecc super-agent next <runId>

next reads the durable state and continues from the exact phase and step where it stopped. Nothing re-plans, nothing re-runs a finished step.

When not to reach for it

The honest limit: for a single-file edit or a 20-line fix, this is overhead. The decompose/integrate/verify machinery pays off when an objective genuinely splits into dependent steps that benefit from parallel execution and a real merge. The agent definition says it outright — not for a single edit or a one-file change. Use debug-detective or pair-programmer for those, and the Super Agent for the objective that is too big for one pass.


The orchestrator shipped in ECC 2.29.0. The state machine, the DAG model, and the branch integration are dependency-free Node in scripts/super-agent, and nextAction is a pure function you can read in one sitting before trusting anything to drive itself.

npm i -g kodelyth-ecc && kodelythecc