# @max-null/dsh-guardian

本插件属于 **`@max-null/*` 插件系列**——这一系列共同构成 **[SSID（思灵 · Seek Soul in Darkness）](https://github.com/Max-Null/seek-soul-in-darkness)** 桌面体验。SSID 是整合它们的盒：`dsh-capture` · `dsh-chat-rail` · `dsh-chinese-thinking` · `dsh-draft-polish` · `dsh-guardian` · `dsh-habit` · `dsh-memory` · `dsh-node-appearance` · `dsh-plugin-center` · `dsh-quick-toolbar` · `dsh-skill-mcp-center` · `dsh-ssid-panels` · `dsh-ssid-zh-ui` · `dsh-achievements`。

This plugin belongs to the **`@max-null/*` family** — a set of plugins that together form the **[SSID (思灵 · Seek Soul in Darkness)](https://github.com/Max-Null/seek-soul-in-darkness)** desktop experience.

Guardian state engine for the DeepSeek Harness — three trigger-line monitors
over session events, with live reminder injection and a UI snapshot service.

M2 of SSiD (思灵), ported from fractal's guardian: assertion counting, the
edit review queue, and no-feedback-loop monitoring.

## What it monitors

| Trigger line | Rule |
|---|---|
| Assertion count | Scans assistant messages for unverified claims (`不支持/做不到/只有 N 种/不存在/无法 X/远低于/过于 X`). Counts per session, decays by 1 every 3 clean turns, segments into levels [1,3]+. |
| Edit review queue | Successful `write`/`edit` tool calls enqueue `{filePath, sessionId, turn}`. FIFO cap 20, dedup per file+session. The review reminder re-lists them at each prompt assembly. |
| No-feedback loop | Per turn: edits without `bash`/`pwsh` increment the counter; any exec resets it. 3 consecutive edit-only turns inject a "build a feedback loop first" warning. |

## 截图

本插件是**会话行为监控类**：不新增任何按钮、面板或设置项。它在会话过程中维护断言计数、编辑审查队列与「无反馈环」监测，效果体现在模型行为的约束上。

> 按《SSiD 开发手册》§9 截图规范：截图须回答「装完会多出/变成什么」的**入口与面板**。
> 本插件无界面元素（no UI surface），故**不适用**该项要求，改以上述行为效果说明代替。

## Compose

```yaml
# cordis.yml (or via the bundle patch):
- id: guardian
  name: '@max-null/dsh-guardian'
```

Requires `storage`, `system-prompt` in the host composition (dsh-base ships
both). Installs as a bundle: `dsh plugin --profile <name> add @max-null/dsh-guardian`.

## Services

- `ctx.guardian` — the engine:
  - `snapshot()` → `{ session, reviewQueue }` for UI panels
  - `sessionState(sessionId)` → per-session state
- Three dynamic `systemPrompt.context` reminders (`guardian:assertion`,
  `guardian:no-feedback`, `guardian:review`), evaluated per assembly from the
  most recently active session.

## Config

| Field | Default | Meaning |
|---|---|---|
| `decayTurns` | `3` | Clean turns before one assertion point decays |
| `assertionThresholds` | `[1, 3]` | Ascending thresholds segmenting levels 1-3 |
| `noFeedbackThreshold` | `3` | Consecutive edit-only turns before the warning |
| `reviewQueueMax` | `20` | Review queue FIFO cap |
| `globalRoot` | `$DSH_HOME/storages/guardian` | JSON storage root |

## Storage

One JSON unit (`guardian`, version 1) under `$DSH_HOME/storages/guardian`:
`sessions` table (per-session state) + the global slot (review queue).
In-memory is authoritative during a run; the session state flushes at turn end
and the review queue on each accepted edit.

A failed flush is logged to stderr and dropped: the serialized write chain stays
usable, and neither the event entry point nor the chain lets a failure escape into
the host process. The state is advisory and rebuildable, so losing one update is the
intended blast radius — a rejected write must never take the kernel down.

## Develop

```sh
npm install --legacy-peer-deps   # @deepseek-ai/* types come from these devDependencies
npm test                         # vitest: 31 tests (incl. write-failure resilience)
npm run typecheck                # tsc against the installed @deepseek-ai/* types
npm run build                    # emit dist/
```

> Dev tooling resolves `@deepseek-ai/*` types from the copies `devDependencies`
> installs into `node_modules`. The `paths` entries in `tsconfig.json` point at an
> adjacent `deepseek-harness` checkout, which does not exist beside
> `max-null-plugins/`, so TypeScript falls back to `node_modules` for every one of
> them. Runtime peer resolution is unaffected — the host composition supplies the
> real packages.

## SSID 系列


