The Composable Harness

a coding agent assembled at boot from YAML patch layers

deepseek-ai/deepseek-harnessView the repository
LANGUAGE
TypeScript · Node · Cordis
SOURCE LOC
236,248 (+291k tests)
PACKAGES
234 workspace packages
BUILT-IN TOOLS
52 across 24 packages
PROVIDERS
2 adapters · 3 protocols
OS SANDBOX
bwrap+Landlock / Seatbelt / ACL
All 22 blocks

Surfaces & entry

The turn

Tools

Context & memory

Model layer

Safety

Extensibility

State

Isometric plate: the 22 subsystems of DeepSeek HarnessBlocks are grouped into districts by hatching and tint; block height is a rough proxy for code mass. Lines trace the data flow of a single turn. The block index beside this diagram carries the same information as text.ASTVDLGMNFOBHPKICJUQER

Hover to read · drag to pan · ⌘/ctrl + scroll to zoom

How to read this plate

Each block is one subsystem of DeepSeek Harness. Its height is a rough proxy for code mass, calibrated the same way across every harness so the plates are comparable. Hatching and tint group blocks into districts — surfaces, the turn, tools, context, the model layer, safety, extensibility and state.

Lines trace the real data flow of a single turn plus the major supporting links. Pick any block for a plain description and the files it was read from, or trace the turn to walk the path a request actually takes.

What this is

DeepSeek Harness takes "everything is a plugin" more literally than any of the others. The CLI writes an empty root config on every boot — the running system is assembled entirely from YAML patch layers: bundle patches, then a profile patch, then your home patch, then command-line overlays. The tool registry, the agent loop, the session store, the LLM runtime, the sandbox, approval, compaction and every individual tool are all just rows in that config.

The container underneath is Cordis, where services are looked up by name rather than imported. A plugin declares static inject = ['agents','sessions','llm','tools'] and stays dormant until those services exist — load order is derived, never sequenced. Every registration returns its exact disposer, so unloading a plugin mid-flight rolls back cleanly, and hot reload is real.

That buys a genuinely unusual capability: agent presets. A preset is a sub-composition mounted once under a standing scope; a session joins it by parenting its scope key. The web build disables the entire agent plane in the host and lets each session mount its own — so a Code Mode agent, a minimal agent and a full coding agent coexist in one process with different tool sets and different prompts.

The session is an append-only event log and provider requests are a pure function of it. Compaction doesn't delete; it shadows nodes, so replay stays exact. Even a cancelled turn writes synthetic aborted-before-dispatch results so the log never breaks. And the sandbox fails closed: if confinement is unavailable it refuses to run rather than running unconfined.

Implementation

Events. Four typed dispatch modes — emit, waterfall, parallel, serial — with a generated catalog that checks them. Every policy point is a waterfall: tools/pre-execute, agent/pre-step, agent/request, agent/request-error, system-prompt/assemble, llm/stream, fs/edit-intent. Compaction, retry and the Claude-Code/Codex hook bridges are all just listeners.

Sandbox. A probed ladder per platform: bubblewrap then Landlock through a ~300-line static-musl C launcher shipped as npm platform packages (it restricts itself, then execs, so the ruleset is inherited); Seatbelt SBPL on macOS; a restricted-token ACL runner on Windows. The in-process filesystem fence shares the same writable-root helper as the Seatbelt profile so the two cannot drift.

Code Mode. run_code is not a registered tool — it is minted by the tool runtime outside the filterable layers, so it cannot be shadowed or restricted. Under code mode it collapses the wire catalog to itself while a generated TypeScript SDK section describes the rest; programs call tools through bindings that re-enter the full guarded pipeline.

Prompt caching by construction. There are no explicit cache-control breakpoints. Instead requests are deep-frozen and derived from the log, a canonical header ensures the tool catalog only changes when it really changes, plan mode deliberately keeps the catalog identical across modes, and the compaction summarizer replays the conversation's own prefix verbatim.