Iman Suherman — Building solutions. Delivering impact.

Articles

Agent On Rails: stop forever-loops without babysitting the terminal

We approved AOR-006 and AOR-009: intelligent model escalation, environment watchdogs, engine-owned task state, and a durable run report — then published the same story on the product site.

7 min read
Agent On RailsAI deliveryGovernance

Coding agents are powerful. They are also good at wasting a night: fixing the same rejection fifteen times, or sitting on a hung npm/Gradle step while nobody is watching. Agent On Rails exists so delivery stays on rails — specs as authority, evidence before done, humans on the merge gate.

The dogfood problem

Two failure modes kept showing up while we dogfooded Agent On Rails on itself and on real multi-repo work:

  • False forever-loop: five fix↔review cycles that each fixed a different bug get killed as “max attempts,” even though that is normal delivery.
  • True forever-loop: the same model keeps “fixing” the same rejection while operators are offline.
  • Environment stuckness: disconnected device, hung Gradle, hung npm — and a smarter model does nothing useful.

What we approved

After a backend review of the CLI, engine, runtime, and control plane, we turned the findings into an approved control-plane contract — not more silent prototype code. Specs AOR-006 (model escalation) and AOR-009 (unattended AI Team runtime) are now status approved on main.

Intelligent escalation (Option A)

Agent On Rails decides the loop verdict from failure signatures — not from a blunt attempt counter.

  • Distinct bugs across cycles → normal_progress (safe even at 5+ cycles).
  • Same stuck signature → forever_loop, then climb the model ladder: tier 1 → 2 → 3 → human.
  • The same-signature strike max is only an extra safety ceiling — not the primary stop.

Watchdog: environment is not a model problem

  1. 01Detect stuckness (timeout / no heartbeat).
  2. 02Notify the human promptly.
  3. 03Stop the stuck step; mark blocked_environment.
  4. 04Continue independent ready work.
  5. 05When the wave is idle, emit a run report — HUMAN_REQUIRED only if blocking acceptance remains.

Command classification is specific-first: ./gradlew test is a test timeout, not a five-minute device timeout just because the binary is gradlew.

Run report and engine-owned state

Every orchestration wave must produce a durable run report humans can read without replaying agent logs. Required keys (empty arrays allowed; omitted keys invalid):

run_report:
  spec_id: AOR-00N
  terminal_status: final_review | human_required | in_progress
  completed: []
  blocked_environment: []
  skipped_due_to_deps: []
  coding_failures: []
  human_actions_needed: []
  notifications_sent: []

The engine is the sole author of that report. Callers register tasks (POST /v1/tasks), run them, and post events — they do not reconstruct escalation counters.

Phase 1 vs the full AI Team

The backend already has strong decision pieces (escalation decide, watchdog concepts). Phase 1 makes those pieces coherent: Gradle classification, shared task API, persistent history, Option A semantics, full RunReport. The full Manager loop (implementor ↔ reviewer ↔ fixer without manual chaining) is Phase 2+ — still governed by the same approved specs.

On the marketing site

  • Home and docs now explain Option A escalation, watchdog env semantics, and run reports.
  • Specs range on the docs page is AOR-001 … AOR-009.
  • Hero downloads: macOS (.dmg), Windows (.msi), Linux (build-from-source docs) — each with an icon.

Links

What comes next

  1. Implement Phase 1 in engine, runtime, and CLI against the approved contract.
  2. Prove unattended happy path and env-block + continue-independent fixtures.
  3. Keep FINAL_REVIEW / merge human-only — agents prepare; people decide.

Bottom line: Agent On Rails is not “another chat IDE.” It is a governed delivery system. This week we made the escalation and watchdog contract explicit, approved, and public — so the next implementation work has rails to stay on.

← All articles

Agent On Rails: stop forever-loops without babysitting the terminal · suherman.net