Preface

When building features with agents, a common scenario is: throw a one-sentence requirement into the chat, and the model modifies the code directly. The specifications only exist in the chat history, and once the context is refreshed in the next round, the previously agreed boundaries, acceptance criteria, and unchanged scopes will no longer match. To check “what exactly was built”, people have to go back through the conversation history and compare diffs, without a formal written agreement that can be used as a gate for review.

Spec-driven development reverses this process: first write “why to change, what to change, and how to confirm completion” into a Markdown file in the repository. After human approval, proceed with implementation, and then conduct acceptance checks item by item against the scenarios afterwards. OpenSpec formalizes this workflow into the openspec/ directory: in-progress changes are placed in changes/, and after being archived, they are merged into specs/. DeepSeek Harness (dsh) itself is a “everything is a plugin” runtime, where models, tools, sessions, and UI can be installed and uninstalled; the community maintainer tianji-qingtian developed dsh-spec-loop, which connects this closed-loop workflow to the /spec command of Harness.

This article is organized after cross-checking the plugin directory page, GitHub repository README, package.json, and release tags: what it is, how the command flow works, how to install it, and the boundaries to pay attention to when using it. DeepSeek Harness is still in developer preview, and the plugin API may have incompatible changes; the version in this article is based on the current released v0.1.2 of the repository.

What is it

dsh-spec-loop is a development and runtime plugin for DeepSeek Harness, maintained by tianji-qingtian, licensed under MIT. The directory page and GitHub repository both show 5 stars (based on the number displayed when opening the page). The main language is JavaScript, and the version number in package.json is 0.1.2, which matches the GitHub Release/tag v0.1.2.

The problem it solves can be summarized in one sentence: use the /spec command family to drive the workflow of “generate specification → approve → implement by task → accept item by item against the specification → archive”, and the change directory is compatible with the layout of OpenSpec, located under openspec/ in the workspace.

Two things need to be clarified:
- It adopts the directory format and phase division of OpenSpec, and implements the validation rules based on the core entries of OpenSpec CLI on its own; it does not depend on a separately installed OpenSpec CLI.
- It is a community plugin, listed on the independent site DeepSeek Harness Plugin Repository. This directory states that it has no official affiliation with DeepSeek / 幻方 (Fangxin), and is not an official app store.

The dsh.client.platform field in package.json is declared as web: it runs on the browser side, attached to the Web UI, with a specification change card added above the input box. The repository README also writes the installation steps according to the web profile.

Core Features

/spec Command Family

The plugin registers a /spec command, which routes to subcommands. The command handler only handles workflow orchestration and file system operations; the proposal text, task list, specification increments, and implementation code are all handed over to the main agent model of the current session, with tasks injected via agent.steer and generated using the full toolset.

The subcommands listed in the README are as follows:

Subcommand Function
init Create openspec/project.md and directory structure
new <target> Generate proposal/task/specification increment after clarification, and automatically validate
status Read-only: current change-id, phase, task progress x/y
list List active changes and capability specifications
show <id> View full proposal text (display design.md together if it exists)
approve <id> Approve, unlock the implementation gate
implement <id> Implement item by item according to tasks.md and check off
verify <id> [--deep] Acceptance test according to Scenario; --deep uses the main model
archive <id> Merge increments into specs/, move directory to archive
validate [id] OpenSpec format validation (runs automatically after new)
edit <id> Revise the proposal, reset status to proposed

/spec new will prompt up to 3 built-in multiple-choice questions, covering scope, constraints, and acceptance methods respectively. The language follows the target description, using Harness’s question-and-answer UI. When using a sub-agent session or lacking a UI provider, the clarification step will be skipped and generation will proceed directly.

OpenSpec Compatible Directory

After initialization, the workspace will have the following layout (aligned with the openspec/ structure of OpenSpec):

<workspace>/openspec/
├── project.md
├── specs/<capability>/spec.md
└── changes/
    ├── <change-id>/
    │   ├── proposal.md
    │   ├── tasks.md
    │   ├── design.md          # Optional
    │   ├── verify.md          # Written by the plugin after acceptance
    │   └── specs/<capability>/spec.md
    └── archive/YYYY-MM-DD-<change-id>/

Specification increments are segmented with ## ADDED|MODIFIED|REMOVED Requirements, and each Requirement must have at least one #### Scenario:. This is an OpenSpec validation rule, and the plugin has built-in identical checks: it runs automatically after proposal generation; if it fails, a correction request will be steered back to the agent (with a retry limit). approve will reject changes that have not passed validation, and archive will reject changes that do not exist in the directory.

When archiving, merge into specs/<capability>/spec.md item by item according to Requirement: append ADDED entries, replace MODIFIED entries by name (append if no matching name exists), delete REMOVED entries, then move the change directory to changes/archive/ with one mv command.

Approval Gate and Persistent State Machine

The state follows this chain:

proposed  approved  implemented  verified  archived

You can run /spec edit to reset to proposed at any stage, and you will need to re-approve after making changes. implement will reject changes whose status is not approved (or later stages in the implementation chain). The gate reads the same session projection used for panel rendering, sharing a single data set between display and behavior states.

The state does not use a custom set of session events. External plugins cannot safely add new types to SessionEventMap (the persistence read path will reject unknown non-ignorable events), so state transitions only fold standard events: successful command/run / command/done pairs, plus machine markers in agent replies (such as SPEC_CHANGE_ID:, SPEC_IMPLEMENTED). After restarting, the change cards, phases, and gates will still be present; if you uninstall the plugin, the session logs will still be readable.

One usage restriction: the approval status is folded per session. Approving in one session will not automatically take effect in another session.

Item-by-Item Acceptance and Change Card Above the Input Box

/spec verify will make a limited referee call for each Scenario of each Requirement: by default, use flash and disable thinking; add --deep to switch to the main model. The verification commands declared in bash code blocks in proposal.md will first be executed via ctx.shell, and the output will be fed into the referee prompt. The results are written to verify.md, with a ✅/❌ table and the original judgment text.

In the Web UI, the dock above the input box will display a full-width change card (labeled 📐 Spec in the README): current change-id, phase, task progress x/y, and the next command to run. The progress comes from Harness’s built-in todos projection — the implementation phase prompt will have the agent mirror tasks.md into todo_write, and the panel does not need additional RPC calls. The copy uses the locale service and supports Chinese and English.

Installation and Enablement

The plugin runs with the permissions of the current dsh process, and may execute code during installation. You should check the source code repository and license before installing; for reproducible installations, pin the commit hash or release tag.

The installation command given on the directory page is:

dsh plugin add github:tianji-qingtian/dsh-spec-loop

The prerequisites in the repository README: the dsh CLI must be on the PATH. If you usually start Harness with npx and do not have a global dsh installed locally, you will get a command not found error. You can install it globally first:

npm install -g @deepseek-ai/dsh

pnpm add -g @deepseek-ai/dsh is also available, provided that pnpm’s global bin directory is in the PATH; or do not install it globally, and prepend npx @deepseek-ai/dsh to subsequent commands.

The README recommends adding the bundle to the web profile, and preferably pinning the release tag (the documentation uses #v0.1.2; #main will track the latest commit). The lib/ artifacts are already committed in the repository, and no build will run during installation:

dsh plugin --profile web add "github:tianji-qingtian/dsh-spec-loop#v0.1.2"
dsh --profile web

add only modifies the profile file, and the running instance will not hot-reload, so you need to restart with the corresponding profile. After restarting, the specification change card should appear above the input box, and /spec will only be registered after the host side finishes loading. You can confirm that dsh-spec-loop is in the list in Settings → Plugins.

The directory page adds the method for pinning a commit, in the form:

dsh plugin add github:tianji-qingtian/dsh-spec-loop#commit

Replace commit with the actual hash. The current tag v0.1.2 corresponds to commit 0783a43190d43accb93238f85d06d231e373bd81 (subject to the GitHub tags API).

The Node engine declared in package.json is ^22.19.0 || >=24.0.0, and the peer dependencies point to @deepseek-ai/dsh-* ^0.1.0-rc.6 and @deepseek-ai/cordis ^4.0.1. Harness is still iterating rapidly, so you should check whether your local dsh version matches before installing.

Typical Usage

The following commands come from the examples in the repository README, with the change-id taking add-user-login as an example (after running /spec new to generate the proposal, use the actual id returned by the agent and shown in /spec list).

First initialize the directory:

/spec init

Start a change with a one-sentence goal. The plugin will first ask for clarification, then have the agent write proposal.md, tasks.md, and the specification increment, then automatically validate:

/spec new 用户登录功能

View the current card, list active changes, and open the proposal:

/spec status
/spec list
/spec show add-user-login

After human review and approval. Before approval, implement will be rejected:

/spec approve add-user-login
/spec implement add-user-login

After the implementation is complete, perform acceptance testing against the Scenarios. Use flash by default; add --deep to use the main model:

/spec verify add-user-login
/spec verify add-user-login --deep

After the acceptance test passes, archive, merge the increments into specs/, and move the directory to changes/archive/:

/spec archive add-user-login

To revise the proposal midway:

/spec edit add-user-login

The status will return to proposed, and you will need to run approve again before you can implement. The change card above the input box will synchronize the change-id, phase, x/y progress, and next command; use /spec status if you only want to view the status without modifying it.

Applicable Scenarios and Notes

It is suitable for these situations:
- Developing features in DeepSeek Harness’s Web UI, and hoping that specifications, tasks, implementations, and acceptance results are saved in repository files instead of only existing in a single chat session.
- Already adopting or preparing to adopt the OpenSpec openspec/ layout, and hope that the change directory on the Harness side can be directly recognized by OpenSpec tools.
- Need a gate that prevents implementation before approval, and generates written acceptance records in verify.md according to Scenarios.

Before using it, remember these boundaries (all from the repository README / requirement documentation, not additional inferences):
1. Permissions and Security. The plugin runs with the permissions of the current dsh process; verify will also execute the bash verification commands declared in proposal.md. Read the source code and MIT license before installing, and do not run dsh plugin add for untrusted repositories.
2. Platform. The client is declared as web, and the change card is attached to the composer dock of the Web UI. The installation path in the README is also --profile web.
3. Approval Per Session. Changes approved in session A will not be automatically considered approved in session B.
4. No Enforcement of Gates via File Monitoring. v1 only enforces gates at the command level: it rejects /spec implement before approve, and does not intercept the agent from directly modifying implementation files with ordinary tools.
5. Not Compatible with GitHub spec-kit Directory Format. The requirement documentation states that v1 only supports OpenSpec; spec-kit is reserved for future expansion.
6. Harness Preview Version. The official note that DeepSeek Harness is still in developer preview, and core plugins and APIs will continue to change. The README also reminds that destructive changes may occur.
7. Do Not Install the Wrong Named Project. There are other specification-related projects in the community such as dsh-specflow and ds-spec-loop, with different mechanisms and installation sources. This article only corresponds to github:tianji-qingtian/dsh-spec-loop.

Summary

dsh-spec-loop connects spec-driven development to DeepSeek Harness: /spec is responsible for opening gates and persisting files, the agent is responsible for writing proposals and modifying code, and the OpenSpec-shaped openspec/ serves as a reviewable source of truth. The approval gate, format validation, Scenario-by-Scenario acceptance testing, and change card above the input box are all designed to allow “first agree, then implement, then verify” to be completed in a single session.

Directory page: https://deepseek-harness-plugin.com/zh-CN/plugins/dsh-spec-loop/

GitHub: https://github.com/tianji-qingtian/dsh-spec-loop