DEV Community

Cover image for DeepSeek Harness Is Open Source: Everything Is a Plugin
Hunter G
Hunter G

Posted on

DeepSeek Harness Is Open Source: Everything Is a Plugin

DeepSeek Harness Is Open Source: Everything Is a Plugin

Half a day after DeepSeek V4 Pro shipped, DeepSeek Harness (developer preview) went open source.

My first reaction after reading the repo structure: this isn't another Codex. It's a breadboard.

Over 230 workspace members. Filesystem, terminal, subprocess, PTY, language servers, web access, skills, subagents, workflows, plan mode, session persistence, settings, credentials, telemetry — almost every capability gets its own package.

If a typical agent project is a pre-assembled computer, Harness is a very large breadboard: models, tools, UI, storage, security policy and context management can all be plugged in — and pulled back out.

We build agent orchestration and a model gateway ourselves, so I read this repo with a very specific question: which of these designs should we copy tomorrow? Here's what I took away.

The name "Harness" is exact

A detail worth pausing on: why call it a Harness.

The word originally means tack, a wiring loom, a restraint device. Abstracted: it connects power to a mechanism that can do work, while keeping that power from running loose.

Applied to AI, the harness connects the model to the filesystem, shell, code editor, web and other agents — while recording what it did, constraining what it can do, and deciding on failure whether to retry, cancel, compact context, or hand the problem back to the user.

The naming is itself a judgment: the model is the horse, not the car. You don't need it to run faster; you need what it's pulling to actually arrive.

That also explains the code volume. Just three questions — can tool calls run in parallel, does cancel actually kill the subprocess, do tool results pollute the context — are enough to justify a pile of packages.

Everything is a plugin, including the agent loop

The project sits on the Cordis microkernel. A running Harness is essentially a Cordis Context: packages register services, events and capabilities into it, and a config file composes them into a working agent.

packages/core/ holds Session, System Prompt, Tools, Agent and Agent Loop. Around it sit capability packages: llm/ for model adapters and streaming, shell/ subprocess/ terminal/ for one-shot commands, process trees and persistent terminals, fs/ for file IO and policy limits, lsp/ to give the agent semantic code navigation rather than text search, web/ for search and fetch, skill/ for reusable skills, subagent/ and workflow/ to extend one agent into a delegating, orchestrated system.

But the part that made me stop is the three-layer split: interface, implementation, consumer.

Take Bash. The interface defines what "execute a command" means. The local implementation actually spawns the process. The model-facing tool package turns that capability into a schema and results the model can understand.

If local shell later becomes a remote container, cloud sandbox or enterprise execution platform, you only replace the implementation layer — you don't rewrite the model tools or the agent loop.

This one lands directly for us. The most painful thing about running a gateway is that "swap an upstream" usually means touching business code. What this split says is: defining a capability, implementing it, and presenting it to the model are three different jobs. Don't write them in one place.

One config file assembles completely different products

Plugin architecture lands in cordis.yml: plugin names, stable IDs, parameters — determining which capabilities the current agent has.

The same codebase becomes very different products. Add an LLM adapter, filesystem, Bash and TUI and you get a terminal coding agent. Swap the UI for the web plugin and you get a browser app. Use the headless entry and it takes a task, completes model and tool turns, prints the answer and exits. Put an ACP or JSON-RPC front door on it and it becomes an automation service other programs drive.

Config supports overlay layers — TUI and Web UI share a base config and stack their own UI plugins, with personal config last.

One gotcha worth recording: a config patch replaces the target plugin's entire config. It is not a deep merge. Write one new field and the existing API key, base URL or other params may vanish with it. The behavior is explicit, but it does not match a first-time user's intuition. I'd bet this becomes the highest-frequency class of issue.

The agent loop isn't a loop, it's traffic control

Most early agent projects reduce to a few lines: send messages to the model, execute any tool calls, send results back, repeat until text.

Harness does that too, but splits it into a strict lifecycle. A user input opens a Turn; a Turn contains multiple Steps; a Step maps to one model request and its subsequent tool execution. Before the request it assembles the system prompt, runtime environment, tool schemas and session messages. After it, streaming chunks, complete messages, tool calls, tool results and finish reasons all enter the event stream.

Tools aren't "get the function name, call it" either. Each passes through pre-policy, an irreversible safety guard, execution, post-processing, content normalization and result notification. A tool can declare that calls under certain parameters are concurrency-safe, so the scheduler parallelizes consecutive read-only work; anything that mutates state or can't be proven safe becomes a barrier and runs exclusively after prior work drains.

The original piece has a line I like: this looks like installing air traffic control on a country road. But once an agent is searching ten files, running tests, and accepting new user instructions with cancel-at-any-time, these rules move quickly from "over-engineered" to "the thing you wish you'd had, according to the incident report."

I agree completely, because nearly every pit we've fallen into lives at this layer. A user types something mid-run — is that the next task, or a course correction on the current one? Harness distinguishes queued messages, injected context and steering, and uses receipts to confirm whether a given steering instruction actually made it into a specific model request.

It doesn't just care that the message was received. It cares which step the model saw it at. Anyone who has built agents recognizes that difference immediately.

Session log is the authoritative source, not a chat transcript

This is the single design I'd most want to copy.

The rule: anything the model saw must be reconstructable from the log.

User messages, runtime context, model request info, streaming output, tool calls and results, compaction events, permission switches, cancellation reasons — all enter an append-only session stream as events. UI, persistence, resume, fork, telemetry and replay don't each maintain their own "roughly correct" state; they all derive from one event source.

It solves the hardest question in agent systems: when a run goes wrong, can we actually know what the model was looking at?

If you only store final chat text, the important factors are gone. Maybe workspace state was injected right before the request. Maybe tool results were truncated. Maybe model routing switched automatically. Maybe the user changed direction mid-stream.

This matters enormously for gateway work. We published an evaluation earlier: the request said kimi-k3, the response self-reported kimi-k2.7-code. It answered the question correctly, but the identity was wrong. Without a log that can reconstruct the scene, you never find that class of problem — let alone assign responsibility after the fact.

Session persistence is itself a plugin, with JSONL and SQLite backends. Resume continues the original session; fork derives a new one from a definite historical boundary.

Four presets are the clearest productization of "everything is a plugin"

The Web UI ships four agent presets. They aren't four separate agents, and they aren't prompt-style changes — they're the same Harness host loading different tools, prompts and runtime capabilities into a session.

Standard is the full coding agent: file editing, shell, search, skills, plan, goals, subagents and workflows.

PTC keeps everything but presents tools via the Code Mode SDK — the model writes TypeScript and composes multiple steps inside one run_code, cutting round trips on long call chains.

Minimal gives exactly two tools: persistent Bash and str_replace_editor. A smaller tool set means less selection and context burden, suited to well-defined tasks where you want the agent to just act.

Creative adds runtime inspection, temporary plugin experiments and preset authoring — the agent can explore and recompose its own runtime.

The most informative one is minimal. It proves something backwards: more tools isn't better; a large tool set is itself a context burden. We all feel the urge to hand agents "a few more tools just in case." Here, giving fewer is shipped as an official preset.

The agent can inspect and even modify itself

Behind creative mode is a set of self-referential Cordis tools: the agent can inspect the running plugin tree and dynamically mount or unmount temporary plugins.

That sounds like swapping an engine while the car is on the highway, so it isn't on by default.

What I find more notable than the capability is the handling: dynamic plugins still run under Cordis Context and Effect semantics, with explicit cleanup paths for registrations. Self-modifying agents easily degenerate into demos; Harness at least put it inside an existing plugin lifecycle.

Security as a system constraint, not a confirm dialog

Once a coding agent has filesystem and shell access, it can modify code, install dependencies, start processes and touch the host beyond the workspace.

Harness treats this as infrastructure, not a checkbox. The default is workspace-write, confining execution and file changes to the workspace and permitted temp dirs, with an ask approval policy for escalation. A looser danger-full-access exists, but the deployer must choose it explicitly. It isn't packaged as a harmless-looking compatibility option.

Three details struck me as unusually professional:

An operation refused by a guard cannot be re-permitted by a later plugin. That closes the "route around it" path.

Filesystem, Bash and subprocess share one sandbox policy. No split boundary where "commands are restricted but file tools go around them" — which is precisely the shape of the recent OpenAI–Hugging Face incident, where the model had no internet but the package service it could call did.

It fails closed. If the system can't confirm isolation is actually in effect, it refuses to run rather than quietly degrading to unprotected execution.

That last one deserves emphasis. Most systems, when uncertain, choose "start anyway." This one chose "stop." Given that the agent can really operate your machine, that default says more about the team's judgment than any security feature list.

Three things I'm taking away

On SDK versus product. Looking only at the Web UI, it's easy to read Harness as DeepSeek's Codex. But the repo's center of gravity is replaceable capability interfaces, an event-driven lifecycle, an authoritative session log and declarative composition — the finished agent is the SDK's first customer. That's a fundamentally different product thesis, and it sets the ceiling.

On the division of labor between model and harness. The model sets the intelligence ceiling; the harness determines how that intelligence enters a real environment, uses tools, retains state and works inside permission boundaries. For enterprise developers, the latter usually matters more than a few extra buttons in a chat window, because it decides whether the system can be audited, extended, replaced and maintained.

And the one worth sitting with: it redefines three things we take for granted. An agent shouldn't be an ever-fattening loop but a set of composable, observable, replaceable capabilities. A session shouldn't be a chat log but a record of what actually ran. A tool shouldn't be a function but something that also carries policy, logging and a presentation protocol.

I'm putting those three sentences at the top of our own agent orchestration design doc — because what we wrote before is the opposite on all three counts: loops that kept growing, logs that only stored chat, tools that were just functions.

So the thing worth watching isn't whether Harness replaces the coding assistant you use today. It's that it turned "how do you build an agent" from writing code into assembling blocks.


Source: Jiqizhixin, "DeepSeek Harness Goes Open Source: Everything Is a Plugin." Repo: github.com/deepseek-ai/deepseek-harness. Cordis design paper: github.com/cordiverse/paper. Technical details per the original article and official repo; hands-on results cited are Jiqizhixin's preview testing, not ours.

Top comments (0)