Architecture overview
The intelligence lives in the harness; the model is a narrow, swappable function. The loop doesn't trust the model's prose — it decides on state and observable effe…
State machine
Every task runs an explicit state machine. It never stays IN_PROGRESS forever: maxSteps, maxWallClock and the stall detector guarantee termination.
PENDING ─► IN_PROGRESS ─► COMPLETE (exitCriteria verified)
├─► BLOCKED (structured reason)
├─► NEEDS_INPUT
└─► FAILED (budget exceeded)Action-or-Terminate
Every turn ends in a tool-call OR a terminal signal (task_complete / task_blocked / need_input). Future-tense text (“I'll”, “let me”) with no action is caught by an intent–action reconciler (PT/EN), rejected and re-prompted: “You said you'd do X but didn't act. Do it now or declare blocked.”
Verified exitCriteria
task_complete only counts if the exitCriteria are met: build passes, tests green, file exists, contract gate. “Done” is the harness's assertion, never the model's alone. Failed? The exact list of what's missing comes back and the agent resumes.
Anti-loop
A weak model loves repeating the same tool and oscillating between two states. The harness detects and breaks it without relying on the model to “notice”:
- Fingerprint + dedup: each call hashes (tool, normalized args); repeated N times → blocked with a nudge.
- Cycle detection: A,B,A,B / A,B,C,A,B,C patterns in the recent window → break.
- Circuit breaker: the same command failing N times with the same error → that approach is forbidden.
- Progress budget: lots of effect, zero progress against the exitCriteria → break.
- Hard ceilings: maxToolCalls per task + per-tool cap.
- Escalation ladder: nudge → re-decompose → escalate to a stronger model → BLOCKED with a diagnosis.
Anti-hallucination
- Mandatory grounding: a claim about the code must be backed by a real observation (read-before-edit). The tool result is the truth, not the model's memory.
- Existence check for a symbol/import/package before using it (anti-slopsquatting).
- Abstention is first-class: “I don't know / need to check” is cheaper than guessing.
- Gates as a filter: build/typecheck catch a hallucinated API/import on the spot.
Capability parity across LLMs
The capability profile (see Providers) parameterizes decomposition, tool-call mode, context per step, self-consistency and retries. The result trends toward parity because the harness supplies what the model lacks — the quality floor is in the verifier, not the model.
Lifecycle of a task
- Message → gateway → profile+workspace, with the agent's identity and the active LLM's capability profile.
- Router selects skills (contract-forced or on demand) and injects taste if the task is UI.
- Harness enters IN_PROGRESS; action required every turn; watchdog and anti-loop active.
- task_complete → gates (hard) + taste critic (soft). Failed? back to the violations.
- COMPLETE → reply to the channel; post-task, learning distills a skill/rule and proposes persona/taste evolution.

