Skip to content

[coordination] Platform-provided durable agent loop — the Loop is an agent-level primitive, not a browser poll #158

Description

@serge-ivo

Re-scoped 2026-08-04 — un-deferred, and now a precondition for #184

Originally filed as "converge the client-driven Loop into the durable Pilot" — framed as Coder cleanup. It is bigger than that: the autonomous loop is a general agent capability the platform should provide, and today it is half-built in the wrong place.

What is actually true in the code

The platform already owns the thinking:

  • POST /v1/instances/:id/loop-decide lives in routes/instances.tsnot coding.ts — with a pure, tested lib/loop-decide.ts. It is instance-scoped and agent-generic (BYOK Claude decides continue/done/escalate/failed).

The browser owns the persistence:

  • store/console/src/pages/InstanceDetail.tsx polls /loop-decide and sends the next instruction. Close the tab, lock the phone, sleep the laptop — the loop dies mid-objective.

Meanwhile the Pilot (CodingSessionWorkflow) is a durable server-side loop, but Coder-bound and tied to the workflow closed enum (#160).

So there are three overlapping things: a generic decide endpoint, a client-driven driver, and a durable-but-hardcoded workflow. The decide step is already right. What is missing is a durable, generic loop runner that any agent can use, with the Pilot as one configuration of it.

Why this is now blocking, not deferred

You cannot budget a loop you do not own. #184 requires bounding spend on unattended work — but today the Loop runs in the user's browser, so the platform cannot stop it, cannot reliably count its iterations, and cannot reserve against a pool. Every enforcement point #184 needs is on the server side of a loop the server does not drive.

Making the loop platform-owned is therefore a precondition for #184, not parallel work.

It is also a straight UX win

Today closing the tab kills an in-flight objective. A durable loop survives tab close, phone lock, and laptop sleep, and can be reattached from another device. That is an improvement to the current Coder experience, not just plumbing — and it is what makes max iterations (already in the Loop UI) meaningful rather than best-effort.

Scope

  • A durable, generic loop runner at instance level: objective → snapshot → loop-decide → act → repeat, until done / escalate / budget exhausted.
  • The console Loop becomes a thin UI over it — start, watch, interject, stop — rather than a parallel client-driven brain.
  • The Pilot (CodingSessionWorkflow) becomes one configuration of the primitive; Coder keeps its behaviour.
  • Works for non-coding agents too (the Chat-tab Loop already targets these).
  • Budget hooks ([coordination] Autonomous work budget — bound spend across every unattended entry point #184) enforced by the runner, once, for every agent.
  • Interject / stop / resume survive disconnect and are addressable from another device.

Acceptance

Part of #154. Pairs with #160 (retiring the workflow enum makes the loop fully declarative). Design: docs/supervision.md.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    backendBackend / Worker / API work

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions