Certified Agent Harness Engineer
Course sections

M1.5

Topologies and what each constrains

574 words · about 4 min

Concept

The same loop deployed in a different shape has different obligations. Five shapes dominate, and the axes that distinguish them are: who is present (interactive human, or nobody), where effects land (local machine, container, or remote host), and who owns the transcript.

The five topologies

CLI. The loop runs in a terminal on the developer's machine. Effects are local and immediate; the user is present, so interactive approval is available; transcript lives on disk. Constrains: the process is the session — crash and you must resume from a log. Single-user assumptions get baked in everywhere.

IDE extension. The editor hosts a UI; the loop typically runs in a separate process or a language-server-like sidecar. Constrains: everything must be async and cancellable because the UI thread cannot block; you inherit the editor's notion of workspace and open buffers, which may disagree with disk — a real source of bugs when the model reads a file the user has unsaved edits in.

Headless / CI. No human. Runs to completion or fails. Constrains: this is the topology that forces you to answer "what happens when approval is required and nobody is there?" The only safe answers are deny or pre-approve a narrow policy; a harness that defaults to "allow when non-interactive" has converted its permission system into decoration. Also: no streaming UI, so all observability must come from the log.

Server / BFF. The loop runs on a server; browsers connect. Constrains: multi-tenancy (sessions must be isolated), authentication, and the hardest one — effects now land on a shared machine, so filesystem and shell tools must be confined per session or the topology is a vulnerability.

ACP-style automation. The harness speaks a protocol (Agent Client Protocol and similar) so an external client drives it. Constrains: the protocol becomes a compatibility surface you must version; and because the driver is another program rather than a person, "ask the user" has to be expressed as a protocol request the client may decline.

Worked example

dsh materialises topologies as bundles: packages/bundle/base, packages/bundle/headless, and packages/bundle/web-app. docs/architecture.md describes the layering — bundles compose into a profile, then a profile patch, then a home patch, then a --patch overlay. packages/acp/acp provides an automation-only Agent Client Protocol server. The load-bearing property is that these differ in which plugins are registered, not in which loop runs: the loop is one package — docs/capability-seams.md describes ctx.agentLoop as "the one concrete loop plugin," and notes that extension packages depend on dsh-agent events and services rather than on that package. The failure prevented is topology forks — a headless variant that quietly drifts from the interactive one until a bug is fixed in only one.

Tradeoffs

One loop across all topologies forces every feature to be expressible as configuration, which is more design work per feature. Separate implementations per topology are faster to write and guarantee divergence. Nearly every mature harness has converged on the first.

How others differ

Claude Code's CLI and IDE extension share a process model, with the extension as a client onto the same engine — the same anti-fork instinct. Codex CLI's local-exec model ties the loop tightly to the developer's machine and gets simplicity in exchange for a harder path to a hosted variant. Protocol-level seams — ACP for client/agent, MCP for tool/server — are the industry's current answer to interop, and both are young enough that "what belongs in the protocol" is genuinely unsettled.


Check yourself

2 questions on M1.5

Start drill