DeepSeek Harness Explained: What Does “Everything Is a Plugin” Mean?
“Everything is a plugin” is a claim about architecture, not a feature list. It says the agent loop itself is replaceable — and that is expensive to mean.

Key topics
“Everything is a plugin” is a claim about architecture, not a feature list. It says the agent loop itself is replaceable — and that is expensive to mean.
Most agent frameworks have a load-bearing wall. The loop lives in the core; you extend around it. DeepSeek Harness, an open-source agent runtime released under MIT and currently in developer preview, makes a stronger claim: the model adapter, the tool registry, the session log, and the agent loop are all plugins, and there is no privileged core to patch. The slogan is easy to print on a README. The architecture it implies is not.
This article audits that claim. What does it actually commit the system to? Which parts are swappable? How do plugins find each other? What happens at load and unload? And where does the design bite under real use?
The Slogan Is a Claim About the Core
Read the phrase literally and it becomes falsifiable. If everything is a plugin, then no component is exempt from replacement — including the piece that decides when to call a model, when to run a tool, and when to stop. That is the agent loop, and in most frameworks it is the thing you fork when you want to change it.
The weaker reading, which most frameworks satisfy, is a fixed core with an extension surface bolted on. Tools are pluggable. Models are pluggable. The loop is not. You get a plugin folder, not a plugin architecture.
The test that separates the two readings is one question: can you replace the agent loop itself without forking the runtime?
That question matters because the loop is where the interesting behavior lives. It controls turn structure, retry policy, tool-call parsing, subagent scheduling, and termination. If the loop is fixed, every experiment that touches those decisions requires a patch against the core — and every upstream change becomes a merge conflict. If the loop is a plugin, the same experiment is a configuration change, and you can run two loops side by side against the same task and compare traces.
A swappable loop changes what you can benchmark, debug, and migrate. It also changes what you can break, which is the part the slogan tends to leave out.
Knowledge check
Check your understanding
Answer this question before you continue.
Capabilities as Plugins: What Actually Gets Swapped
“Everything” is too vague to act on. The useful version is a named list of capability categories, each with multiple shipped implementations selected in configuration rather than code.
| Category | What it controls | Example swap points |
|---|---|---|
| Models | Which model adapter serves requests | Provider adapters |
| Tools | What the model can call | Tool registry entries |
| Skills | Reusable prompt or workflow units | Skill packages |
| Sessions | How conversation state persists | JSONL, SQLite backends |
| Sandboxes | Where code executes | Local executor, E2B sandbox |
| Storage | Where artifacts live | Backend selection |
| Loops | Turn structure and control flow | Agent loop implementations |
| Scheduling | Subagent and task orchestration | Subagent providers |
| UI | How the runtime is driven | Browser UI, headless, terminal |
The concrete swap points are the tell. Session persistence has more than one backend. Subprocess execution has a local executor and a sandboxed one. Shell access has variants. These are not abstractions in a diagram; they are choices you make in a config file, and the runtime picks the implementation.
Two qualifications matter here. First, the table shows current shipped implementations, not the full architectural contract. The categories are the extension points; the specific backends are examples that can change as the project iterates. Second, the slogan blurs a distinction that determines what you actually get:
- A capability plugin adds behavior the harness did not have.
- A configuration choice selects among behavior that already exists.
Swapping your session backend from JSONL to SQLite is a configuration choice. Writing a new backend is a capability plugin. Both are legitimate, but only one of them is extension. If you confuse the two, you will overestimate how much the harness gives you for free and underestimate how much interface design you still owe.
The practical consequence: swapping a capability is a config change, but the interfaces between capabilities become your real API surface. That surface is what you are actually betting on when you adopt the harness.
Knowledge check
Check your understanding
Answer this question before you continue.
The Kernel, Services, and Events: How Plugins Find Each Other
“No privileged core” does not mean no core. It means the core is small enough to be boring.
DeepSeek Harness is built on Cordis, a plugin framework whose kernel manages mounting, unmounting, and dependency resolution. Agent capabilities live outside that kernel. The kernel does not know what a tool is. It knows how to load a plugin, resolve what that plugin depends on, and unload it cleanly.
Plugins cooperate through two runtime coordination mechanisms rather than through direct imports:
- A service registry, where a plugin publishes a capability that other plugins can consume.
- An event bus, where a plugin emits or listens for lifecycle and runtime events.
This is the part the slogan hides, and it is the part that determines whether the architecture works. If plugins imported each other directly, you would get a static dependency graph — easy to read, impossible to hot-swap. By routing cooperation through services and events, the harness buys composability.
It pays for that composability with traceability. You cannot read the call graph from the source tree. When plugin A calls plugin B, the connection exists at runtime, resolved through the registry. That is a real cost, and it shows up the first time you debug a composition bug.
Dependency declaration is what keeps load order deterministic. A plugin that declares what it needs can be mounted after its dependencies. But declared dependencies order framework-managed registration; they cannot make arbitrary side effects safe. A plugin that writes to a file or a database during mount has effects the kernel cannot sequence or revoke. That is your responsibility, not the framework's.
The kernel is not the product. The kernel is the contract that lets the product be replaced.
Knowledge check
Check your understanding
Answer this question before you continue.
Lifecycle: Mount, Register, Revoke
This is where plugin architectures quietly fail, so it deserves its own section.
Registration is scoped to the plugin. When a plugin mounts, it registers its tools, services, and event handlers. When it unmounts, those registrations are revoked automatically. The harness does not ask the plugin to clean up after itself; it removes what the plugin registered.
That automatic revocation is the difference between a hot-swappable system and a system that appears hot-swappable until you swap something twice. Leaked tool registrations and stale event handlers are the classic failure mode. A tool that was unloaded but still appears in the registry will be called, and it will fail in a way that looks like a model problem rather than a lifecycle problem.
The distinction between framework-managed and external state is the one to internalize:
| State type | Managed by | On unmount |
|---|---|---|
| Tool registrations | Harness registry | Revoked automatically |
| Service publications | Harness registry | Revoked automatically |
| Event handlers | Harness event bus | Revoked automatically |
| Files written by plugin | Plugin | Must be cleaned up explicitly |
| Database rows | Plugin | Must be cleaned up explicitly |
| External service state | Plugin | Must be cleaned up explicitly |
Hot-swap is also an evaluation tool, and this is the use I would reach for first. Change one capability, rerun the same task, compare traces. Because the session log records what the model saw, you can attribute a behavioral difference to the swap rather than to noise. That is a cleaner experiment than most agent evaluation setups allow.
But “identical scaffolding” is a claim you have to earn. For a fair comparison, hold constant or record: initial state, capability set, model parameters, event schema version, and termination policy. If any of those drift between runs, you are measuring the drift, not the swap.
The cost is state. Automatic revocation covers what a plugin registered through the harness. It does not cover what a plugin wrote outside that system. If your plugin persists anything, you own the cleanup, and the harness will not warn you when you forget.
Knowledge check
Check your understanding
Answer this question before you continue.
The Append-Only Session Log as the Integration Backbone
Traceability in this harness is not a logging feature bolted onto the side. It is the substrate that makes plugin composition debuggable.
Everything the model sees is recorded in an append-only session log: system prompts, reasoning, tool calls and results, subagent scheduling, and every context injection. Resume, fork, replay, search, transcripts, and the web UI all read the same event stream. One source of truth instead of parallel bookkeeping.
The design commitment hiding in that sentence is worth naming. Adding a new kind of model-visible input means adding a new event type, which is a schema commitment, not a log line. You cannot inject context into a prompt and leave the trace silent, because the trace is defined as the set of things that reached the model. That constraint is what keeps the log honest.
Here is what a minimal trace looks like when the invariant holds:
[plugin.mount] source=memory-plugin id=mem-01
[context.inject] source=memory-plugin target=system-prompt tokens=340
[model.request] model=deepseek-v4 messages=7 tools=4
[tool.call] tool=read_file args={path:"src/main.ts"}
[tool.result] status=ok bytes=2048
[context.inject] source=memory-plugin target=user-turn tokens=120
[model.request] model=deepseek-v4 messages=9 tools=4
Each line carries a source field and an ordering position. That is what makes attribution possible: you can trace which plugin injected what, at which step, and in what order. Without the source field, you have a log. With it, you have a causal chain.
The engineering payoff shows up when a plugin misbehaves. The trace tells you which plugin contributed the input that made the output wrong. Without that, a composition bug is archaeology: you know the output was wrong, and you have no way to reconstruct which component contributed the input that made it wrong.
If a swap requires a fork, the harness is not plugin-oriented. If the trace goes dark, it is not traceable. Both failures look like bugs in your plugin.
Where the Plugin Model Bites
Elegance is not the test. Operations is the test. Here is where this architecture charges you.
Developer-preview churn. The plugin contracts are still being defined. Breaking changes to internal symbols, DOM injection, and custom session event types are the brittle edges, and they are exactly the edges plugin authors touch. If you build on this today, budget for rework, and pin your version. The architectural categories — capability seams, lifecycle, traceability — are more durable than any specific backend or API shape.
Stateful plugins are a different trust tier. A plugin that fetches a web page or runs a calculation is stateless; the worst case is a bad output you ignore. A plugin that writes persistent memory, persona data, or shared knowledge operates on the harness itself, not just within a session. Its effects persist into future sessions and shape future agent behavior. That is a higher level of trust, and it deserves a different review standard: not just “does this produce a useful output” but “does this leave the agent’s persistent state better than it found it.”
Composition debugging. A bug may live in the interaction between two plugins, not in either one. Neither plugin’s tests will catch it. The event bus that bought you composability is now the place where the failure hides.
Startup cost and graph size. A large plugin graph has a load cost, and it has a cognitive cost: there is no single obvious place to read the system’s behavior. You trade a readable monolith for a composable graph, and the graph is only readable through its trace.
When a Plugin Harness Is the Wrong Choice
The pattern is not universally correct. Here is the decision boundary I would apply.
Choose a plugin harness when you need to swap the loop, benchmark models under identical scaffolding, or run multiple agent backends behind one trace. Those are the cases where the architecture earns its complexity, because the thing you need to vary is the thing most frameworks fix.
Choose a fixed harness when your extension needs are shallow, your team is small, and operational simplicity beats composability. If you will never replace the loop, you are paying the indirection tax for a benefit you do not use.
The lock-in axis is ownership of memory and context. The harness is what manages context, and memory is a form of context — short-term memory lives in the conversation, long-term memory crosses sessions. Whoever owns the harness owns the memory layer, and that determines how portable your agent actually is. A plugin architecture that you control keeps that ownership with you. A managed API that hides the harness takes it.
A one-pass decision rule: list the components you would need to replace in the next six months. If the agent loop is on that list, you need a plugin harness. If it is not, you probably do not.
The Audit
Pick one capability in your current agent stack. Replace it without touching the rest of the code. Then check whether the session trace still explains what happened.
If the swap required a fork, the harness is not plugin-oriented in the way the slogan promises. If the trace went dark, it is not traceable. Either gap is worth fixing before you add another capability, because every capability you add on top of a fixed core makes the eventual replacement more expensive.
The slogan is a promise about the core. The audit is how you find out whether the core kept it.
Knowledge check
Final check
Finish the article by checking the ideas you just learned.
References
Research updated Sep 11, 2026


