# dsh — DeepSeek Harness adapter Spike of the `claude-harness` port for DeepSeek Harness (DSH 0.2.1-rc.3). The Claude Code installation in `~/.claude` stays untouched; this directory is a separate Cordis bundle plus a thin install helper. **What works in the spike:** - `guard-main` / `require-plan` — the tested bash/Python hooks run through `ctx.tools.guard`; the agent gets `BLOCKED` with the same messages as in Claude Code; - superpowers bootstrap — `using-superpowers` is injected once per session from `agent/pre-step` and re-injected after compaction; - roles — the model loads them with the `role` skill (`~/.dsh/roles`, then `~/.claude/roles`, then repo `roles/`); `/role dev|admin|analyst|qa` remains the user-facing command and injects the same text, without Claude's auto-memory step. **Not yet:** SDD (DSH subagents are asynchronous), `briefing`, `harness-check`, `role-hint`, `harness-doctor`, auto-memory, caveman. See [PORT.md](PORT.md) for the design, mapping table, and risks. ## Quick start ```bash # Static check bash dsh/install.sh --check # Global instructions, superpowers skills, local role skill, and roles # (run from a terminal; these write outside the session workspace) bash dsh/install.sh --global bash dsh/install.sh --skills bash dsh/install.sh --roles # Install the bundle in DSH: # Plugins -> install a bundle from dsh/bundle # or ask the agent to call plugin_manager install_bundle with that target. ``` Do not hand-edit `$DSH_HOME/profiles/desktop/package.json` or `cordis.patch.yml`: the Desktop profile is Electron-managed and the plugin manager owns those writes. ## Verify 1. In a new session, ask `what skills do you have?` — the superpowers catalog should be visible. 2. In a repository on `main`, ask the agent to create a file — expect `BLOCKED [guard-main]`. 3. Create a worktree on a feature branch, ask for an edit under `src/` — expect `BLOCKED [require-plan]` until `.bounded` or a plan for the branch exists. 4. The model should load a role with `skill({name:"role"})`; `/role dev` is the user-facing command with the same file. Expect the five-line role summary. 5. Prompt `Let's make a react todo list` — `brainstorming` must trigger before any code. The injected bootstrap starts with a marker: ```text ``` After compaction the marker disappears from `session.surface.nodes` and the next step injects a fresh copy. ## Tests ```bash bash dsh/tests/run.sh ``` Pure Node; no DSH process is required. The guard tests create a throwaway git repository and exercise the real `hooks/guard-main.sh` and `hooks/require-plan.sh` through the adapter. ## Layout ```text dsh/ bundle/ package.json DSH bundle manifest (dsh.bundle.patch) cordis.patch.yml inserts the dsh-harness row index.js ctx.tools.guard + agent/pre-step + /role command-role.js /role command glue lib/guards.js DSH tool call -> claude-harness hook JSON lib/bootstrap.js superpowers skill resolution, marker, dedupe lib/role.js role layers and text (pure) dsh-tools.md superpowers tool mapping hooks -> ../../hooks local install: tested hooks are reused, not copied locale/{en,ru}.json icon.svg tests/ install.sh mcp.codegraph.yml optional CodeGraph MCP overlay PORT.md design, mapping, risks, next phases ``` ## Configuration The row is configurable from the profile patch; defaults target this repository layout: ```yaml - id: dsh-harness config: guards: true bootstrap: true roleCommand: true bootstrapSubagents: false hooksDir: '' # empty -> bundle/hooks -> ../../hooks rolesDir: '' # empty -> ~/.dsh/roles, ~/.claude/roles, repo roles/ projectRolesDir: '' # empty -> /.claude/roles roleNames: [dev, admin, analyst, qa] bootstrapSkillPath: '' # empty -> ~/.dsh/skills, then Claude cache toolMappingPath: '' # empty -> bundle/dsh-tools.md bootstrapMaxBytes: 65536 ``` ## Known limits - The guard adapter uses the repository's bash/Python hooks; if `python3` is missing, the hooks fail open by design. - `bundle/hooks` is a symlink for local-directory installation. A published bundle needs a real copy of `hooks/` (already listed in `package.json` `files`). - `using-superpowers` is read from `~/.dsh/skills` after `--skills`; the Claude plugin cache is only a fallback, so a partial Claude Code rollback does not break the bootstrap. Set `bootstrapSkillPath` or `DSH_SUPERPOWERS_SKILL` for another layout. - Role loading is model-driven through the `role` skill; there is no automatic `agent/pre-step` injection. If the model skips the skill, use the `/role` command or ask it to load the role explicitly. - Model names in roles and superpowers (`sonnet`, `haiku`, `opus`) are not DSH models. Map them to live provider/model routes before porting SDD. - SDD is intentionally out of scope for this spike; see [PORT.md](PORT.md#3-what-is-deliberately-deferred).