Skip to content

Add an Effect composition root and make the agent runtime a service #36

Description

@FreshlyBrewedCode

Parent

#32

What to build

The daemon gets an Effect composition root, and the agent runtime is the first service to move into
it. server/daemon.ts builds a Layer; the agent runtime is resolved from context instead of being
threaded by hand through eight files and roughly twenty call sites (cli.ts → daemon.ts →
ServerOptions → StartTrackedRunOptions → DispatchEnv → startRun → buildAgentStepEffect).

Two concrete outcomes beyond deleting plumbing:

  • The adapter becomes selectable from factory.config.ts. Today "pluggable adapter" is a claim
    the code does not support: there is one production implementation, chosen by a hardcoded
    opencodeAdapter default in two separate places, with no config surface at all.
  • DispatchEnv loses a field. That bag exists to carry environment down a recursive dispatch
    chain; every field removed from it is one less thing a child run has to inherit explicitly.

The agent runtime goes first because its plumbing is the worst in the codebase — it proves the
pattern on the strongest case before #37 applies it to the remaining singletons.

Scope boundary, and it matters: server/http.ts's route handlers and sseStream stay plain
functions over Request/Response/ReadableStream. They read already-constructed services; they
do not become Effects. D22 is reaffirmed, not reopened.

ADRs to update as part of this ticket — both already carry the decision, so this is confirming the
text matches what shipped, and amending it if implementation forced a different shape:
docs/adr/0009-imperative-workflows-effect-boundary.md §5 and the 2026-09-18 status note in
docs/adr/0004-server-dispatch.md. The seam itself is docs/adr/0012-agent-runtime-seam.md §4.

Acceptance criteria

  • The agent runtime is a Context.Service resolved from context, not a value passed through interfaces
  • adapter is gone as a pass-through field from StartTrackedRunOptions, DispatchEnv, ServerOptions and the run/step options
  • The agent runtime is selectable from factory.config.ts, with opencode as the default when unset
  • server/http.ts's route handlers and SSE stream are still plain functions, not Effects
  • Tests swap the corpus-replay runtime by providing a layer, not by threading an option
  • Nested runs still inherit the agent runtime correctly — a grandchild run works
  • ADR 0009 §5 and the ADR 0004 status note match what shipped
  • bun run check passes

Blocked by

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

    taskA single self-contained piece of work that ships as one PR

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions