DeepSeek Harness capability three roles: Definition / Provider / Consumer
Official documentation often mentions Service Definition, Service Provider, and Consumer. Together, they form the seam of a capability—that is, the replaceable capability interface.
This chapter will clarify what each of the three is, and why a capability is split into three roles.
The complete capability constitutes its seam; any single role is not a seam.
What is each of the three roles?
When a capability is generic enough and needs to support replaceable providers (for example, Bash execution), the harness splits the capability into three roles.
| Role | What is it responsible for? | Taking Bash as an example |
|---|---|---|
| Service Definition Interface + Types | Define the Cordis service, as well as the types of Request and Result | dsh-shell (registered as ctx.shell) |
| Service Provider Implementation | Actually implement this capability, typically targeting a specific runtime environment | dsh-bash-local (local execution) |
| Consumer Model-oriented tools | Expose the capability as a tool that models can call | dsh-tool-bash (bash tool) |
Service Definition only declares "what capabilities exist and what they look like," without caring about how they are implemented.
Service Provider inherits the abstract class of Definition and fills in the concrete behavior.
Consumer faces the model, wrapping the capability into tool schemas so that the model can call it.
The three roles can be placed in the same package, or split across different packages.
There is only one criterion: whether these roles need to evolve or be replaced independently.
Understand the three seam roles with one diagram
All three roles depend on Definition, while Provider and Consumer do not depend on each other.
The dashed box in the diagram is the complete capability, i.e., the seam.
Definition sits in the middle; both Provider and Consumer depend only on it.
Provider inherits the implementation of Definition, Consumer throughinject: ['shell']Depends on it.
There is no dependency between Provider and Consumer.
Therefore, when swapping Provider, neither Definition nor Consumer needs a single line of change.
Taking Bash as an example: the three roles of ctx.shell
Bash execution is the most typical seam in dsh; each of the three roles has its own package.
Service Definition is the dsh-shell package, registered as the ctx.shell service.
It defines the request type for BashShellExecRequestand result typeShellRunResult。
The Service Provider is dsh-bash-local, which executes commands on the local computer.
The same Definition has other Providers, such as dsh-bash-sandbox executing in a sandbox, and dsh-pwsh-local executing PowerShell.
The Consumer is dsh-tool-bash, which wraps the capability into a bash tool callable by the model.
tool-bash Through inject DeclarationDependency ctx.shell,再In execute 里Call ctx.shell.run(...)。
The official "Capability Seam and Core Services" reference document uses a table to maintain the three-role ownership of ctx.shell.
| ctx key | Role | Affiliated package (Definition) | Implementation (Provider) | Direct consumer (Consumer) |
|---|---|---|---|---|
| ctx.shell | seam | shell | bash-local / bash-sandbox / pwsh-local | tool-bash / tool-pwsh / hooks-claude-code / hooks-codex |
The consumers also include two hook bridge plugins: hooks-claude-code and hooks-codex.
Like tool-bash, they only recognize the ctx.shell interface and do not care which executor is behind it.
In the Bash seam, the model-facing request ShellExecRequest (workdir, timeoutMs optional) is separated from the fully resolved spec ShellExecSpec (fields required) actually used by the executor.
The tool layer calls ctx.shell.resolve(request) between the two—this is "explicit is better than implicit at package boundaries."
Why split it into three roles?
The first benefit of the split is that providers are replaceable.
The same Service Definition can have multiple providers, selected via cordis.yml.
Example
# Local Execution
- name: '@deepseek-ai/dsh-bash-local'
# To switch providers, simply replace the line above.
# Replace with the line below to switch to the sandbox executor:
# - name: '@deepseek-ai/dsh-bash-sandbox'
When switching providers, both the Service Definition and Consumer remain unchanged.
The second benefit of the split is that the three roles can evolve independently.
| Role | The freedom to evolve independently |
|---|---|
| Service Definition | Once callers start depending on its conventions, it rarely changes. |
| Service Provider | Can independently optimize performance and security |
| Consumer | Can adjust how the capability is presented to the model |
The third benefit of splitting is dependency decoupling.
Service Provider depends on Service Definition.
Consumer depends on Service Definition.
Service Provider and ConsumerMutually independent。
| Dependency relationships | Whether it holds |
|---|---|
| Provider → Definition | Yes |
| Consumer → Definition | Yes |
| Provider → Consumer | no |
| Consumer → Provider | no |
Hands-on analysis: find the three roles of the seam you are using.
The official "Capability Seam and Core Services" reference document maintains a complete service list.
Pick a seam you are familiar with, for example ctx.fs or ctx.llm, and sort it out in three steps.
Step 1: find its Definition package—that is, the "belonging package" column in the table.
Step 2: find its Provider package—that is, the "implementation" column in the table.
Step 3: find its Consumer—that is, the "direct consumer" column in the table.
For example ctx.llm of Definition Yes llm Package,ImplementationYes llm-deepseek and llm-pi-ai,straightJieeliminate费方Yes agent-loop and compaction-basic。
Another example is ctx.fs: the Definition is the fs package, the implementations are fs-local, fs-sandbox, and fs-e2b, and the direct consumer is tool-fs.
Once you get used to this way of thinking, you can tell at a glance which role any built-in service belongs to.
Summary and self-test
One-sentence summary: a capability is split into three roles—Definition (interface and types), Provider (implementation), and Consumer (model-facing tools)—and together they form the seam.
Self-test question 1: Which packages do the Definition, Provider, and Consumer of the Bash capability correspond to respectively?
Self-test question 2: when replacing Bash's Provider, which packages can remain unchanged?
Self-test question 3: why is it said that "any single role is not a seam"?
other extensions