MarchLiu/dsh-cybernetics ↗★ 11

@mars.liu/dsh-cybernetics

Cybernetic work protocol for DSH: the session goal (dsh-goal) driven loop of task -> verify -> triage agents, implicitly advanced via one workflow run per round. Server plugin + client goal tab.

Package
@mars.liu/dsh-cybernetics
Compatibility
Unverified
Harness peer range
*
Version
0.17.2
License
MIT
Last updated
Nov 5, 2026

Install

$npx -p @deepseek-ai/dsh dsh plugin --profile web add github:MarchLiu/dsh-cybernetics

Installation and Usage

Installation

npm package name: @mars.liu/dsh-cybernetics. In a DSH profile, install this directory via link: — the plugin has zero runtime dependency on host packages (tool registration uses bare JSON Schema + inline validation) and doesn't need its own node_modules; requires Node >= 23.6.

Install from source:

git clone https://github.com/MarchLiu/dsh-cybernetics.git
cd dsh-cybernetics

Link-install in your DSH profile (e.g. ~/.dsh/profiles/web/):


### Plugin-page configuration

Configure directly on this plugin's card on the Web editor's "Plugins" page — since v0.8.1 the card itself renders every volatile field (field descriptions in the `Config` schema):

- **All-goals mode** (`allGoalsMode`, volatile): toggle, takes effect immediately on save, prompt segments remount instantly;
- **task/verify/triage agent models** (`taskAgentModel` / `verifyAgentModel` / `triageAgentModel`, volatile): dropdown-backed text fields — pick from the live system model list (shown as `providerName · provider/model`) or type "provider/model" / a bare model name; Enter or blur saves, empty inherits from the session agent (triage = the convergence-decision role, full rounds only). A configured value missing from the live model list shows an unavailable warning (runtime falls back to the session agent model) with a one-click Clear;
- **Recursion depth / parallel cap** (`roundsPerSubgoal` integer ≥1 / `maxConcurrentRounds` integer ≥0, volatile): number fields, Enter or blur saves, blank restores the default (an `unset` write);
- **Hard gate** (`hardGate`, volatile since v0.8.10): a boolean toggle on the card — strips write/execution tools from the top-level agent at assembly and routes every change through the goal loop; takes effect immediately on save (gate listeners hot-installed/disposed), no restart needed;
- **Smart agent model selection** (`smartAgentModelSelection`, volatile since v0.16): a boolean toggle on the card — each round start auto-picks a model per role (task/verify/triage) from the live model catalog by task shape (light models for trivial work, the top tier for hard work); explicitly configured role models always win, and unresolvable picks keep inheriting the session agent with the reason audited; takes effect on the next goal round — see the classification rule table in "Features → Smart agent model selection";
- **Other gate fields** (`gateMode`/`gatedTools`/`gateAllowlist`/`gateAllowlistExtra`/`gateApprovalRelay`, non-volatile): not served to the card; edit them in the profile config document (saving triggers a plugin reload). `gateMode` has no default: unset + `hardGate: true` runs `allowlist`; an explicit `denylist` is honored and carries the residual risk documented above.

### Advanced configuration: roles (profile yaml, agent-guided)

The `roles` field maps sub-agent roles to `{provider, model}` overrides (fixed `default`/`verify`/`triage` slots plus any named task role, e.g. `frontend`). **When do you need it?** The flat card fields (`taskAgentModel` / `verifyAgentModel` / `triageAgentModel`) already cover the three fixed roles; reach for `roles` only when you want per-role overrides for *named task roles* (roles passed via the round's `role` argument, e.g. a `writer` or `frontend` role on a different model) or need provider+model pairs beyond what the panel exposes.

Since v0.8.4 this field is **not editable in the GUI** — hand-editing a JSON object in a settings card is unfriendly. Instead, edit the profile config yaml directly (the user patch row in the profile's `cordis.patch.yml`, or the profile's own config document):

```yaml

### In-session usage: the `cybernetics` tool

The session agent drives the loop in-session via the `cybernetics` tool (`toolName` is configurable); the implicit trigger prompt segments (`implicitTrigger: false` to disable) instruct it to classify input and call the tool per protocol without waiting for an explicit request:

| action | Semantics |
|---|---|
| `start` | New task: `{action:'start', title, brief}` creates a goal and (by default, in the background) starts its first round |
| `round` | Drives one round, blocking (on an existing goal or a newly created one) |
| `collect` | Folds a completed background round, yielding the controller decision (continue/pause) |
| `revise` | Revises the goal: creates a new goal (append-only), `reason` required, optional objective/title/depth/executor/abortPrevious |
| `cancel` | Aborts a running round (does not change the goal; use when only aborting, not revising) |
| `list` | Shows the state, round counts, and run handles of all goals on this session's goal board |

Companion auditing: each round's structured result lands in `.cybernetics/round--.json`; revisions land in `.cybernetics/revisions-.jsonl`; goal-board snapshots land in `.cybernetics/board-.json`.