Skip to content

[coordination] Supervision graph as configured platform data — hierarchy belongs to the platform, not inside an agent #183

Description

@serge-ivo

Design: docs/supervision.md. Extends #154, which deferred cross-agent work until "a real second consumer beyond Coder" existed — configurable multi-layer supervision is that consumer.

The observation

Coder has a two-level hierarchy: Overseer coordinates across repos → each repo's PilotEngine. The structure is right. It lives in the wrong place — inside the agent rather than in the platform.

Three things hardcode it:

Hardcoded as Where Consequence
Target is a repo drive_claude(repoId, instruction) You cannot delegate to an agent. The type forbids it.
Coordinator is a route POST /:instanceId/coding/overseer Supervision is code, not configuration.
Depth fixed at 2 Overseer → Pilot → Engine, by construction No third layer is expressible.

No table anywhere describes who supervises whom. So supervision cannot be configured, inspected, or reused — every future agent needing a coordinator would rebuild the Overseer.

Supervision is a different edge from choreography

agent_connections (0056) routes an emitted FACT to another instance — deliberately decoupled, a producer must not know its consumers. Correct for the lead chain. Supervision is not that edge:

Choreography (built) Supervision (missing)
Verb emit a fact assign a goal
Addressing producer doesn't know consumer supervisor names the subordinate
Result nothing returns result returns; supervisor is accountable
Failure dead-letter + replay escalate to the supervisor
Shape fan-out tree

Modelling supervision as an event connection would lose the return path and the accountability — the entire point. But both need at-least-once handoff, idempotency and trace correlation, which migration 0058 already provides, so supervision reuses the delivery outbox rather than growing a second reliability mechanism (same argument that re-scoped #17).

Scope

  • Owner-scoped edge: supervisor_instance_id → subordinate_instance_id (both instances belong to one user, as connections already enforce).
  • DAG validation at wiring time — A supervises B supervises A is now reachable by configuration, not just a code bug, and it is an unbounded money-spending loop. Reject at create time, when the human is present.
  • Handoff rides the 0058 outbox; parent trace flows down every hop so a three-level delegation renders as ONE tree (the traceId → child run → chain.link mechanism already built for the pump).
  • Wiring API + validation; console surface tracked with [console] Agent-to-agent connections have no UI — the pump is invisible #182.
  • Depends on [coordination][deferred] First-class delegate(target, goal) registry primitive #156 (generalize delegate target from repoId to a supervisable entity) — that type change is the smallest useful first step.

Acceptance

  • A user can configure instance A to supervise instance B without code.
  • A cycle is rejected at wiring time with a readable message.
  • A delegation survives a transient subordinate failure (outbox retry) and dead-letters visibly when exhausted.
  • A multi-level delegation renders as a single correlated trace.
  • Coder's Overseer is re-expressible in the primitive; the hardcoded route can then come out.

Companions: #184 (budget), #185 (authority containment). Both are cheap to build in now and expensive to retrofit.

Metadata

Metadata

Assignees

No one assigned

    Labels

    backendBackend / Worker / API workcoordinationAgent coordination / delegation primitives

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions