dsh-scout 0.9.3 → 0.9.4

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/CHANGELOG.md CHANGED
@@ -4,9 +4,47 @@
4
4
 
5
5
  本文件从 0.9.1 开始记录;0.9.0 及更早版本的变更见仓库的 git tag。
6
6
 
7
+ ## [0.9.4] - 2026-11-07
8
+
9
+ **待发布**:本条目描述冻结为 0.9.4 的工作树;npm 元数据与发布 workflow 结果在发布后补记。
10
+
11
+ 0.9.4 的主题是「在真实宿主里能用 + 报告让人读得下去」:修复桌面 App 下导出写不进会话工作区的 P0,补齐主体核验的字段级证据,并把报告从「按内部数据模型平铺」重构为「按决策阶段组织」的可读结构。
12
+
13
+ ### Added
14
+
15
+ - **阶段式报告(v2)**:`report.md` 重排为 30 秒结论 → 公司与主体 → 已确认的事实(业务/资本/组织)→ 线索与待确认(面试确认/外部可查/说法冲突)→ 风险与红旗(按严重度)→ 面试问题(按主题,≤12)→ 距离下一步还差什么 → 附录 A 来源表 / B 技术台账 / C 调查覆盖度 / D 术语表。正文不再出现 E0–E3、source id 或内部枚举,改用人话标签与短来源名 + 采集日期;E 码只保留在附录术语表与台账。
16
+ - **主体核验分档与字段级 provenance**:`identityStatus` 增加 `corroborated`;`scout_verify_identity` 支持可选 `fieldSources`(逐字段来源,须为 `sourceIds` 子集)。E3 注册类来源支撑统一社会信用代码才算 `verified`,两个独立来源覆盖全部字段为 `corroborated`,报告与决策理由明确标注「非官方登记核验」。
17
+ - **来源元数据升级**:同一 URL 再次登记时,显式更强的 `evidenceLevel` / 不同 `sourceType` / 新标题会升级已有来源并记录 `source_updated` 事件(E3 升级仍受授权域约束)。
18
+ - **面试问题字段**:`scout_add_claim` / `scout_ingest` 支持可选 `interviewQuestion`(ingest 草稿还支持 `nextAction` / `confidenceNote`);只有显式问题与精选问题进入问题列表。
19
+ - **紧凑摘要与下一步**:搜索摘要显示新来源标题与 host,ingest 摘要区分「+N sources, +M claims」;空 case 的 `nextActions` 由状态合成(核验主体/登记来源/补必需维度)。
20
+ - **验收脚本**:新增 `scripts/acceptance-report.mjs` 与 `npm run test:acceptance`(受限文件系统 + 会话沙箱策略 + 完整 case + 工作区导出 + 冷启动回填,15 项断言)。
21
+
22
+ ### Changed
23
+
24
+ - 面试问题不再由 `claim.nextAction` 生成(研究动作不再冒充面试问题);`corroborated` 的决策理由按「是否仍有未核验结论」分两种措辞。
25
+ - URL 去重归一化会剥掉 `utm_*` / `hmsr` 等追踪参数;来源类型推断新增 App Store → `company_official`、中文工商聚合站 → `public_database`。
26
+ - `scout_import` 校验来源/claim 的枚举与字段,非法等级不再被 `NaN` 比较放过;旧导出仍可导入。
27
+ - **zh-CN 报告字节基线随本轮报告重构更新**(0.9.3 起的「除 Coverage 外逐字节不变」在 0.9.4 明确升级为阶段式报告新基线;`tests/model.test.mjs` 的 golden 已同步)。
28
+
29
+ ### Fixed
30
+
31
+ - **P0 · 桌面宿主导出失败**:导出 / `autoPersist` 未向受限 fs 后端传 per-call 沙箱策略,桌面 App 下写会话工作区被 `FS_SANDBOX_DENIED` 拒绝(只有临时目录可写)。现在从 `sandboxPolicy.resolve({session})` 取策略并作为 `writeText` 第 5 参数传入;失败时附可执行提示。
32
+ - `/scout export <caseId> [targetDir]` 冷启动不回填、`[targetDir]` 被静默忽略:现在与工具同一状态机并真正使用 targetDir。
33
+ - 冷启动后同名 `scout_start` 静默覆盖磁盘完成导出(数据丢失):现在默认拒绝,提示 `scout_import` / 换 id / `overwrite:true`。
34
+ - 同一 URL 二次登记静默丢弃显式元数据;重复 ingest 同一批 claim 导致台账翻倍。
35
+ - `caseId` 可含 `../`、公司名/岗位可为空;`fieldSources` 可引用 `sourceIds` 之外的来源。
36
+
37
+ ### Known boundaries
38
+
39
+ - 兼容矩阵新增本轮实测宿主 **dsh 0.2.1-rc.5**;`engines.dsh` 范围通过不等于 fs 写语义通过,桌面安装后仍需人工复测一次默认 `scoutDir` 导出与冷启动回填。
40
+ - `corroborated` 只是决策可用的分档,不改变 E3 证据定义;PROCEED 仍要求所有非 informational claim 与三个必需岗位维度 verified(决策语义拆分留给 0.10.0)。
41
+ - 验收脚本是真实插件代码 + 真实 fs 沙箱契约 + 脚本驱动,不经过 LLM agent loop。
42
+
7
43
  ## [0.9.3] - 2026-10-13
8
44
 
9
- **待发布**:本条目描述冻结为 0.9.3 的工作树;npm 元数据(tarball / shasum / integrity / provenance / git tag)在发布后补记。
45
+ **已发布**(2026-10-13):npm `dsh-scout@0.9.3`(`dist-tags.latest` = `0.9.3`),tarball `https://registry.npmjs.org/dsh-scout/-/dsh-scout-0.9.3.tgz`(**23 个文件**),shasum `45d3dc0d3b2e61840c8549bd8021798fae32b8c3`,integrity `sha512-x88Ar9Oi8RUK/PNtG/akox+MCJFBD2ajP95MwWGiodNtoDsz4Zsm4tx2BQU9KjChYq/YZnr1aWBl/uGYPWduqg==`,带 **Sigstore provenance**(透明日志 `https://search.sigstore.dev/?logIndex=3245268322`),由 GitHub Actions 以 `npm publish --provenance --access public` 发布;git tag `v0.9.3`(annotated,指向 `3634c2c`)与 GitHub Release `v0.9.3`(附件 `dsh-scout-0.9.3.tgz`,158,725 B)同批创建;发布 workflow run `38428072425` success(2026-10-13 16:08:46Z → 16:29:14Z,约 20 分 28 秒:四版本 release gate → `pnpm pack` → npm publish → GitHub Release)。发布前验收:`npm test` **134/134**、`test:profile` PASS(六步真实宿主链)、`pnpm pack` 23 个文件、`env -u DSH_BIN npm run check:release` **4/4 PASS**;独立验证 [verification-0.9.3.md](docs/verification-0.9.3.md)(仓库文档,不在 npm 包内)判定 **GO**。
46
+
47
+ **发布时移动过一次 tag,如实记录**:首次 tag `v0.9.3` 指向 `6b8b9ab`,release workflow run `38426795876` 在 14 秒内(job 15:59:47Z → 16:00:01Z)挂在 `Run the release gate`——验证套件 V4 派生一个子进程跑出厂 README 守卫,却把断言压在 spec reporter 的汇总行上;Node 的默认 test reporter 跨大版本不稳定(CI 的 Node 22 对管道子进程打印 TAP 的 `# fail 0`,本地 Node 26 打印 spec 的 `fail 0`),子进程两种情况下都 18/18 通过,断言只在 CI 用的 Node 22 上失败。**当时 `Pack the tarball` / `Publish to npm` / `Create GitHub Release with tarball` 全部 skipped,没有任何东西发出去。** 修复提交 `3634c2c`(子进程固定到 TAP reporter、断言改读 TAP 失败数与退出码、用 `process.execPath`、剥离 `NODE_OPTIONS` 里的 test-runner 旗标)后删除 tag 并重建,第二次 run `38428072425` 成功。这是本轮"本地绿、CI 红"的实例:0.9.3 的全部工作就是把静默漂移变成可见失败,而这次先被拦下的是发布流程自己。
10
48
 
11
49
  0.9.3 的主题是**安装体验**,不加功能、不改运行时契约。缘起是一份在真实桌面 App 上完整走完安装的评审:README 的「三条已验证路径」对桌面 App 用户**全部不可用**——桌面版的 `desktop` profile 被 Electron 应用独占,CLI 对它的所有 `dsh plugin` 子命令都按 profile 名硬拒绝(`error: profile "desktop" is managed exclusively by the Electron application`,连兼容性逃生门 `allow-version` 一起拒绝),而桌面 App 恰恰是这类插件最主流的入口。本版把「App 内安装」补成主路径,并给安装补上可执行的判据。
12
50
 
package/README.en.md CHANGED
@@ -123,7 +123,7 @@ error: profile "desktop" is managed exclusively by the Electron application
123
123
  That is a hard refusal **by profile name**, so **every** `dsh plugin` subcommand against it is rejected — including `allow-version` in the compatibility section below. Install from the **sidebar → Plugins page** (install, enable, and remove all live there) instead:
124
124
 
125
125
  ```sh
126
- dsh-scout@0.9.3
126
+ dsh-scout@0.9.4
127
127
  ```
128
128
 
129
129
  > Always pin the exact version. pnpm ≥ 11 enables minimum-release-age supply-chain protection by default, so a bare package name silently skips a just-released version and falls back to an older one (installing right after 0.9.2 shipped resolved to 0.9.0); with an exact version pnpm records it under the profile's `minimumReleaseAgeExclude` (it prints `Added 1 entry to …`).
@@ -134,7 +134,7 @@ No restart is needed: the 12 `scout_*` tools are injected into the current sessi
134
134
 
135
135
  ```sh
136
136
  # Replace <your-profile> with your own profile name — do not copy the example verbatim
137
- dsh plugin --profile <your-profile> add dsh-scout@0.9.3
137
+ dsh plugin --profile <your-profile> add dsh-scout@0.9.4
138
138
  ```
139
139
 
140
140
  <details>
@@ -154,8 +154,8 @@ Every name it lists is a usable profile (e.g. `web`, or one you created). `deskt
154
154
  ### Path 2: local tarball (offline / reproducible)
155
155
 
156
156
  ```sh
157
- pnpm pack # produces dsh-scout-0.9.3.tgz
158
- dsh plugin --profile <your-profile> add "file:$PWD/dsh-scout-0.9.3.tgz"
157
+ pnpm pack # produces dsh-scout-0.9.4.tgz
158
+ dsh plugin --profile <your-profile> add "file:$PWD/dsh-scout-0.9.4.tgz"
159
159
  ```
160
160
 
161
161
  ### Other install sources, and the trade-off
@@ -164,9 +164,9 @@ dsh plugin --profile <your-profile> add "file:$PWD/dsh-scout-0.9.3.tgz"
164
164
  |---|---|---|---|
165
165
  | npm (path 1) | yes, ships `dist/` | no (`pendingBuilds: []` measured) | **recommended** |
166
166
  | local tarball (path 2) | yes (the `pnpm pack` output) | no | offline / self-test |
167
- | git: `github:MaxHou-infinity/dsh-scout#v0.9.3` | no (`dist/` is not committed) | yes — `prepare` runs `tsc` and installs devDependencies | **not recommended**; only for unreleased commits |
167
+ | git: `github:MaxHou-infinity/dsh-scout#v0.9.4` | no (`dist/` is not committed) | yes — `prepare` runs `tsc` and installs devDependencies | **not recommended**; only for unreleased commits |
168
168
 
169
- The git ref must be a **real tag or commit**: the repository has 10 tags since `v0.3.0` (`v0.3.0` … `v0.9.2`; `v0.9.1` was a local iteration and was never tagged), and this release creates `v0.9.3`. Git is also the only path that executes code: `dist/` is not committed, so it always builds locally, and pnpm may require an explicit `allowBuilds` entry for `dsh-scout` (only allow a pinned version you have reviewed).
169
+ The git ref must be a **real tag or commit**: the repository has 11 tags since `v0.3.0` (`v0.3.0` … `v0.9.3`; `v0.9.1` was a local iteration and was never tagged), and this release creates `v0.9.4`. Git is also the only path that executes code: `dist/` is not committed, so it always builds locally, and pnpm may require an explicit `allowBuilds` entry for `dsh-scout` (only allow a pinned version you have reviewed).
170
170
 
171
171
  > The desktop app bundles its own node / pnpm runtime (measured: node 24.21.0 + pnpm 11.7.0), so you do **not** need Node installed; the "Node ≥ 22.19" requirement applies to the CLI / gate paths only.
172
172
 
@@ -174,10 +174,10 @@ The git ref must be a **real tag or commit**: the repository has 10 tags since `
174
174
 
175
175
  **Desktop app**
176
176
 
177
- 1. **Sidebar → Plugins page**: `dsh-scout` appears under Installed; **open its detail page** — the title carries a `v0.9.3` tag, and the version lives only on this page (list cards carry only the Experimental / Problem status tags);
177
+ 1. **Sidebar → Plugins page**: `dsh-scout` appears under Installed; **open its detail page** — the title carries a `v0.9.4` tag, and the version lives only on this page (list cards carry only the Experimental / Problem status tags);
178
178
  2. **Settings → Built-in plugins → Plugin list**: the `dsh-scout` row carries the **Enabled** tag and the **Running** status — not **Disabled** / **Failed** / **Conditional** (this page shows **no version**);
179
179
  3. start a new turn — 12 `scout_*` tools appear in the tool list;
180
- 4. `/scout status <caseId>` resolves and its output ends with the plugin version (`· dsh-scout 0.9.3`) — with no stderr or logs on desktop, this is the surface that proves which version actually loaded.
180
+ 4. `/scout status <caseId>` resolves and its output ends with the plugin version (`· dsh-scout 0.9.4`) — with no stderr or logs on desktop, this is the surface that proves which version actually loaded.
181
181
 
182
182
  **CLI**
183
183
 
@@ -201,11 +201,13 @@ Use the **sidebar → Plugins page** on desktop to upgrade / remove. A failed in
201
201
 
202
202
  ### DSH compatibility
203
203
 
204
- DSH compatibility has **three layers** — do not conflate them:
204
+ The following table records **historical DSH 0.2.0-rc.2 behavior**. As of 2026-10-29, the [current official rules](https://deepseek-harness.github.io/deepseek-harness/develop/basic/publish) prioritize `engines.dsh`, falling back to DSH peer ranges only when it is absent. This plugin declares the same range in both places.
205
+
206
+ That older runtime has three compatibility layers:
205
207
 
206
208
  | Layer | Where | Who enforces it | What happens on mismatch |
207
209
  |---|---|---|---|
208
- | **Declaration** | `package.json` → `engines.dsh` (`>=0.1.0-rc.6 <0.3.0-0`) | **Nothing reads it today** (the DSH 0.2.0-rc.2 runtime never reads `engines.dsh`; the official manifest comment says *"DSH compatibility is declarative until a reader enforces it"*) | Expresses author intent only; blocks nothing |
210
+ | **Declaration** | `package.json` → `engines.dsh` (`>=0.1.0-rc.6 <0.3.0-0`) | **That version does not read it** (the DSH 0.2.0-rc.2 runtime never reads `engines.dsh`; the official manifest comment says *"DSH compatibility is declarative until a reader enforces it"*) | Expresses author intent only; blocks nothing |
209
211
  | **Enforced** | The ranges in `peerDependencies` whose names are `@deepseek-ai/dsh` / `@deepseek-ai/dsh-*` (this repo has exactly one: `@deepseek-ai/dsh-tools: ">=0.1.0-rc.6 <0.3.0-0"`) | DSH install checks + the profile startup preflight `evaluatePluginCompatibility()` | Install is refused, or the plugin row is disabled at startup |
210
212
  | **Not enforced** | `@deepseek-ai/cordis: ">=4.0.2 <5"` (and `@deepseek-ai/schemastery`) | DSH's peer name filter only accepts `@deepseek-ai/dsh` / `@deepseek-ai/dsh-*` | Resolved by pnpm; DSH makes no compatibility judgement |
211
213
 
@@ -238,7 +240,7 @@ Granting requires explicit risk acceptance (CLI `--accept-risk`, plugin manager
238
240
 
239
241
  ```json
240
242
  {
241
- "dsh-scout@0.9.3": ["0.2.0-rc.2"]
243
+ "dsh-scout@0.9.4": ["0.2.1-rc.5"]
242
244
  }
243
245
  ```
244
246
 
@@ -246,20 +248,22 @@ A hand-written grant is bound by the same four boundaries above (exact versions
246
248
 
247
249
  #### Verified version matrix
248
250
 
249
- **The `dsh-scout@0.9.3` candidate tarball passed on four exact DSH versions** (before this release, 2026-10-13, isolated profiles, all four binaries fetched from npm rather than the local DSH): covering installation, cold startup, tool mounting, the **six-step real-host gate** (`scout_start` → export → cold restart → lazy rehydration → cross-language import → uninstall, plus the "marker missing / `complete:false`" negative controls), and unload. The full gate runs through `npm run check:release`; measured output:
251
+ **`dsh-scout@0.9.4` passed on four exact DSH versions** (before the release, 2026-11-07, isolated profiles, all four binaries fetched from npm rather than the local DSH): covering installation, cold startup, tool mounting, the **six-step real-host gate** (`scout_start` → export → cold restart → lazy rehydration → cross-language import → uninstall, plus the "marker missing / `complete:false`" negative controls), and unload. The full gate runs through `npm run check:release`; measured output:
250
252
 
251
253
  ```text
252
254
  dsh-scout release gate: PASS (4 DSH versions, >=0.1.0-rc.6 <0.3.0-0)
253
255
  ```
254
256
 
255
- | DSH version | npm channel (checked 2026-10-12) | 0.9.3 (candidate tarball) |
257
+ | DSH version | npm channel (checked 2026-10-12) | 0.9.4 (candidate tarball) |
256
258
  | --- | --- | --- |
257
259
  | `0.1.0-rc.6` | Declared lower bound | Pass |
258
260
  | `0.1.2-rc.1` | Older release regression | Pass |
259
261
  | `0.2.0-rc.2` | `latest` / `next` | Pass |
260
262
  | `0.2.1-alpha.2` | `alpha` | Pass |
261
263
 
262
- This table previously recorded the **0.9.0** and **0.9.1** candidate tarball results; 0.9.3 keeps the identical `peerDependencies` and `engines.dsh` ranges (**unchanged**) — this version changes the install docs and the diagnostic surface (the desktop-app path in the install chapter, the README version-reference guard, and the plugin version in `/scout status`), not dependencies or the runtime contract — and it passed the same gate again on the same four exact versions (4/4), so the table is updated to this version. The npm-channel column is still the 2026-10-12 check; this re-run did not re-check it. The previous release, **0.9.2, is published on npm** (`dist-tags.latest` = `0.9.2`): the release workflow (run `38406696598`) ran the same four-version gate before `pnpm pack`, so the 0.9.2 four-version pass this table recorded at the time is the exact artifact that shipped. The `/scout` command and Skill added in 0.9.1 are optional bindings, skipped silently on hosts without the corresponding services, so they do not affect loading.
264
+ This table previously recorded the **0.9.0**, **0.9.1**, and **0.9.3** candidate/released results; 0.9.4 keeps the identical `peerDependencies` and `engines.dsh` ranges (**unchanged**) — this version changes the runtime fs sandbox seam, the stage-based report, and the evidence tiers — and it passed the same gate again on the same four exact versions (4/4), so the table is updated to this version. The previous release, **0.9.3, is published on npm** (`dist-tags.latest` = `0.9.3`): the release workflow (run `38428072425`) ran the same four-version gate before `pnpm pack`, so the four-version pass this table recorded at the time is the exact artifact that shipped. **0.9.2 is published on npm** (`dist-tags.latest` = `0.9.2`): the release workflow (run `38406696598`) ran the same four-version gate before `pnpm pack`. The npm-channel column is still the 2026-10-12 check; this re-run did not re-check it. The `/scout` command and Skill added in 0.9.1 are optional bindings, skipped silently on hosts without the corresponding services, so they do not affect loading.
265
+
266
+ 2026-10-29 verification-script repair: nightly checks use Node 24 for the Node ≥24.9 requirement of DSH `0.2.2-alpha.2`. The verifier selects single-call or batch execution via the public `setExecutor` capability, checks result cardinality and call IDs, and never retries failures. This repair is not yet published to npm; see the [verification record](docs/verification-dsh-2026-10-29.md).
263
267
 
264
268
  Future `0.2.x` versions still require runtime verification. The [nightly compatibility workflow](https://github.com/MaxHou-infinity/dsh-scout/actions/workflows/compatibility-nightly.yml) resolves npm's `latest`, `next`, and `alpha` tags to exact versions before running tests and the isolated profile check. The badge shows the latest workflow result; this table records versions already verified.
265
269
 
package/README.md CHANGED
@@ -123,7 +123,7 @@ error: profile "desktop" is managed exclusively by the Electron application
123
123
  这是 CLI 里**按 profile 名**的硬拒绝,该 profile 的**所有** `dsh plugin` 子命令都会命中——包括下面兼容性小节里的 `allow-version`。请在**侧边栏 → 插件页**(安装、启用、移除都在这一页)里安装:
124
124
 
125
125
  ```sh
126
- dsh-scout@0.9.3
126
+ dsh-scout@0.9.4
127
127
  ```
128
128
 
129
129
  > 版本务必显式写死。pnpm ≥ 11 默认启用最小发布年龄(minimum release age)供应链保护,裸包名会让刚发布的版本被静默跳过、回退到旧版(0.9.2 发布后立即安装曾解析到 0.9.0);写上精确版本后 pnpm 会把它记入 profile 的 `minimumReleaseAgeExclude`(输出里打印 `Added 1 entry to …`)。
@@ -134,7 +134,7 @@ dsh-scout@0.9.3
134
134
 
135
135
  ```sh
136
136
  # 把 <your-profile> 换成你自己的 profile 名,不要照抄示例
137
- dsh plugin --profile <your-profile> add dsh-scout@0.9.3
137
+ dsh plugin --profile <your-profile> add dsh-scout@0.9.4
138
138
  ```
139
139
 
140
140
  <details>
@@ -154,8 +154,8 @@ ls ~/.dsh/profiles # 或用 $DSH_HOME/profiles
154
154
  ### 路径 2:本地 tarball(离线 / 可复现)
155
155
 
156
156
  ```sh
157
- pnpm pack # 生成 dsh-scout-0.9.3.tgz
158
- dsh plugin --profile <your-profile> add "file:$PWD/dsh-scout-0.9.3.tgz"
157
+ pnpm pack # 生成 dsh-scout-0.9.4.tgz
158
+ dsh plugin --profile <your-profile> add "file:$PWD/dsh-scout-0.9.4.tgz"
159
159
  ```
160
160
 
161
161
  ### 其他安装方式与取舍
@@ -164,9 +164,9 @@ dsh plugin --profile <your-profile> add "file:$PWD/dsh-scout-0.9.3.tgz"
164
164
  |---|---|---|---|
165
165
  | npm(路径 1) | ✅ 自带 `dist/` | ❌(实测 `pendingBuilds: []`) | **推荐** |
166
166
  | 本地 tarball(路径 2) | ✅(`pnpm pack` 产物) | ❌ | 离线 / 自测 |
167
- | git:`github:MaxHou-infinity/dsh-scout#v0.9.3` | ❌(仓库不含 `dist/`) | ✅ `prepare` 会跑 `tsc`,并安装 devDependencies | **不推荐**;只在需要未发布提交时使用 |
167
+ | git:`github:MaxHou-infinity/dsh-scout#v0.9.4` | ❌(仓库不含 `dist/`) | ✅ `prepare` 会跑 `tsc`,并安装 devDependencies | **不推荐**;只在需要未发布提交时使用 |
168
168
 
169
- git 路径的 ref 必须是**真实存在的 tag 或 commit**:仓库自 `v0.3.0` 起共 10 个 tag(`v0.3.0` … `v0.9.2`;`v0.9.1` 是本地迭代版、未打 tag),本次发布创建 `v0.9.3`。它也是三条路径里唯一会执行代码的:仓库不含 `dist/`,装完必然在本地构建,pnpm 可能要求为 `dsh-scout` 显式添加 `allowBuilds`(只放行你审查过的固定版本)。
169
+ git 路径的 ref 必须是**真实存在的 tag 或 commit**:仓库自 `v0.3.0` 起共 11 个 tag(`v0.3.0` … `v0.9.3`;`v0.9.1` 是本地迭代版、未打 tag),本次发布创建 `v0.9.4`。它也是三条路径里唯一会执行代码的:仓库不含 `dist/`,装完必然在本地构建,pnpm 可能要求为 `dsh-scout` 显式添加 `allowBuilds`(只放行你审查过的固定版本)。
170
170
 
171
171
  > 桌面 App 自带 node / pnpm 运行时(实测 node 24.21.0 + pnpm 11.7.0),**无需**安装 Node;「Node ≥ 22.19」只对 CLI / 门禁路径成立。
172
172
 
@@ -174,10 +174,10 @@ git 路径的 ref 必须是**真实存在的 tag 或 commit**:仓库自 `v0.3.
174
174
 
175
175
  **桌面 App**
176
176
 
177
- 1. **侧边栏 → 插件页**:`dsh-scout` 出现在「已安装」里;**打开它的详情页**,标题旁带 `v0.9.3`——版本号只在这一页(列表卡片上只有「实验性 / 异常」状态标签);
177
+ 1. **侧边栏 → 插件页**:`dsh-scout` 出现在「已安装」里;**打开它的详情页**,标题旁带 `v0.9.4`——版本号只在这一页(列表卡片上只有「实验性 / 异常」状态标签);
178
178
  2. **设置 → 内置插件 → 插件列表**:`dsh-scout` 行是 **已启用**、运行状态 **运行中**,不是 **已停用** / **启动失败** / **条件启用**(这一页**不显示版本号**);
179
179
  3. 新开一轮对话,工具列表里出现 12 个 `scout_*` 工具;
180
- 4. 输入 `/scout status <caseId>` 能命中命令,且输出末尾带插件版本(`· dsh-scout 0.9.3`)——桌面看不到 stderr 与日志,这是确认运行时真正加载了哪个版本的自证面。
180
+ 4. 输入 `/scout status <caseId>` 能命中命令,且输出末尾带插件版本(`· dsh-scout 0.9.4`)——桌面看不到 stderr 与日志,这是确认运行时真正加载了哪个版本的自证面。
181
181
 
182
182
  **CLI**
183
183
 
@@ -201,11 +201,13 @@ dsh plugin --profile <your-profile> remove dsh-scout # 卸载
201
201
 
202
202
  ### DSH 兼容性
203
203
 
204
- DSH 对插件的兼容性有**三个层次**,不要混为一谈:
204
+ 以下表格记录 **DSH 0.2.0-rc.2 的历史行为**。截至 2026-10-29,[官方当前规则](https://deepseek-harness.github.io/deepseek-harness/develop/basic/publish)已优先检查 `engines.dsh`,缺失时才回退检查 DSH peer 范围。本插件两处范围相同。
205
+
206
+ 在上述旧运行时中,兼容性分为三个层次:
205
207
 
206
208
  | 层次 | 位置 | 谁在执行 | 不匹配会怎样 |
207
209
  |---|---|---|---|
208
- | **声明** | `package.json` 的 `engines.dsh`(`>=0.1.0-rc.6 <0.3.0-0`) | 目前**没有任何代码**读取(DSH 0.2.0-rc.2 运行时不读 `engines.dsh`;官方 manifest 的注释写明 *"DSH compatibility is declarative until a reader enforces it"*) | 只表达作者意图,不拦截任何东西 |
210
+ | **声明** | `package.json` 的 `engines.dsh`(`>=0.1.0-rc.6 <0.3.0-0`) | 该版本**没有代码**读取(DSH 0.2.0-rc.2 运行时不读 `engines.dsh`;官方 manifest 的注释写明 *"DSH compatibility is declarative until a reader enforces it"*) | 只表达作者意图,不拦截任何东西 |
209
211
  | **生效** | `peerDependencies` 中名字为 `@deepseek-ai/dsh` / `@deepseek-ai/dsh-*` 的范围(本仓库只有 `@deepseek-ai/dsh-tools: ">=0.1.0-rc.6 <0.3.0-0"` 一条) | DSH 安装检查 + profile 启动预检 `evaluatePluginCompatibility()` | 安装阶段拒绝,或启动时禁用该插件行 |
210
212
  | **不被校验** | `@deepseek-ai/cordis: ">=4.0.2 <5"`(以及 `@deepseek-ai/schemastery`) | DSH 的 peer 名字过滤只认 `@deepseek-ai/dsh` / `@deepseek-ai/dsh-*` | 由 pnpm 解析,DSH 不做兼容判定 |
211
213
 
@@ -238,7 +240,7 @@ dsh plugin --profile <name> revoke-version <package>@<version> --dsh-version <ex
238
240
 
239
241
  ```json
240
242
  {
241
- "dsh-scout@0.9.3": ["0.2.0-rc.2"]
243
+ "dsh-scout@0.9.4": ["0.2.1-rc.5"]
242
244
  }
243
245
  ```
244
246
 
@@ -246,20 +248,22 @@ dsh plugin --profile <name> revoke-version <package>@<version> --dsh-version <ex
246
248
 
247
249
  #### 已实测版本矩阵
248
250
 
249
- **`dsh-scout@0.9.3` 候选 tarball 已在四个精确 DSH 版本上实测通过**(2026-10-13 发布前,隔离 profile,四个 binary 均从 npm 真实取用、非本机 DSH):覆盖安装、冷启动、工具挂载、**六步真实宿主门禁**(`scout_start` → 导出 → 冷重启 → 惰性回填 → 跨语言导入 → 卸载,外加「标记缺失 / `complete:false`」两个负向对照)和卸载。完整门禁由 `npm run check:release` 执行,实测输出:
251
+ **`dsh-scout@0.9.4` 已在四个精确 DSH 版本上实测通过**(2026-11-07 发布前,隔离 profile,四个 binary 均从 npm 真实取用、非本机 DSH):覆盖安装、冷启动、工具挂载、**六步真实宿主门禁**(`scout_start` → 导出 → 冷重启 → 惰性回填 → 跨语言导入 → 卸载,外加「标记缺失 / `complete:false`」两个负向对照)和卸载。完整门禁由 `npm run check:release` 执行,实测输出:
250
252
 
251
253
  ```text
252
254
  dsh-scout release gate: PASS (4 DSH versions, >=0.1.0-rc.6 <0.3.0-0)
253
255
  ```
254
256
 
255
- | DSH 版本 | npm 渠道(2026-10-12 核对) | 0.9.3(候选 tarball)结果 |
257
+ | DSH 版本 | npm 渠道(2026-10-12 核对) | 0.9.4(候选 tarball)结果 |
256
258
  | --- | --- | --- |
257
259
  | `0.1.0-rc.6` | 兼容范围下界 | 通过 |
258
260
  | `0.1.2-rc.1` | 旧版回归 | 通过 |
259
261
  | `0.2.0-rc.2` | `latest` / `next` | 通过 |
260
262
  | `0.2.1-alpha.2` | `alpha` | 通过 |
261
263
 
262
- 本表此前记录过 **0.9.0** 与 **0.9.1** 候选 tarball 的结果;0.9.3 沿用同一 `peerDependencies` 与 `engines.dsh` 范围(**没有变化**):本版改的是安装文档与诊断面——README 安装章节补上桌面 App 主路径、README 版本引用守卫、`/scout status` 输出带插件版本——依赖与运行时契约未动,并用同一道门禁在同样四个精确版本上复跑通过(4/4),故更新为本版本。npm 渠道那一列仍是 2026-10-12 的核对结果,本次复跑未重新核对。上一版 **0.9.2 已发布到 npm**(`dist-tags.latest` = `0.9.2`):发布 workflow(run `38406696598`)在 `pnpm pack` 之前跑了同一道四版本门禁,所以当时这张表记录的 0.9.2 四版本通过,就是最终发布的那份。0.9.1 新增的 `/scout` 命令与 Skill 走可选绑定,宿主没有对应服务时静默跳过,不影响加载。
264
+ 本表此前记录过 **0.9.0**、**0.9.1** 与 **0.9.3** 的候选/已发布结果;0.9.4 沿用同一 `peerDependencies` 与 `engines.dsh` 范围(**没有变化**):本版改的是运行时 fs 沙箱接缝、阶段式报告与证据分档,并用同一道门禁在同样四个精确版本上复跑通过(4/4),故更新为本版本。上一版 **0.9.3 已发布到 npm**(`dist-tags.latest` = `0.9.3`):发布 workflow(run `38428072425`)在 `pnpm pack` 之前跑了同一道四版本门禁,所以当时这张表记录的 0.9.3 四版本通过,就是最终发布的那份。**0.9.2 已发布到 npm**(`dist-tags.latest` = `0.9.2`):发布 workflow(run `38406696598`)在 `pnpm pack` 之前跑了同一道四版本门禁,所以更早一次记录同样对应最终发布的产物。npm 渠道那一列仍是 2026-10-12 的核对结果,本次复跑未重新核对。0.9.1 新增的 `/scout` 命令与 Skill 走可选绑定,宿主没有对应服务时静默跳过,不影响加载。
265
+
266
+ 2026-10-29 验证脚本修复:夜间检查改用 Node 24,以满足 DSH `0.2.2-alpha.2` 的 Node ≥24.9 要求;验证器通过公开的 `setExecutor` 能力区分单次与批量执行接口,并校验结果数量及调用 ID。失败不重试。该修复尚未发布到 npm,验证结果与边界见 [本次记录](docs/verification-dsh-2026-10-29.md)。
263
267
 
264
268
  未来的 `0.2.x` 版本虽落在声明范围内,仍需实际验证。[夜间兼容检查](https://github.com/MaxHou-infinity/dsh-scout/actions/workflows/compatibility-nightly.yml)每天解析 npm 的 `latest`、`next`、`alpha` 到精确版本,再运行测试和隔离 profile 检查。徽章显示该工作流最近一次运行结果;以上表格记录已完成的精确版本验证。
265
269
 
package/dist/i18n.d.ts CHANGED
@@ -5,7 +5,7 @@
5
5
  * pre-0.9.1 output; `en` is additive. This module only imports types so that
6
6
  * `model.ts` can import it at runtime without creating an import cycle.
7
7
  */
8
- import type { ClaimDimension, ClaimImpact, ClaimStatus, Decision, EvidenceLevel } from './model.js';
8
+ import type { ClaimDimension, ClaimImpact, ClaimStatus, Decision, EvidenceLevel, IdentityField, SourceType } from './model.js';
9
9
  export declare const SCOUT_LANGUAGES: readonly ["zh-CN", "en"];
10
10
  export type ScoutLanguage = typeof SCOUT_LANGUAGES[number];
11
11
  export declare function isScoutLanguage(value: unknown): value is ScoutLanguage;
@@ -31,8 +31,153 @@ export interface ScoutStrings {
31
31
  claimLedger: string;
32
32
  sources: string;
33
33
  coverage: string;
34
+ identity: string;
34
35
  interviewQuestions: string;
35
36
  };
37
+ /** Verified-subject block (legal entity, registration number, tier, provenance). */
38
+ identity: {
39
+ legalEntity: string;
40
+ registrationNumber: string;
41
+ region: string;
42
+ representative: string;
43
+ brandRelationship: string;
44
+ tier: string;
45
+ tiers: Record<'verified' | 'corroborated' | 'needs_verification', string>;
46
+ fieldLabels: Record<IdentityField, string>;
47
+ evidence: string;
48
+ fieldEvidence: string;
49
+ unknown: string;
50
+ };
51
+ /**
52
+ * Stage-based report (0.9.4 readability rework). The report body speaks the
53
+ * reader's language: no E-codes, no source ids, no internal status enums.
54
+ */
55
+ report: {
56
+ meta: {
57
+ role: string;
58
+ location: string;
59
+ evidenceAsOf: string;
60
+ decision: string;
61
+ objective: string;
62
+ unknownLocation: string;
63
+ };
64
+ readingGuide: string;
65
+ confidenceLegend: string;
66
+ quick: {
67
+ heading: string;
68
+ entity: string;
69
+ entityUnverified: string;
70
+ business: string;
71
+ businessUnknown: string;
72
+ capital: string;
73
+ capitalSuffix: string;
74
+ capitalUnknown: string;
75
+ confirmHeading: string;
76
+ confirmIdentity: string;
77
+ confirmRole: string;
78
+ confirmRisk: string;
79
+ };
80
+ sections: {
81
+ identity: string;
82
+ confirmed: string;
83
+ open: string;
84
+ risk: string;
85
+ interview: string;
86
+ gap: string;
87
+ appendixSources: string;
88
+ appendixLedger: string;
89
+ appendixCoverage: string;
90
+ appendixGlossary: string;
91
+ };
92
+ themes: {
93
+ business: string;
94
+ capital: string;
95
+ organization: string;
96
+ };
97
+ openSubheads: {
98
+ interview: string;
99
+ external: string;
100
+ conflict: string;
101
+ };
102
+ labels: {
103
+ ask: string;
104
+ nextStep: string;
105
+ advice: string;
106
+ tier: string;
107
+ means: string;
108
+ identityEvidence: string;
109
+ };
110
+ tier: {
111
+ verified: string;
112
+ corroborated: string;
113
+ unverified: string;
114
+ meansVerified: string;
115
+ meansOther: string;
116
+ };
117
+ confirmedItem: string;
118
+ captured: string;
119
+ openInterviewLine: string;
120
+ openExternalLine: string;
121
+ riskLine: string;
122
+ gapLine: {
123
+ why: string;
124
+ toProceed: string;
125
+ minActions: string;
126
+ identityItem: string;
127
+ };
128
+ decisionSentences: {
129
+ proceed: string;
130
+ identity: string;
131
+ corroborated: string;
132
+ unresolved: string;
133
+ stop: string;
134
+ };
135
+ questionThemes: {
136
+ role: string;
137
+ capital: string;
138
+ product: string;
139
+ process: string;
140
+ general: string;
141
+ };
142
+ questionKeywords: {
143
+ role: string[];
144
+ capital: string[];
145
+ product: string[];
146
+ process: string[];
147
+ };
148
+ tableHeaders: {
149
+ item: string;
150
+ value: string;
151
+ id: string;
152
+ source: string;
153
+ type: string;
154
+ level: string;
155
+ capturedAt: string;
156
+ summary: string;
157
+ stage: string;
158
+ impact: string;
159
+ next: string;
160
+ code: string;
161
+ label: string;
162
+ meaning: string;
163
+ };
164
+ coverage: {
165
+ untouched: string;
166
+ openOnly: string;
167
+ verified: string;
168
+ withOpen: string;
169
+ };
170
+ sourceTypes: Record<SourceType, string>;
171
+ levelLabels: Record<EvidenceLevel, string>;
172
+ levelMeanings: Record<EvidenceLevel, string>;
173
+ statusMeanings: Partial<Record<ClaimStatus, string>>;
174
+ empty: {
175
+ noVerified: string;
176
+ noOpen: string;
177
+ noRisks: string;
178
+ noQuestions: string;
179
+ };
180
+ };
36
181
  /** Claim rendering templates. */
37
182
  claim: {
38
183
  line: string;
@@ -52,6 +197,7 @@ export interface ScoutStrings {
52
197
  /** Investigation coverage block. */
53
198
  coverage: {
54
199
  entry: string;
200
+ identityEntry: string;
55
201
  untouchedLine: string;
56
202
  yes: string;
57
203
  no: string;
@@ -63,6 +209,8 @@ export interface ScoutStrings {
63
209
  /** One line per decision reason code; the missing-dimension one is a template. */
64
210
  decisionReasons: {
65
211
  identity: string;
212
+ identityCorroborated: string;
213
+ identityCorroboratedClear: string;
66
214
  unresolved: string;
67
215
  missingDimension: string;
68
216
  proceed: string;
@@ -86,12 +234,20 @@ export interface ScoutStrings {
86
234
  autoConfidenceNote: string;
87
235
  autoNextAction: string;
88
236
  };
237
+ /** Fallback next actions for a case that has no open claim yet. */
238
+ nextActions: {
239
+ verifyIdentity: string;
240
+ collectSources: string;
241
+ missingDimension: string;
242
+ conclude: string;
243
+ };
89
244
  comparison: {
90
245
  title: string;
91
246
  overviewHeading: string;
92
247
  summary: string;
93
248
  countsSuffix: string;
94
249
  identityVerified: string;
250
+ identityCorroborated: string;
95
251
  identityUnverified: string;
96
252
  decisionTableHeading: string;
97
253
  tableHeader: string;