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.
Install
$
npx -p @deepseek-ai/dsh dsh plugin --profile web add github:MarchLiu/dsh-cyberneticsREADME
Read the full README ↗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`.