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.

RoleWhat is it responsible for?Taking Bash as an example
Service Definition Interface + TypesDefine the Cordis service, as well as the types of Request and Resultdsh-shell (registered as ctx.shell)
Service Provider ImplementationActually implement this capability, typically targeting a specific runtime environmentdsh-bash-local (local execution)
Consumer Model-oriented toolsExpose the capability as a tool that models can calldsh-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.

能力 Seam 三角色关系图

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 keyRoleAffiliated package (Definition)Implementation (Provider)Direct consumer (Consumer)
ctx.shellseamshellbash-local / bash-sandbox / pwsh-localtool-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

# File path: cordis.yml
# 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.

RoleThe freedom to evolve independently
Service DefinitionOnce callers start depending on its conventions, it rarely changes.
Service ProviderCan independently optimize performance and security
ConsumerCan 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 relationshipsWhether it holds
Provider → DefinitionYes
Consumer → DefinitionYes
Provider → Consumerno
Consumer → Providerno

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