dsh-doublecheck 0.9.30 → 0.9.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README-zh.md DELETED
@@ -1,496 +0,0 @@
1
- <div align="center">
2
-
3
- # dsh-doublecheck
4
- - **1024 商店渠道**:先 `npm i -g dsh1024`,再 `dsh1024 plugin --profile web add dsh-doublecheck`(计入 [deepseek1024.com](https://deepseek1024.com) 安装排行)。
5
-
6
- **DeepSeek Harness 的交付质量门禁:先拷问需求,再测试实现,最后证明交付——并用「可交付 / 需要返工」的裁决来把关交接。**
7
-
8
- *需求在第一次改动之前就被拷问清楚;交付是被证明的,而不是被口头宣称的。*
9
-
10
- [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
11
- [![Gitee](https://img.shields.io/badge/Gitee-mirror-c71d23?logo=gitee)](https://gitee.com/perrylink/dsh-doublecheck)
12
- [![DSH plugin](https://img.shields.io/badge/dsh--plugin-✅-green)](https://github.com/topics/dsh-plugin)
13
- [![dsh-doctor](https://raw.githubusercontent.com/PerryLink/dsh-plugin-doctor/main/badges/PerryLink__dsh-doublecheck.svg)](https://github.com/PerryLink/dsh-plugin-doctor#verified-徽章)
14
- [![DSH Market](https://raw.githubusercontent.com/2BingLing/dsh-market/master/assets/readme/badge-listed-zh.svg)](https://dsh.market/)
15
- [![Node](https://img.shields.io/badge/node-%5E22.19%20%7C%7C%20%3E%3D24-brightgreen.svg)](#)
16
- [![CI](https://img.shields.io/github/actions/workflow/status/PerryLink/dsh-doublecheck/ci.yml?branch=main&label=CI)](https://github.com/PerryLink/dsh-doublecheck/actions)
17
- [![Version](https://img.shields.io/github/v/tag/PerryLink/dsh-doublecheck?label=version)](https://github.com/PerryLink/dsh-doublecheck/releases)
18
- [![npm version](https://img.shields.io/npm/v/dsh-doublecheck)](https://www.npmjs.com/package/dsh-doublecheck)
19
- [![npm downloads](https://img.shields.io/npm/dm/dsh-doublecheck)](https://www.npmjs.com/package/dsh-doublecheck)
20
- [![dshfind](https://dshfind.com/api/badge/PerryLink/dsh-doublecheck?metric=downloads&lang=zh)](https://dshfind.com/zh/plugins/PerryLink/dsh-doublecheck?ref=badge)
21
-
22
- [English](README.md) · [简体中文](README-zh.md) · [Español](README-es.md) · [Português](README-pt.md) · [हिन्दी](README-hi.md)
23
-
24
- ```sh
25
- dsh plugin --profile <name> add dsh-doublecheck
26
- ```
27
-
28
-
29
- </div>
30
-
31
- ---
32
-
33
-
34
- **📖 生态实测知识库**(实测数据,不是营销):[插件开发指南 · 选型实测数据 · 维护取舍判据](https://perrylink.github.io/dsh-plugin-guide/)。
35
-
36
- <!-- star-cta -->
37
- ## ⭐ 如果它帮到了你
38
-
39
- 这个插件是 [DSH 插件家族](https://github.com/PerryLink)的一员(95 个,全部 Apache-2.0)。如果你在用,**给个 star** —— 它不会解锁任何功能,但会让下一个人在搜索里更容易找到它。
40
-
41
- *English:* part of a 95 plugin family for DeepSeek Harness. If it is useful, **a star helps the next person find it** — nothing is gated behind it.
42
-
43
- ## What is dsh-doublecheck?
44
-
45
- DeepSeek Harness 的交付质量门禁:先拷问需求,再测试实现,最后证明交付——并用「可交付 / 需要返工」的裁决来把关交接。
46
-
47
- 需求在第一次改动之前就被拷问清楚;交付是被证明的,而不是被口头宣称的。
48
-
49
- ![dsh-doublecheck 工作流图:请求 → 策略/复核 → 判定。](docs/assets/dsh-doublecheck-flow.svg)
50
-
51
- *工作流概览:请求 → 策略/复核 → 判定。下面的示例使用实际命令面。*
52
-
53
-
54
- *同一次运行,动图版。*
55
-
56
- ## 兼容性
57
-
58
- | 方面 | 状态 |
59
- |---|---|
60
- | Harness | DeepSeek Harness `dsh-v0.2.2-rc.1` (adapted 2026-11-05): `engines.dsh` gains `>=0.2.2-0 <0.3.0` (every earlier line stays admitted); the gate and projection paths are covered by the rc.1 test suite. |
61
- | Node | `^22.19.0 \|\| >=24.9.0` |
62
- | 平台 | 全部(纯宿主;无原生代码,自身无直接网络请求) |
63
- | 模型 | 任意(守卫本身从不调用模型;评审与批评阶段作为宿主 subagent 运行) |
64
-
65
- ## 你会得到什么
66
-
67
- `dsh-doublecheck` 安装两个插件行,它们读取并执行同一份持久会话日志:
68
-
69
- 1. **`doublecheck-grill`** —— 需求熔炉:内置的 `grill-requirements` 技能,加上面向模型的 `doublecheck_skills`、`doublecheck_spec`、`doublecheck_report` 工具,以及按维度执行的验证工作流。
70
- 2. **`doublecheck-guard`** —— 纪律守卫:grill 门禁、红/绿证据门禁、对抗式评审、`/doublecheck` 与 `/gate` 命令、实时的 `gate` 设置卡片,以及四阶段交付门禁。
71
-
72
- 两者共同执行**纪律闭环** —— *grill → design → red → green → review → verify*:
73
-
74
- ```text
75
- grill ──▶ design ──▶ red ──▶ green ──▶ review ──▶ verify
76
- │
77
- └─ 六个需求维度、共识门禁,
78
- 结构化 spec 提交到会话 + 工作区
79
- ```
80
-
81
- | 阶段 | 含义 |
82
- |---|---|
83
- | **grill** | 拷问六个需求维度;在达成共识之前拒绝实现。 |
84
- | **design** | 通过 `doublecheck_spec` 提交已确定的 spec。 |
85
- | **red** | 在实现改动之前,用一次失败的测试运行来证明差距。 |
86
- | **green** | 改动之后一次通过的测试运行闭合闭环。 |
87
- | **review** | 一个分叉的对抗式批评者对照 spec 审计交付。 |
88
- | **verify** | `doublecheck_report` + 按维度的验证工作流证明交付。 |
89
-
90
- ## 快速开始
91
-
92
- ```sh
93
- dsh plugin --profile web add github:PerryLink/dsh-doublecheck
94
- ```
95
-
96
- ```sh
97
- # 1. install the bundle into your profile
98
- dsh plugin --profile web add github:PerryLink/dsh-doublecheck
99
-
100
- # or from npm (published releases)
101
- dsh plugin --profile web add dsh-doublecheck
102
-
103
- # 2. restart and verify the row
104
- dsh --profile web --dump-config | grep -E -A3 'id: doublecheck-(grill|guard)'
105
- ```
106
-
107
- 两个行(`doublecheck-grill` 和 `doublecheck-guard`)随配置文件自动激活。
108
-
109
- ## 安装与卸载
110
-
111
- - **git 渠道**(最新 `main`):`dsh plugin --profile web add github:PerryLink/dsh-doublecheck` —— `prepare` 脚本只使用生产依赖进行构建。
112
- - **npm 渠道**(发布版本):`dsh plugin --profile web add dsh-doublecheck`。
113
- - **tarball 渠道**:在本仓库中执行 `pnpm pack`,然后 `dsh plugin --profile web add ./dsh-doublecheck-<version>.tgz`。
114
- - **卸载**:`dsh plugin --profile web remove dsh-doublecheck`(或从配置文件补丁中移除这些行)。
115
-
116
- 如需零配置的严格模式(每个门禁都以 `block` 强度开启、要求门禁覆盖率),在捆绑补丁之上应用随附的覆盖层:`dsh --profile web --patch ./node_modules/dsh-doublecheck/strict.patch.yml`。
117
-
118
- ### 示例
119
-
120
- 以下为插件真实入口;安装后调用一个即可。
121
-
122
- #### 详细示例
123
-
124
- **命令**
125
-
126
- ~~~sh
127
- /gate run
128
- ~~~
129
-
130
- **输出**
131
-
132
- ~~~text
133
- # Delivery gate report
134
-
135
- > **Verdict: rework required** — 2 red item(s)
136
- > The gate is red. Re-open the work in plan mode to re-check the open items before delivering.
137
- ~~~
138
-
139
- *来源 `README.md §Example report (lines 243-251)`*
140
-
141
- #### 失败分支
142
-
143
- **输入**
144
-
145
- ~~~text
146
- /doublecheck maybe
147
- ~~~
148
-
149
- **输出**
150
-
151
- ~~~text
152
- Unknown /doublecheck argument "maybe". Usage: /doublecheck status|report|on|off
153
- ~~~
154
-
155
- *来源 `plugins/dsh-doublecheck/src/guard/prose.ts:191-192; plugins/dsh-doublecheck/src/guard/command.ts:156; plugins/dsh-doublecheck/tests/command.spec.ts:201-208`*
156
-
157
- #### 简短示例
158
-
159
- - `doublecheck_skills`
160
- - `doublecheck_spec`
161
-
162
- ## 配置
163
-
164
- 所有可调项都是 Schemastery 的 `Config` 字段(可在 cordis.yml 中修改)。按 id 定位的覆盖会替换整行——请重新声明你需要的每一个键。`cordis.patch.yml` 逐键内联说明;Schema 默认值是调优默认值的唯一来源。
165
-
166
- | 键 | 默认值 | 含义 |
167
- |---|---|---|
168
- | `specFile` | `'doublecheck-spec.md'` | 已提交 spec markdown 的工作区文件(grill 行)。 |
169
- | `reportFile` | `'doublecheck-report.md'` | 交付报告的工作区文件(grill 行)。 |
170
- | `reportVerify` | `true` | 默认运行验证工作流(grill 行)。 |
171
- | `verifyProvider` | `'fork'` | 各维度检查器运行的 subagent 提供者(grill 行)。 |
172
- | `verifyMode` | `'all'` | `all` = 每个维度一个并行检查器;`single` = 一个合并检查器(grill 行)。 |
173
- | `intensity` | `'remind'` | grill、红/绿和评审门禁的执行强度(`remind` / `warn` / `block`)。 |
174
- | `enableByDefault` | `true` | 没有 `/doublecheck on\|off` 记录的会话的主开关。 |
175
- | `language` | `'en'` | 注入的提醒/拒绝/评审/门禁文案语言(`en` / `zh`)。 |
176
- | `guardTools` | `['edit', 'write']` | 两个门禁监视的修改工具名称。 |
177
- | `vagueTaskMaxChars` | `200` | 超过此长度的任务绝不会被视为模糊。 |
178
- | `remindOnce` | `true` | 每个提醒每会话最多注入一次(跨重启持久)。 |
179
- | `testToolNames` | `['bash', 'pwsh']` | 可以运行测试的 shell 工具名称。 |
180
- | `testCommandPatterns` | *(pnpm/npm/yarn/bun test、pytest、go/cargo/make test、node --test、deno test、uv run pytest)* | 命令必须匹配才能计为一次测试运行的正则。 |
181
- | `testFilePatterns` | *(测试目录、`*.test.*` / `*.spec.*`)* | 识别测试文件的正则——始终可编辑,免于红门禁。 |
182
- | `modules.grill` | `true` | 关闭则禁用 grill 门禁。 |
183
- | `modules.tdd` | `true` | 开启则启用红/绿证据门禁。 |
184
- | `modules.adversary` | `false` | 开启则在绿色后启用分叉批评者评审。 |
185
- | `adversaryModel` | `null` | 批评者模型路由;`null` = 主模型自评。 |
186
- | `adversaryProvider` | `'fork'` | 批评者运行的 subagent 提供者。 |
187
- | `adversaryMaxFindings` | `5` | 注入会话的发现上限(1–20)。 |
188
- | `adversaryTools` | `['read', 'glob', 'grep']` | 批评者工具允许列表;请保持只读。 |
189
- | `adversaryTimeoutMs` | `120000` | 一次批评者运行的硬性时间预算。 |
190
- | `gate.enabled` | `true` | 门禁面板与回合边界红色通知的主开关。 |
191
- | `gate.planSuggestion` | `true` | 在红色报告中附加计划模式复查建议。 |
192
- | `gate.reportFile` | `'gate-report.md'` | 门禁报告的工作区文件。 |
193
- | `gate.requirements.checklist` | *(六个 spec 维度问题)* | 可插拔的关键问题清单:`{ id, question, specDimension, required }`。 |
194
- | `gate.requirements.minConfirmed` | `6` | 必须通过的最少必答问题数(1..必答数量)。 |
195
- | `gate.requirements.interrogateTool` | `'ask_user_question'` | 其调用计为询问证据的工具名称。 |
196
- | `gate.tests.requirePassingRun` | `true` | 最近一次测试运行未通过(或缺失)即为红灯。 |
197
- | `gate.tests.allowFailingRuns` | `0` | 最近一次绿色之后允许的失败运行次数,超过则红灯。 |
198
- | `gate.tests.requireCoverage` | `false` | 开启则要求在测试输出中有覆盖率证据。 |
199
- | `gate.tests.minCoveragePct` | `80` | 最低覆盖率百分比(0–100)。 |
200
- | `gate.tests.evalReports.enabled` | `false` | 开启则把 dsh-eval 报告(dsh-auto-review 的评测引擎)并入测试证据。 |
201
- | `gate.tests.evalReports.dir` | `'.eval-reports'` | 存放引擎报告的工作区相对目录。 |
202
- | `gate.tests.evalReports.file` | `'report.json'` | 目录内的报告文件名。 |
203
- | `gate.tests.evalReports.required` | `false` | 为 true 时缺失报告即为红灯(否则跳过)。 |
204
- | `gate.consistency.*` | `provider: 'fork'`、`model: null`、`tools: ['read','glob','grep']`、`timeoutMs: 120000`、`maxFindings: 5` | 本地一致性评审者的旋钮(`model: null` = 主模型)。 |
205
- | `gate.review.engine` | `'auto'` | `auto` = 存在时使用 dsh-auto-review 的裁决记录,否则使用本地评审者;`local` = 始终使用本地评审者。 |
206
- | `gate.review.provider` | `'fork'` | 本地评审评审者的提供者(其 `model`/`tools`/`timeoutMs`/`maxFindings` 与 `gate.consistency.*` 相同)。 |
207
-
208
- 上表中每个 `gate.*` 键都属于同一个**活动字段**:守卫行把整个 `gate` 块标记为 `.volatile()`,因此它就是该行的可编辑设置卡片(表单命名空间即该行的 profile 条目 id)。其余键是来自 profile patch 的普通 composition 配置。该块在加载时读取一次,所以编辑在下次加载生效——`gate.enabled` 决定回合边界的红灯提示是否安装。若宿主的 schemastery 早于 `.volatile()`,本行照旧挂载:没有卡片,该块仍取自 profile patch。
209
-
210
- 配置错误会在加载时大声失败:无效的正则、空或重复的名称列表、越界阈值、重复的清单 id 都会抛错,而不是悄无声息地什么都不做。`strict.patch.yml` 是全门禁阻断覆盖层,以 `intensity: block` 重新声明守卫行,开启所有模块并要求覆盖率。
211
-
212
- ## 工具与界面
213
-
214
- | 界面 | 类型 | 说明 |
215
- |---|---|---|
216
- | `doublecheck_skills` | 工具 | 通过技能注册表接口列出并加载包内四个内置技能。 |
217
- | `doublecheck_spec` | 工具 | 将拷问得出的六维 spec 提交到会话日志和工作区 markdown 副本。 |
218
- | `doublecheck_report` | 工具 | 将纪律证据折叠为交付报告(可选的按维度验证工作流)。 |
219
- | `/doublecheck status\|report\|on\|off` | 命令 | 开关、模块、强度、阶段事实、折叠报告,以及持久的开/关覆盖。 |
220
- | `/gate status\|run\|config` | 命令 | 实时清单进度、已确定的可交付/返工报告,以及生效配置。 |
221
- | `grill-requirements`、`red-green-tdd`、`delivery-review`、`delivery-proof` | 技能 | 覆盖全部六个闭环阶段的内置纪律技能。 |
222
- | `gate` | 活动配置字段 | 可插拔清单是守卫行唯一的 `.volatile()` 字段:从该行的设置卡片编辑(命名空间 = 该行的 profile 条目 id),在加载时读取一次。 |
223
- | `strict.patch.yml` | 覆盖层 | 一个补丁层内以 `block` 强度开启每个门禁并启用覆盖率要求。 |
224
- | `dsh-doublecheck/invariant` | 伴生行 | 通过宿主 `invariants` 注册表报告包自有写路径矛盾。 |
225
- | `doublecheck` | 会话投影 | 客户端渲染的一行有界状态:阶段、最近裁决、红灯数、编辑数与 spec/review 标记。见[如何读这一行](#如何读这一行)。 |
226
-
227
- ### 如何读这一行
228
-
229
- `doublecheck` 会话投影是一个**字符串**,而且刻意只有一行——这样任何客户端都能完整显示它、不会切掉任何内容。聊天桥的 `/status`、状态栏或任何自定义消费者都原样渲染:
230
-
231
- ```text
232
- gate:rework r2 | stage:green | test:green edits:12 spec:yes review:yes | goal:ship parser fix
233
- ```
234
-
235
- | 片段 | 读法 |
236
- |---|---|
237
- | `gate:<裁决> r<n>` | 最近一次交付门禁的裁决——未运行时是 `none`,否则是 `deliverable` 或 `rework`——以及它的红灯数 `r<n>`。 |
238
- | `stage:<阶段>` | 依据持久证据到达的纪律阶段:`grill`、`design`、`red`、`green`、`review`、`verify`。 |
239
- | `test:<颜色>` | 最近一次测试运行的颜色:`none`、`red`、`green`。 |
240
- | `edits:<n>` | 从会话日志折叠出的实现编辑数(写测试文件不计入)。 |
241
- | `spec:yes` / `spec:no` | 日志中是否存在已提交的 `doublecheck_spec`。 |
242
- | `review:yes` / `review:no` | 是否存在对手审查记录。 |
243
- | `goal:<摘录>` | 已提交的 spec 目标,会被裁剪。仅当 `spec:yes` 时出现。 |
244
-
245
- 这一行的长度**由构造保证有界**,因此不会被任何渲染器截断:
246
-
247
- - 硬预算:**120 个字符**。凡是原样保留 120 字符以内取值的渲染器——微信桥的通用投影渲染器就是其中之一——都会完整显示这一行。旧的「对象」形态**空态就有 131 个字符**,这正是裁决与红灯数过去总被切掉的原因。
248
- - 前三段是**无损的**。红灯数超过 `9999`、编辑数超过 `99999` 时打印为 `9999+` / `99999+`,而不会无限增长;非有限值或负数打印为 `0`。
249
- - `goal:` 是唯一有损的一段。它会被压成单行(换行与控制字符变空格,`|` 变 `/`),并裁剪到剩余预算,最多 40 个字符,被裁剪时以 `…` 结尾。完整目标见 `/doublecheck status` 与交付报告。
250
- - 这是一眼速览,不是记录本身:`/gate status` 与 `/doublecheck status` 渲染完整状态。
251
-
252
- 该投影的 `stateVersion` 为 **3**。递增它会丢弃旧版本写入的持久化投影缓存行,并以该键从会话日志重新折叠,因此升级后的会话会重算这一行,而不是显示过期值。折叠状态本身没有变化,升级前的会话不会因此加载失败。
253
-
254
- ## 门禁阶段
255
-
256
- 交付门禁把会话的持久证据聚合为可配置的四阶段清单,并确定一个 **可交付 / 需要返工** 的裁决。每个阶段只折叠会话日志(重放即状态),因此一次运行在恢复或分叉后会得到相同的结果。
257
-
258
- | 阶段 | 检查 | 证据来源 | 模型成本 |
259
- |---|---|---|---|
260
- | 需求询问 | 逐项确认的关键问题清单(默认六个 spec 维度问题) | 已提交的 `doublecheck_spec` + `ask_user_question` 调用 | 无 |
261
- | 测试证据 | 最近运行颜色、绿色后的失败运行、可选覆盖率阈值、可选 dsh-eval 报告 | 会话日志中的 shell 测试运行(`[exit code: N]`、覆盖率百分比);开启 `gate.tests.evalReports.enabled` 时的 dsh-eval 报告文件 | 无 |
262
- | 实现一致性 | 差异 ↔ 需求映射:每次改动都必须服务于某个 spec 维度 | 本地分叉评审者(结构化发现、只读工具) | 一个 subagent |
263
- | 评审结论 | 交付裁决;`engine: auto` 在存在时消费 dsh-auto-review 的持久裁决记录,否则使用本地评审者 | `autoReview/verdict` / `autoReview/rejection` 事件,或本地分叉评审者 | 一个 subagent(本地) |
264
-
265
- 红灯是失败的检查(缺失 spec、最近运行失败、覆盖率低于下限、未映射的改动、blocker/major 发现)——每一项都附带返工建议。警告与跳过永远不会翻转裁决。门禁将 [dsh-auto-review](https://github.com/PerryLink/dsh-auto-review) 作为弱依赖集成:`review.engine: auto` 在存在时折叠其裁决记录,否则降级到本地评审者;`gate.tests.evalReports.enabled` 把其评测引擎的 dsh-eval 报告(prompt 回归 / 压测 / 公平性套件)并入测试证据,并在报告不存在时如实跳过。门禁从不合成审批请求。
266
-
267
- ## 示例报告
268
-
269
- `/gate run` 返回这份 markdown——可直接粘贴到 PR 描述中:
270
-
271
- ````markdown
272
- # Delivery gate report
273
-
274
- > **Verdict: rework required** — 2 red item(s)
275
- > The gate is red. Re-open the work in plan mode to re-check the open items before delivering.
276
-
277
- ## 1. Requirements interrogation — PASS
278
- - [✔] **What outcome must the delivery produce?** — spec dimension "goal" committed
279
- - [✔] **What is in scope, and what is out of scope?** — spec dimension "scope" committed
280
- - [✔] **Which observable checks prove the work is done?** — spec dimension "acceptanceCriteria" committed
281
- - [✔] **What can go wrong, and what is the correct behavior in each case?** — spec dimension "failureModes" committed
282
- - [✔] **What is traded when goals conflict; what is optional?** — spec dimension "priorities" committed
283
- - [✔] **What does the user explicitly not want?** — spec dimension "nonGoals" committed
284
-
285
- ## 2. Test evidence — FAIL
286
- - [✔] **passing test run** — latest test run passed
287
- - [✔] **failing cases after green** — 0 failing run(s) after green (allowed: 0)
288
- - [✖] **coverage evidence** — 61% coverage below the 80% minimum — rework: raise coverage above the configured minimum
289
-
290
- ## 3. Implementation consistency — WARN
291
- - [⚠] **[minor] src/telemetry.ts touched without a requirement** — [minor] the edit adds a metric no spec dimension covers
292
-
293
- ## 4. Review conclusion — PASS
294
- - [✔] **dsh-auto-review conclusion** — 3 call(s) approved by dsh-auto-review (latest risk: low)
295
-
296
- ## Red items
297
- 1. **tests/coverage** — 61% coverage below the 80% minimum — *rework: raise coverage above the configured minimum*
298
- 2. **consistency/finding-1** — [minor] the edit adds a metric no spec dimension covers — *rework: src/telemetry.ts touched without a requirement*
299
-
300
- ## Audit
301
- - review engine: dsh-auto-review
302
- - generated at: 2026-08-14T12:00:00.000Z
303
- - counts, ids, and verdicts only: no file contents or session text are embedded, and recognized secrets are redacted.
304
- ````
305
-
306
- ## CI 输出
307
-
308
- `/gate run` 还会写一个 `gate-report.json`(与无损 JSON 相同的已定状态,位于 `gate-report.md` 旁边)。`doublecheck-gate` CLI 把该文件转成可供 GitHub Actions 使用的机器可读输出:
309
-
310
- ```sh
311
- # JSON(PR 评论 / 状态载荷)
312
- doublecheck-gate --format json --input gate-report.json
313
- # SARIF 2.1.0(code-scanning 上传 / 状态检查)
314
- doublecheck-gate --format sarif < gate-report.json
315
- ```
316
-
317
- CLI 只序列化已定的 `GateState` —— 它从不重新运行四阶段门禁或证据折叠。其退出码映射裁决:`0` = 可交付,`1` = 返工,`2` = 用法/解析错误。
318
-
319
- ## 权限与数据
320
-
321
- - **读取**:仅进程内读取会话日志(`tool/call` / `tool/result` / `tool/ptc-dispatch`、注入的 `user/message` 来源,以及外部的 `autoReview/*` 裁决记录);可选的计划模式服务状态。V3 改名前的宿主用旧标签 `tool/code-dispatch` 记录 PTC 子调用;两个标签折叠结果完全一致。注入的提示携带本包自有的 `dsh-doublecheck` 消息来源 kind;该 kind 出现之前记录的日志会以 `plugin:dsh-doublecheck`(宿主 V3→V4 迁移对已发布的 catch-all 包装所做的改写)或已发布的 `plugin` 包装抵达,三种形态折叠结果一致。
322
- - **写入**:会话工作区中的 `doublecheck-spec.md`、`doublecheck-report.md` 和 `gate-report.md`(路径可配置),通过 `ctx.fs` 接口;持久的 `doublecheck/state` 和 `doublecheck/gate` 会话事件。
323
- - **模型调用**:门禁的一致性阶段和本地评审阶段(每次 `/gate run` 各一个 subagent)、可选的对抗式评审,以及 `doublecheck_report` 验证工作流会启动 subagent 运行;除此之外不调用模型或网络。
324
- - **绝不触碰**:凭据、环境变量,或会话工作区之外的任何文件。workshop 清单只声明 `filesystem:read` 和 `filesystem:write`。门禁报告只携带计数、id 和裁决;评审文本中被识别的机密在存储或显示之前会被脱敏。
325
-
326
- ## 安全边界
327
-
328
- - **模型可见 ⟺ 已记录。** 每条注入的提醒、评审和门禁通知都经由标准通道并落入会话日志;持久的 spec/state/gate 事实经由工具结果或 `SessionEventMap` 成员。
329
- - **失败关闭 / 大声失败。** 守卫和门禁配置在 `apply` 中校验(断言抛错);无法运行的评审者或对抗式接口会退化为诚实的 "unavailable"/跳过通知,而非伪造裁决。
330
- - **审计安全报告。** 门禁和交付报告只记录计数、id 和裁决——不含文件内容或会话文本——模型生成的发现文本在存储或显示之前会经过机密脱敏器。
331
- - **自身无网络。** 该插件不发起直接网络请求;批评者和评审者 subagent 经由宿主的 subagent 接口运行。
332
- - **对 dsh-auto-review 的弱依赖。** 它从不被 import 或硬性要求;门禁折叠其持久裁决记录并降级到本地评审者,且从不合成审批请求。
333
-
334
- ## 已知限制
335
-
336
- - **持久写入。** `/doublecheck on\|off` → `doublecheck/state` 与 `/gate run` → `doublecheck/gate` 需要宿主的 `ignorable` 追加接口(rc.6 之后至 `0.1.1-rc.2`)。在无此接口的宿主上(rc.6/rc.8,以及移除该信封的 `0.1.2-alpha.1`——`0.1.2-rc.1` 仅恢复存量日志读取兼容字段、仍无法盖章),写入被跳过、开关保持进程内状态。
337
- 0.1.2-rc.1(2026-09-02 已适配):会话信封保留 ignorable 字段但仅用于存量日志读取兼容——Session.append 仍无法盖章,门控行为不变。
338
- 0.1.5-alpha.1(2026-09-09 已适配):会话格式 V3 把持久子调用事件 `tool/code-dispatch` 改名为 `tool/ptc-dispatch`(载荷不变;两个标签折叠结果一致)。Session.append 仍无 `ignorable` 写入通道,写入继续跳过、开关保持进程内——行为不变。(该条引入的 `doublecheck-gate` 设置命名空间已在 0.1.7-alpha.1 随宿主删除命名空间注册表一并移除。)
339
- 0.1.5-rc.1(2026-09-10 已适配):依赖钉号移至已发布的 0.1.5-rc.1 线;无接口变更影响本插件行为。
340
- 0.1.5-rc.2(2026-09-11 已适配):依赖钉号移至已发布的 0.1.5-rc.2 线;无接口变更影响本插件行为。
341
- 0.1.7-alpha.1(2026-09-22 已适配):宿主删除了共享的 catch-all `plugin` 消息来源 kind(提示改携本包自有的 `dsh-doublecheck` kind,`remindOnce` 折叠仍能读取持久日志可能持有的两种升级前形态),并用 `SettingsForms` 取代了设置命名空间注册表(`doublecheck-gate` 命名空间消失;门禁清单改为守卫行唯一的 `.volatile()` 字段,仍在加载时读取一次)。`@deepseek-ai/cordis` 与 `@deepseek-ai/schemastery` 的 dev/test 钉号移至 `^4.0.3` / `^3.18.3`,即 `Volatile` 与 `.volatile()` 首次出现的版本;peer 区间仍为 `^4.0.2` / `^3.18.2`,且活动字段能力在加载时探测,因此更早的宿主线仍能挂载本行(只是没有设置卡片)。除设置存储位置外无行为变更。
342
- - **可选接口。** 挂载设置服务时会出现守卫行自己的设置卡片;该卡片就是本行自己的 Config(命名空间 = 其 profile 条目 id),`gate` 块在加载时读取一次,因此其取值在下一次加载时作用于 `/gate` 面板与红灯提示。活动字段能力在加载时探测:若宿主的 schemastery 早于 `.volatile()`,本行照旧挂载——没有卡片,`gate` 块仍取自 profile patch。`/gate status` 的计划模式行读取可选的 `ctx.planMode`(没有则显示 `unknown`);对抗式评审需要 `ctx.subagents`;验证需要 `workflowEngine`。
343
- - **本地降级。** 当 dsh-auto-review 缺失或本会话没有裁决记录时,`gate.review.engine: auto` 会降级到本地评审者——报告会写明原因,而不是捏造裁决。
344
- - **dsh-eval 证据基于文件。** dsh-auto-review 评测引擎(`dsh-eval`)把其 prompt 回归 / 压测 / 公平性结果写入工作区报告文件,而非会话日志。`gate.tests.evalReports.enabled` 折叠该文件(默认关闭;缺失时跳过),折叠出的计数随持久 `doublecheck/gate` 记录保存,使已定的运行仍可重放。
345
-
346
- ## 开发
347
-
348
- ```sh
349
- pnpm install # node ^22.19 || >=24
350
- pnpm run build # tsc --noEmitOnError (lib/ is committed)
351
- pnpm run prepare # tsc --noEmitOnError (git-install channel)
352
- pnpm run prepublishOnly # build + full test suite
353
- pnpm run typecheck # tsc --noEmit + tests tsconfig
354
- pnpm run lint # eslint src tests
355
- pnpm test # vitest run
356
- pnpm run test:coverage # vitest run --coverage
357
- pnpm run pack:check # build + pack the tarball
358
- ```
359
-
360
- ## 主题
361
-
362
- `dsh`, `dsh-plugin`, `deepseek-harness`, `engineering-discipline`, `requirements`, `guard`, `skill`, `quality-gate`, `delivery-gate`
363
-
364
- ## 贡献者
365
-
366
- - [@PerryLink](https://github.com/PerryLink) —— 创建者与维护者:grill → design → red → green → review → verify 纪律闭环、四阶段交付门禁、五语言文档,以及 CI/发布流水线。
367
-
368
- ## 与其他 DSH 插件的互操作
369
-
370
- 已对照 **DSH `0.2.0-rc.2`**(本 README 面向的运行时)与 2026-10-05 实测的高星插件集验证。
371
-
372
- 本插件**不干扰**其他插件,包括广泛安装的高星插件:
373
-
374
- - **无工具名冲突。** 所有工具都带命名空间,不占用任何已被内置工具或其他插件持有的裸名。
375
- - **无服务键冲突。** 不提供任何服务键,因此不存在服务键冲突。
376
- - **无 slot 冲突。** 不注册客户端 slot key,因此不参与 `shadows-shipped-ui` 座位争抢。
377
- - **无 HTTP 路由冲突。** 不注册任何 `webServer` 前缀。
378
- - **无 patch 层冲突。** 组合包 patch 只 `insert` 自己那一行,从不覆写内置行的 `config`。
379
- - **无全局改写。** 不改原型、不改写 `process.env`、不替换全局 fetch dispatcher。
380
-
381
- **共享事件监听器在构造上就不互相干扰。** 它用 `ctx.on()` 监听顺序敏感事件 `agent/turn-stopping`, `tools/post-execute`, `tools/pre-execute` —— Cordis 的**广播**语义:每个监听器都会运行,任何一个都无法饿死其他监听器。**此处每个监听器都通过 `next()` 委托**,因此链条绝不会被短路;改写作用在 `next()` 产出的值上,而不是用它顶替返回:
382
- - `tools/post-execute` — also used by `cc-safety-net` (1576★).
383
- - `tools/pre-execute` — also used by `cc-safety-net` (1576★).
384
-
385
- 静态证据:`dsh-plugin-doctor` 的 K10–K13 在本仓全部为 `pass`。
386
-
387
- ## PerryLink DSH Plugin Family
388
-
389
- 本项目是 [PerryLink](https://github.com/PerryLink) 维护的 DeepSeek Harness 插件家族成员。完整名单默认折叠,避免每个 README 的首屏被长表淹没;点击展开可查看每一行及其状态。
390
-
391
- <details>
392
- <summary>展开全部插件</summary>
393
-
394
- | 插件 | 状态 |
395
- |---|---|
396
- | **[dsh-aqua-input-check](https://github.com/PerryLink/dsh-aqua-input-check)** | |
397
- | **[dsh-archive-check](https://github.com/PerryLink/dsh-archive-check)** | |
398
- | **[dsh-auto-review](https://github.com/PerryLink/dsh-auto-review)** | |
399
- | **[dsh-autotier](https://github.com/PerryLink/dsh-autotier)** | |
400
- | **[dsh-bid-ca-precheck](https://github.com/PerryLink/dsh-bid-ca-precheck)** | |
401
- | **[dsh-bid-qual-check](https://github.com/PerryLink/dsh-bid-qual-check)** | |
402
- | **[dsh-cert-mcp](https://github.com/PerryLink/dsh-cert-mcp)** | |
403
- | **[dsh-checkpoint-rewind](https://github.com/PerryLink/dsh-checkpoint-rewind)** | |
404
- | **[dsh-click](https://github.com/PerryLink/dsh-click)** | |
405
- | **[dsh-composer-history](https://github.com/PerryLink/dsh-composer-history)** | |
406
- | **[dsh-contract-stance](https://github.com/PerryLink/dsh-contract-stance)** | |
407
- | **[dsh-customs-doc-check](https://github.com/PerryLink/dsh-customs-doc-check)** | |
408
- | **[dsh-data-quality](https://github.com/PerryLink/dsh-data-quality)** | |
409
- | **[dsh-demurrage-ledger](https://github.com/PerryLink/dsh-demurrage-ledger)** | |
410
- | **[dsh-doublecheck](https://github.com/PerryLink/dsh-doublecheck)** | |
411
- | **[dsh-drill-script-check](https://github.com/PerryLink/dsh-drill-script-check)** | |
412
- | **[dsh-eia-guide-check](https://github.com/PerryLink/dsh-eia-guide-check)** | |
413
- | **[dsh-emergency-plan](https://github.com/PerryLink/dsh-emergency-plan)** | |
414
- | **[dsh-essay-rubric-check](https://github.com/PerryLink/dsh-essay-rubric-check)** | |
415
- | **[dsh-evidence-check](https://github.com/PerryLink/dsh-evidence-check)** | |
416
- | **[dsh-export-ctl-check](https://github.com/PerryLink/dsh-export-ctl-check)** | |
417
- | **[dsh-fast](https://github.com/PerryLink/dsh-fast)** | |
418
- | **[dsh-fmea-table-check](https://github.com/PerryLink/dsh-fmea-table-check)** | |
419
- | **[dsh-forecast-penalty](https://github.com/PerryLink/dsh-forecast-penalty)** | |
420
- | **[dsh-fund-research](https://github.com/PerryLink/dsh-fund-research)** | |
421
- | **[dsh-github](https://github.com/PerryLink/dsh-github)** | |
422
- | **[dsh-gongwen-flow-check](https://github.com/PerryLink/dsh-gongwen-flow-check)** | |
423
- | **[dsh-gongwen-word-check](https://github.com/PerryLink/dsh-gongwen-word-check)** | |
424
- | **[dsh-guard-plan-qc](https://github.com/PerryLink/dsh-guard-plan-qc)** | |
425
- | **[dsh-hazchem-check](https://github.com/PerryLink/dsh-hazchem-check)** | |
426
- | **[dsh-hazplan-check](https://github.com/PerryLink/dsh-hazplan-check)** | |
427
- | **[dsh-hidden-risk-map](https://github.com/PerryLink/dsh-hidden-risk-map)** | |
428
- | **[dsh-hs-classify](https://github.com/PerryLink/dsh-hs-classify)** | |
429
- | **[dsh-icd-rule-check](https://github.com/PerryLink/dsh-icd-rule-check)** | |
430
- | **[dsh-industry-research](https://github.com/PerryLink/dsh-industry-research)** | |
431
- | **[dsh-lawcite-adapter](https://github.com/PerryLink/dsh-lawcite-adapter)** | |
432
- | **[dsh-laya](https://github.com/PerryLink/dsh-laya)** | |
433
- | **[dsh-lc-doc-check](https://github.com/PerryLink/dsh-lc-doc-check)** | |
434
- | **[dsh-learning-gap-check](https://github.com/PerryLink/dsh-learning-gap-check)** | |
435
- | **[dsh-library](https://github.com/PerryLink/dsh-library)** | |
436
- | **[dsh-local-ai](https://github.com/PerryLink/dsh-local-ai)** | |
437
- | **[dsh-lsp-actions](https://github.com/PerryLink/dsh-lsp-actions)** | |
438
- | **[dsh-mask](https://github.com/PerryLink/dsh-mask)** | |
439
- | **[dsh-mcp-panel](https://github.com/PerryLink/dsh-mcp-panel)** | |
440
- | **[dsh-medrec-qc](https://github.com/PerryLink/dsh-medrec-qc)** | |
441
- | **[dsh-memento](https://github.com/PerryLink/dsh-memento)** | |
442
- | **[dsh-nsfc-form-check](https://github.com/PerryLink/dsh-nsfc-form-check)** | |
443
- | **[dsh-nurse-record-check](https://github.com/PerryLink/dsh-nurse-record-check)** | |
444
- | **[dsh-observe](https://github.com/PerryLink/dsh-observe)** | |
445
- | **[dsh-origin-rvc-check](https://github.com/PerryLink/dsh-origin-rvc-check)** | |
446
- | **[dsh-ota-review-check](https://github.com/PerryLink/dsh-ota-review-check)** | |
447
- | **[dsh-output-styles](https://github.com/PerryLink/dsh-output-styles)** | |
448
- | **[dsh-paper-doc-adapter](https://github.com/PerryLink/dsh-paper-doc-adapter)** | |
449
- | **[dsh-permission-rules](https://github.com/PerryLink/dsh-permission-rules)** | |
450
- | **[dsh-permit-report-check](https://github.com/PerryLink/dsh-permit-report-check)** | |
451
- | **[dsh-pipeline-check](https://github.com/PerryLink/dsh-pipeline-check)** | |
452
- | **[dsh-pleading-draft](https://github.com/PerryLink/dsh-pleading-draft)** | |
453
- | **[dsh-plugin-doctor](https://github.com/PerryLink/dsh-plugin-doctor)** | |
454
- | **[dsh-plugin-guide](https://github.com/PerryLink/dsh-plugin-guide)** | |
455
- | **[dsh-plugin-kit](https://github.com/PerryLink/dsh-plugin-kit)** | |
456
- | **[dsh-plugin-upgrade](https://github.com/PerryLink/dsh-plugin-upgrade)** | |
457
- | **[dsh-policy-brief-draft](https://github.com/PerryLink/dsh-policy-brief-draft)** | |
458
- | **[dsh-power-loss-split](https://github.com/PerryLink/dsh-power-loss-split)** | |
459
- | **[dsh-power-ticket-check](https://github.com/PerryLink/dsh-power-ticket-check)** | |
460
- | **[dsh-ppap-check](https://github.com/PerryLink/dsh-ppap-check)** | |
461
- | **[dsh-protest-deadline](https://github.com/PerryLink/dsh-protest-deadline)** | |
462
- | **[dsh-railway-window](https://github.com/PerryLink/dsh-railway-window)** | |
463
- | **[dsh-repair-order-qc](https://github.com/PerryLink/dsh-repair-order-qc)** | |
464
- | **[dsh-research-report](https://github.com/PerryLink/dsh-research-report)** | |
465
- | **[dsh-review-reply-check](https://github.com/PerryLink/dsh-review-reply-check)** | |
466
- | **[dsh-rulefile-check](https://github.com/PerryLink/dsh-rulefile-check)** | |
467
- | **[dsh-safety-brief-check](https://github.com/PerryLink/dsh-safety-brief-check)** | |
468
- | **[dsh-score](https://github.com/PerryLink/dsh-score)** | |
469
- | **[dsh-session-sync](https://github.com/PerryLink/dsh-session-sync)** | |
470
- | **[dsh-site-log-check](https://github.com/PerryLink/dsh-site-log-check)** | |
471
- | **[dsh-skill-pack-security](https://github.com/PerryLink/dsh-skill-pack-security)** | |
472
- | **[dsh-soe-decision-check](https://github.com/PerryLink/dsh-soe-decision-check)** | |
473
- | **[dsh-soilwater-check](https://github.com/PerryLink/dsh-soilwater-check)** | |
474
- | **[dsh-sop-sync-check](https://github.com/PerryLink/dsh-sop-sync-check)** | |
475
- | **[dsh-spc-gbt-adapter](https://github.com/PerryLink/dsh-spc-gbt-adapter)** | |
476
- | **[dsh-talk](https://github.com/PerryLink/dsh-talk)** | |
477
- | **[dsh-tender-extract](https://github.com/PerryLink/dsh-tender-extract)** | |
478
- | **[dsh-tender-matrix](https://github.com/PerryLink/dsh-tender-matrix)** | |
479
- | **[dsh-test-drive](https://github.com/PerryLink/dsh-test-drive)** | |
480
- | **[dsh-ticktick](https://github.com/PerryLink/dsh-ticktick)** | |
481
- | **[dsh-translate](https://github.com/PerryLink/dsh-translate)** | |
482
- | **[dsh-warranty-calc](https://github.com/PerryLink/dsh-warranty-calc)** | |
483
- | **[dsh-budget](https://github.com/PerryLink/dsh-budget)** | 🧊 已冻结 — 见仓库 README |
484
- | **[dsh-claude-move](https://github.com/PerryLink/dsh-claude-move)** | 🧊 已冻结 — 见仓库 README |
485
- | **[dsh-defend](https://github.com/PerryLink/dsh-defend)** | 🧊 已冻结 — 见仓库 README |
486
- | **[dsh-draw](https://github.com/PerryLink/dsh-draw)** | 🧊 已冻结 — 见仓库 README |
487
- | **[dsh-reach](https://github.com/PerryLink/dsh-reach)** | 🧊 已冻结 — 见仓库 README |
488
- | **[dsh-background-agents](https://github.com/PerryLink/dsh-background-agents)** | 🚫 已退役 — 见仓库 README |
489
- | **[dsh-session-pin](https://github.com/PerryLink/dsh-session-pin)** | 🚫 已退役 — 见仓库 README |
490
- | **[dsh-team-rooms](https://github.com/PerryLink/dsh-team-rooms)** | 🚫 已退役 — 见仓库 README |
491
-
492
- </details>
493
-
494
- ## 许可证
495
-
496
- [Apache License 2.0](LICENSE) © 2026 dsh-doublecheck contributors