dsh-scout 0.8.1 → 0.9.2
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 +91 -0
- package/README.en.md +249 -38
- package/README.md +145 -25
- package/assets/icon.svg +7 -0
- package/dist/i18n.d.ts +115 -0
- package/dist/i18n.js +299 -0
- package/dist/index.d.ts +14 -9
- package/dist/index.js +682 -206
- package/dist/model.d.ts +58 -8
- package/dist/model.js +260 -107
- package/docs/dsh-scout-product-contract.md +51 -5
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +25 -15
- package/scripts/check-release.mjs +238 -0
- package/scripts/profile-smoke.mjs +1120 -47
- package/tests/acceptance.test.mjs +1684 -0
- package/tests/model.test.mjs +496 -778
- package/tests/package.test.mjs +246 -0
- package/tests/tools.test.mjs +974 -0
package/README.md
CHANGED
|
@@ -3,14 +3,19 @@
|
|
|
3
3
|
[](https://github.com/MaxHou-infinity/dsh-scout/actions/workflows/ci.yml)
|
|
4
4
|
[](LICENSE)
|
|
5
5
|
[](package.json)
|
|
6
|
-
[](https://github.com/MaxHou-infinity/dsh-scout/actions/workflows/compatibility-nightly.yml)
|
|
7
|
+
[](tests/model.test.mjs)
|
|
8
8
|
[](README.en.md)
|
|
9
9
|
|
|
10
10
|
**司察(Scout)** —— 面向 [DeepSeek Harness](https://github.com/deepseek-ai/DeepSeek-Harness) 的**证据驱动型公司与岗位尽调 / 背调插件**。
|
|
11
11
|
|
|
12
12
|
一句话说清楚:**它让 AI 帮你回答——"这家公司和这个岗位,值得进入下一轮吗?面试中还有哪些事项必须核验?"** 并且,每一个结论都挂靠真实的来源,绝不把"公司自述"或"融资新闻"当成已经核实的事实。
|
|
13
13
|
|
|
14
|
+
## 命名
|
|
15
|
+
|
|
16
|
+
- **Scout**:侦察兵先于你抵达目标——背调、尽调、取证、面试准备。包名与仓库名保持 `dsh-scout`,让安装引用稳定。
|
|
17
|
+
- **司察**(sī-chá):"司"呼应 scout,"察"意为考察、明察,概括了这款插件"用证据调查一家公司与一个岗位"的核心动作。
|
|
18
|
+
|
|
14
19
|
---
|
|
15
20
|
|
|
16
21
|
## 为什么需要它?(它解决什么痛点)
|
|
@@ -68,9 +73,11 @@ scout_report / scout_questions 生成报告 / 派生面试问题
|
|
|
68
73
|
│
|
|
69
74
|
scout_compare 多个案例并排对比(决策/主体/风险/问题)
|
|
70
75
|
│
|
|
71
|
-
scout_export / scout_import
|
|
76
|
+
scout_export / scout_import 落盘持久化(五文件 + 完成标记),换会话可恢复
|
|
72
77
|
```
|
|
73
78
|
|
|
79
|
+
也可以用显式入口驱动:`/scout status|questions|report|export`(见下文「命令与 Skill」)。
|
|
80
|
+
|
|
74
81
|
## 快速上手(一段完整示例)
|
|
75
82
|
|
|
76
83
|
以"判断某公司 HR 岗位是否值得推进"为例,Agent 会这样工作:
|
|
@@ -91,11 +98,12 @@ scout_export / scout_import 落盘持久化(五文件),换会话可恢复
|
|
|
91
98
|
- **Key supporting evidence**:最有力的已核验结论
|
|
92
99
|
- **Blocking or unresolved risks**:阻断推进的风险与未知项
|
|
93
100
|
- **Verification checklist**:所有待核验的阻断/重要事项 + 各自的下一步动作(直接当面试行动清单用)
|
|
101
|
+
- **Coverage(0.9.1 新增)**:11 个调查维度各自的「已核验 / 待核验 / 未调查」计数,并单列**未调查维度**——报告因此不只是证据清单,也是尽调进度
|
|
94
102
|
- **Claim ledger**:全部结论台账(状态/证据等级/影响/来源/置信说明)
|
|
95
103
|
- **Sources**:带 URL 的来源清单(可点击回溯)
|
|
96
|
-
- **Interview questions
|
|
104
|
+
- **Interview questions**:建议的面试反问(未调查维度的问题优先)
|
|
97
105
|
|
|
98
|
-
##
|
|
106
|
+
## 工具清单(12 个)
|
|
99
107
|
|
|
100
108
|
| 工具 | 作用 |
|
|
101
109
|
|---|---|
|
|
@@ -107,19 +115,110 @@ scout_export / scout_import 落盘持久化(五文件),换会话可恢复
|
|
|
107
115
|
| `scout_verify_identity` | 用 E3 官方源核验法定主体 |
|
|
108
116
|
| `scout_verify_claim` | 用更强证据提升主张为 verified |
|
|
109
117
|
| `scout_report` | 渲染当前 Markdown 报告 |
|
|
110
|
-
| `scout_questions` | 从案例派生去重、按优先级排序的面试问题清单(上限 12
|
|
118
|
+
| `scout_questions` | 从案例派生去重、按优先级排序的面试问题清单(上限 12 条;案例自带的精选问题保留名额) |
|
|
111
119
|
| `scout_compare` | 2–5 个案例的并排对比报告(决策/主体/关键结论/风险/面试问题) |
|
|
112
|
-
| `scout_export` | 持久化五文件导出(case/sources/claims/events/report
|
|
113
|
-
| `scout_import` |
|
|
120
|
+
| `scout_export` | 持久化五文件导出(case/sources/claims/events/report)+ 完成标记 |
|
|
121
|
+
| `scout_import` | 从导出目录恢复案例并重算决策(容忍旧导出,报 `complete`) |
|
|
122
|
+
|
|
123
|
+
### 输出契约(0.9.1 起)
|
|
124
|
+
|
|
125
|
+
变更类工具(`scout_start` / `scout_add_source` / `scout_ingest` / `scout_search` / `scout_add_claim` / `scout_verify_identity` / `scout_verify_claim` / `scout_import`,共 8 个)**不再把整份 case JSON 回吐给模型**:
|
|
126
|
+
|
|
127
|
+
- `value` 是**结构化对象**:`{ ok, caseId, decision, identity, counts: { sources, claims, verified, open }, changed: { kind, ids }, nextActions, persist? }`;
|
|
128
|
+
- `render` 是**整串不超过 1 KB 的紧凑摘要**:决策 + 本次增量 + 未核验阻断项 + 下一步。上限就是渲染预算本身(`MAX_RENDER_BYTES = 1024` B):省略号自身的 UTF-8 长度先从预算里扣掉、再按码元裁切,因此**含省略号的整串也不会超过 1024 B**;
|
|
129
|
+
- `persist: { persisted, targetDir, error? }` **只出现在变更类工具的 `autoPersist` 路径**(未尝试落盘时该键省略)。**落盘失败不再静默**:`persist.persisted === false` + `persist.error`,且不会产生 `case_exported` 事件。`scout_export` **不带 `persist` 键**,它用**顶层** `persisted` / `complete` / `error` 表达同一件事;
|
|
130
|
+
- **全量数据仍由 `scout_report`(Markdown 报告)与 `scout_export`(文件)提供**——模型看到的是摘要,不是台账全文。
|
|
131
|
+
|
|
132
|
+
读类工具各有自己的形状:`scout_report` → `{ caseId, decision, report, coverage }`;`scout_questions` → `{ caseId, questions }`;`scout_compare` → `{ caseIds, report }`;`scout_export` → `{ caseId, targetDir, files, persisted, complete, error? }`,其中 `targetDir` 是**解析后的绝对路径**。`scout_import` 复用变更类信封,并额外带 `sourceDir`(恢复来源目录)与 `complete`(导出是否完整)。
|
|
133
|
+
|
|
134
|
+
### 命令与 Skill(0.9.1 新增)
|
|
135
|
+
|
|
136
|
+
| 入口 | 作用 |
|
|
137
|
+
|---|---|
|
|
138
|
+
| `/scout` 命令 | `status` / `questions` / `report` / `export` 四个子动作(复用工具逻辑)。宿主会在处理前后自动落 `command/run` + `command/done` 事件——两者都在宿主已知事件词表内,所以会话日志天然可重建 |
|
|
139
|
+
| `scout` Skill | 插件直接注册的尽调工作流(`ctx.skills.register`,不需要落文件、不需要 client bundle):start → search/ingest → claim → verify_identity → report → questions + 四条证据纪律;卸载即消失 |
|
|
140
|
+
|
|
141
|
+
命令用法(与实现一致):
|
|
142
|
+
|
|
143
|
+
```text
|
|
144
|
+
/scout status <caseId> | /scout questions <caseId> | /scout report <caseId> | /scout export <caseId> [targetDir]
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
两者都是**可选绑定**:宿主没有 `commands` / `skills` 服务时静默跳过,不影响插件加载与工具使用。
|
|
114
148
|
|
|
115
149
|
## 安装到 DSH Profile
|
|
116
150
|
|
|
151
|
+
两条已验证路径,任选其一:
|
|
152
|
+
|
|
117
153
|
```sh
|
|
154
|
+
# 路径 A:Git 安装(抓源码,会执行 prepare)
|
|
118
155
|
dsh plugin --profile scout-demo add github:MaxHou-infinity/dsh-scout#<commit>
|
|
119
|
-
|
|
156
|
+
|
|
157
|
+
# 路径 B:本地 tarball 安装(离线、可复现;门禁里跑的就是这一条)
|
|
158
|
+
pnpm pack # 生成 dsh-scout-0.9.2.tgz
|
|
159
|
+
dsh plugin --profile scout-demo add "file:$PWD/dsh-scout-0.9.2.tgz"
|
|
160
|
+
|
|
161
|
+
# 验证工具挂载
|
|
162
|
+
dsh --profile scout-demo --dump-config
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
要求:Node ≥ 22.19。Git 安装会运行 `prepare`,pnpm 可能需要为 `dsh-scout` 显式添加 `allowBuilds`(只放行你审查过的固定版本)。
|
|
166
|
+
|
|
167
|
+
### DSH 兼容性
|
|
168
|
+
|
|
169
|
+
DSH 对插件的兼容性有**三个层次**,不要混为一谈:
|
|
170
|
+
|
|
171
|
+
| 层次 | 位置 | 谁在执行 | 不匹配会怎样 |
|
|
172
|
+
|---|---|---|---|
|
|
173
|
+
| **声明** | `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"*) | 只表达作者意图,不拦截任何东西 |
|
|
174
|
+
| **生效** | `peerDependencies` 中名字为 `@deepseek-ai/dsh` / `@deepseek-ai/dsh-*` 的范围(本仓库只有 `@deepseek-ai/dsh-tools: ">=0.1.0-rc.6 <0.3.0-0"` 一条) | DSH 安装检查 + profile 启动预检 `evaluatePluginCompatibility()` | 安装阶段拒绝,或启动时禁用该插件行 |
|
|
175
|
+
| **不被校验** | `@deepseek-ai/cordis: ">=4.0.2 <5"`(以及 `@deepseek-ai/schemastery`) | DSH 的 peer 名字过滤只认 `@deepseek-ai/dsh` / `@deepseek-ai/dsh-*` | 由 pnpm 解析,DSH 不做兼容判定 |
|
|
176
|
+
|
|
177
|
+
三个必须知道的细节:
|
|
178
|
+
|
|
179
|
+
1. **预发布版本参与匹配。** 判定用 `semver.satisfies(runtime, range, { includePrerelease: true })`。上界写成 `<0.3.0-0` 正是为了在开启 prerelease 的前提下排除 `0.3.0-alpha` 及以后;反过来说,这条 range 的写法**依赖这个标志位**——去掉它,`0.2.0-rc.2` 会被判成不匹配。**用其它工具核对这条范围时请带上 `includePrerelease`**:按默认 semver 语义(node-semver 的预发布规则——预发布版本只被「同 major.minor.patch 元组且带预发布」的比较器接受),`0.1.2-rc.1` / `0.2.0-rc.2` / `0.2.1-alpha.2` 都会被判为**不满足**(semver 7.8.5 实测:`0.1.0-rc.6` 两种语义均为 true;后三者 plain=false / incl=true;`0.3.0-alpha.1` 两者均为 false)。**以 DSH 的判定为准。**
|
|
180
|
+
2. **失败的形态是「静默不加载」,不是报错。** 安装时能预判的 spec(`add` 一个 registry 包)会在 pnpm 执行前直接拒绝并打印豁免命令;git / tarball spec 在安装后判定,失败会回滚 profile 清单与 lockfile。而**已经在 profile 里、启动时才发现不匹配**的插件行会被置为 disabled,本进程只在 stderr 打一行 `dsh: disabling profile plugin <row>: <reason>`——用户看到的现象是"插件没生效"(工具不在、`/scout` 不在),不是一条显眼的红色报错。
|
|
181
|
+
3. **这一条 `@deepseek-ai/dsh-tools` peer 就是全部门禁。** 改 peer 范围等于改兼容承诺。
|
|
182
|
+
|
|
183
|
+
#### 逃生门:profile 级精确版本豁免
|
|
184
|
+
|
|
185
|
+
如果只是**声明范围过期**(例如 DSH 发了 `0.3.0-alpha.1`,而插件其实还能跑),可以不做新版本、直接在 profile 里豁免:
|
|
186
|
+
|
|
187
|
+
```sh
|
|
188
|
+
dsh plugin --profile <name> version-exemptions # 查看当前豁免与运行时版本
|
|
189
|
+
dsh plugin --profile <name> allow-version <package>@<version> --dsh-version <exact-dsh-version> --accept-risk
|
|
190
|
+
dsh plugin --profile <name> revoke-version <package>@<version> --dsh-version <exact-dsh-version>
|
|
120
191
|
```
|
|
121
192
|
|
|
122
|
-
|
|
193
|
+
豁免记录写在 profile 目录下、与 `package.json` / `cordis.patch.yml` 并列的 `compatibility.json`(精确 `package@version` → 允许的精确 DSH 版本列表)。四条边界:
|
|
194
|
+
|
|
195
|
+
- **只接受精确版本**,不接受 range;
|
|
196
|
+
- 只授权「这一个包版本 + 这一个 DSH 版本」这一对,**不随插件或 DSH 升级继承**;
|
|
197
|
+
- **不授权**依赖的安装脚本;
|
|
198
|
+
- 生效时机是**下一次组合**:live profile 会重新组合并挂载,startup-only profile 需要重启。
|
|
199
|
+
|
|
200
|
+
授予豁免需要显式风险确认(CLI 的 `--accept-risk`,插件管理器里是 `acceptRisk: true`),DSH 会在写入前打印风险警告——不兼容的插件可能崩溃或损坏数据。
|
|
201
|
+
|
|
202
|
+
#### 已实测版本矩阵
|
|
203
|
+
|
|
204
|
+
**0.9.2 候选 tarball 已在四个精确 DSH 版本上实测通过**(2026-10-13,隔离 profile,四个 binary 均从 npm 真实取用、非本机 DSH):覆盖安装、冷启动、工具挂载、**扩展后的六步真实宿主门禁**(`scout_start` → 导出 → 冷重启 → 惰性回填 → 跨语言导入 → 卸载,外加「标记缺失 / `complete:false`」两个负向对照)和卸载。完整门禁由 `npm run check:release` 执行,实测输出:
|
|
205
|
+
|
|
206
|
+
```text
|
|
207
|
+
dsh-scout release gate: PASS (4 DSH versions, >=0.1.0-rc.6 <0.3.0-0)
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
| DSH 版本 | npm 渠道(2026-10-12 核对) | 0.9.2 候选 tarball 结果 |
|
|
211
|
+
| --- | --- | --- |
|
|
212
|
+
| `0.1.0-rc.6` | 兼容范围下界 | 通过 |
|
|
213
|
+
| `0.1.2-rc.1` | 旧版回归 | 通过 |
|
|
214
|
+
| `0.2.0-rc.2` | `latest` / `next` | 通过 |
|
|
215
|
+
| `0.2.1-alpha.2` | `alpha` | 通过 |
|
|
216
|
+
|
|
217
|
+
本表此前记录过 **0.9.0** 与 **0.9.1** 候选 tarball 的结果;0.9.2 沿用同一 `peerDependencies` 与 `engines.dsh` 范围(**没有变化**),只把 `@deepseek-ai/schemastery` 由 `^3.18.2` 对齐到 `~3.18.4`,并用扩展后的门禁在同样四个精确版本上复跑通过(4/4),故更新为本版本。npm 渠道那一列仍是 2026-10-12 的核对结果,本次复跑未重新核对。0.9.1 新增的 `/scout` 命令与 Skill 走可选绑定,宿主没有对应服务时静默跳过,不影响加载。
|
|
218
|
+
|
|
219
|
+
未来的 `0.2.x` 版本虽落在声明范围内,仍需实际验证。[夜间兼容检查](https://github.com/MaxHou-infinity/dsh-scout/actions/workflows/compatibility-nightly.yml)每天解析 npm 的 `latest`、`next`、`alpha` 到精确版本,再运行测试和隔离 profile 检查。徽章显示该工作流最近一次运行结果;以上表格记录已完成的精确版本验证。
|
|
220
|
+
|
|
221
|
+
> **夜间变红不等于插件坏了**:它可能只是声明范围过期(例如 DSH 发布 `0.3.0-alpha.1`)。`check:release` 会把「超出声明范围(预期)」与「范围内但失败(回归)」分开报告——前者应当更新声明范围,或按上面的精确版本豁免处理,而不是当成回归去修。
|
|
123
222
|
|
|
124
223
|
## 配置(可选)
|
|
125
224
|
|
|
@@ -128,33 +227,45 @@ dsh --profile scout-demo --dump-config # 验证工具挂载
|
|
|
128
227
|
```yaml
|
|
129
228
|
- id: dsh-scout
|
|
130
229
|
config:
|
|
131
|
-
scoutDir: /path/to/scout-cases # 默认导出目录;case 落在 <scoutDir>/<caseId
|
|
230
|
+
scoutDir: /path/to/scout-cases # 默认导出目录;case 落在 <scoutDir>/<caseId>/(默认 'dsh-scout')
|
|
132
231
|
autoPersist: true # 每次变更后自动写五文件(默认 false)
|
|
232
|
+
language: en # 'zh-CN'(默认)或 'en'
|
|
233
|
+
authorityHostSuffixes: # E3 权威源主机后缀白名单(默认覆盖政府/公司登记/交易所域名)
|
|
234
|
+
- gov.cn
|
|
133
235
|
```
|
|
134
236
|
|
|
135
|
-
- `scoutDir`
|
|
136
|
-
- `autoPersist: true`
|
|
237
|
+
- 相对 `scoutDir` 以**会话的 cwd** 为基准解析,不再落到 DSH 进程的当前目录;
|
|
238
|
+
- `autoPersist: true` 时,每次变更后自动落盘;**失败可见**:返回值带 `persist.persisted=false` + `persist.error`,且不会写 `case_exported` 事件;
|
|
239
|
+
- `language` 影响报告、面试问题、对比报告,以及 `scout_ingest` 采集草稿自动写入的说明文字(`confidenceNote` / `nextAction`);它还会对齐案例自带、**仍是出厂默认**的文案,判定粒度不同:`decisionObjective` / `role.fitQuestion` 是**逐字段**(该字段仍是出厂默认即对齐);精选面试问题是**按下标逐条**——长度与出厂数组相同时,该下标仍是出厂默认的条目替换为本部署语言的同下标默认值,**用户改过的那条保持原样**;长度与出厂数组不同时,整组视为用户自撰、原样保留。判定依据是「是否等于该下标的出厂默认」,不是编辑历史(把某条改回出厂原文,那条会被对齐)。与案例自带语言相同时是 no-op,默认 `zh-CN` 对既有用户零变化。另外,`case.json` 里的 `language` 是**本部署的渲染语言**,不是文件内容的语言:对齐只按这个标签判定,**不校验标签与内容是否自洽**,所以手工把 `language` 改成与内容不符的值再导入时,插件会按「语言相同」提前返回、不做校正(正常的导出 / 导入 / 升级路径不受影响:0.9.0 旧导出的 `language` 恒为 `zh-CN`,与其内容一致)。
|
|
137
240
|
|
|
138
|
-
##
|
|
241
|
+
## 数据持久化
|
|
139
242
|
|
|
140
|
-
案例默认在内存中、按会话隔离;`scout_export`
|
|
243
|
+
案例默认在内存中、按会话隔离;`scout_export` 把案例写成一个可复制的目录:
|
|
141
244
|
|
|
142
245
|
```
|
|
143
|
-
case.json
|
|
144
|
-
sources.json
|
|
145
|
-
claims.json
|
|
146
|
-
events.jsonl
|
|
147
|
-
|
|
246
|
+
case.json 案例主体(含决策状态)
|
|
247
|
+
sources.json 来源清单
|
|
248
|
+
claims.json 结论台账
|
|
249
|
+
events.jsonl 可回放事件流(case_started / source_added / claim_added /
|
|
250
|
+
identity_verified / claim_verified / case_exported /
|
|
251
|
+
case_imported / case_rehydrated)
|
|
252
|
+
report.md 当前报告快照
|
|
253
|
+
export.complete.json 0.9.1 起:完成标记(先写 complete:false,五文件落盘后改写 complete:true)
|
|
148
254
|
```
|
|
149
255
|
|
|
150
|
-
`
|
|
256
|
+
- 导出顺序是「**先记 `case_exported` 事件、后写文件**」,所以磁盘上的 `events.jsonl` 包含本次导出;「导出 → 导入 → 再导出」的事件序列稳定;
|
|
257
|
+
- 完成标记 `export.complete.json` 的内容形如 `{ schemaVersion, caseId, complete, files, eventCount }`:**写入前先置 `complete: false`**,五个数据文件全部落盘后再改写为 `complete: true`——所以**陈旧标记不会为半份导出宣称完整**(覆盖写场景下,上一次成功导出的标记会在新文件写入前先被降级)。`scout_import` 读的是标记里的 **`complete` 字段**,而不是「标记文件是否存在」;**`eventCount` 只有在 `complete: true` 时才与磁盘上 `events.jsonl` 的行数一致**(导出中断时它记录的是那次失败尝试期望的事件数),读取方请以 `complete` 为准、不要只比较 `eventCount`;标记里的 `files` 与 `scout_export` 返回值里的 `files` **同名不同义**——标记只列**五个数据文件**,`scout_export` 返回的是这次调用写出的**六个名字**(五个数据文件 + 标记自身),两者都正确;
|
|
258
|
+
- `scout_import` 能导入**没有完成标记**的旧导出;标记缺失或 `complete: false` 时,只要**五个数据文件都已落盘**,导入仍会进行,但返回值报 `complete: false`,由调用方决定是否信任这份快照(五个数据文件缺任何一个、例如在写 `claims.json` 时中断的全新导出,仍是硬失败);
|
|
259
|
+
- **会话恢复是否自动回填,取决于导出是否完整**:缓存未命中时,**只有完整导出**(完成标记 `complete: true`)才会被惰性回填,并追加 `case_rehydrated` 事件,让"凭空出现"的 case 状态仍然可审计;**0.9.0 的旧导出没有完成标记,不会被自动回填**,需要用 `scout_import` 显式恢复。对齐本身只在 `decide` 路径生效——重算决策的工具调用(`scout_add_claim` / `scout_ingest` / `scout_search` / `scout_verify_identity` / `scout_verify_claim` / `scout_import`)与缓存未命中时的惰性回填会经过它;回填由**第一个访问该 case 的工具调用**触发(`requireCase`),所以冷启动后即使只调 `scout_report` 也可能带上一次对齐,而只创建案例的 `scout_start` 不经过。对齐结果随第一次 `decide` 落到内存 case 与之后的导出;**直接读磁盘 `case.json`、从不经过插件的第三方工具看不到对齐**。
|
|
151
260
|
|
|
152
261
|
## 何时不要用(设计边界)
|
|
153
262
|
|
|
154
263
|
- 它内置的 `scout_search` 仅做搜索到来源的登记;**不替代**专用浏览器或 MCP Provider 的深度抓取;
|
|
264
|
+
- 它**不会**自动投递简历、发送求职邮件,或把你的身份信息交给第三方;
|
|
155
265
|
- 它**不会**替你把融资信息、公司自述或招聘启事当成已核实的事实;
|
|
156
266
|
- 它**不构成**法律、投资或医疗建议;
|
|
157
|
-
- 主体核验依赖 E3 官方源,若 gsxt 等无法访问,报告会如实标记"待核验"
|
|
267
|
+
- 主体核验依赖 E3 官方源,若 gsxt 等无法访问,报告会如实标记"待核验";
|
|
268
|
+
- **0.9.1 与 0.9.2 明确不做**:client 面板、自造 session event、`ctx.storageDomain` 持久化重写、评分 / 排名。理由与边界见 [CHANGELOG](CHANGELOG.md);其中「自造 session event 会让插件自己写的会话无法重建」是硬约束,见[产品契约 §5.1](docs/dsh-scout-product-contract.md)。
|
|
158
269
|
|
|
159
270
|
完整 MVP 边界与验收标准见[产品契约](docs/dsh-scout-product-contract.md);首个示例案例见 [Snapmaker HR Head](docs/fixtures/dsh-scout/snapmaker-hr-head.json)。
|
|
160
271
|
|
|
@@ -162,10 +273,12 @@ report.md 当前报告快照
|
|
|
162
273
|
|
|
163
274
|
```sh
|
|
164
275
|
pnpm install
|
|
165
|
-
pnpm test
|
|
166
|
-
pnpm run check:release
|
|
276
|
+
pnpm test # 构建 + 单元测试(决策默认值/证据约束/主体核验/会话隔离/报告渲染/导出导入往返/自动持久化/面试问题/采集→主张流转/多语言/分发包契约)
|
|
277
|
+
pnpm run check:release # 四个精确 DSH 版本的 profile 门禁 + 打包内容检查
|
|
167
278
|
```
|
|
168
279
|
|
|
280
|
+
`test:profile` 会在隔离 profile 里跑一条**六步真实宿主场景链**:创建(`scout_start` + `scout_add_source` + `scout_add_claim`)→ 导出(绝对 `targetDir`、6 个文件、完成标记 `complete: true`)→ 冷重启(同一 `DSH_HOME`/profile 的第二个进程)→ 惰性回填(不 `scout_import`,断言决策不变并落 `case_rehydrated`)→ 跨语言导入(`en` profile 导入 zh 导出,报告与 `report.md` 的 CJK = 0)→ 卸载(无 registry 残留),另有三条负向对照:`output.schema` 敏感性、标记缺失、标记 `complete:false`。全量约 16 秒,可用 `DSH_SCOUT_SMOKE_SKIP_CROSS_LANGUAGE` / `DSH_SCOUT_SMOKE_SKIP_REHYDRATION_CONTROL` / `DSH_SCOUT_SMOKE_SKIP_NEGATIVE_CONTROL` 跳过,跳过的项会在 PASS 行如实报为覆盖降级。**仍未覆盖**(脚本注释里逐条写明):真实 LLM / agent loop 与 approval 策略、相对路径(`agent` 未设置时 `cwd` 为 `undefined`,门禁只用绝对路径)、`autoPersist` 自动落盘、真实进程中断(撕裂导出靠改写标记复现)、其余 6 个工具只断言注册。`check:release` 随后用四个精确 DSH 版本复跑同一条门禁(并把「超出声明范围(预期)」与「范围内失败(回归)」分开报),最后检查打包内容。
|
|
281
|
+
|
|
169
282
|
## 路线图
|
|
170
283
|
|
|
171
284
|
- ✅ v0.1:证据纪律、三态决策、结构化报告、会话隔离
|
|
@@ -175,7 +288,14 @@ pnpm run check:release
|
|
|
175
288
|
- ✅ v0.5:公司/岗位对比(`scout_compare`:多案例并排对比报告,合并面试问题)
|
|
176
289
|
- ✅ v0.6:采集→主张流转(`scout_ingest` 支持 claim 草稿:登记来源的同时自动添加主张)
|
|
177
290
|
- ✅ v0.7:Provider 深度集成(`scout_search`:DSH Web Provider 搜索,结果自动登记为来源)
|
|
291
|
+
- ✅ v0.8:首个 npm 发布(0.8.0);0.8.1 声明 Schemastery `Config`、补 `exports` 映射、修可选服务注入;0.8.2 对齐 DSH 0.2 rc 通道
|
|
292
|
+
- ✅ v0.9.0:适配 DSH 0.2 运行时;四个精确版本的兼容矩阵 + 夜间兼容检查 + 兼容 issue 模板
|
|
293
|
+
- ✅ v0.9.1:输出契约(结构化值 + 紧凑摘要)、落盘可信度、服务调用时绑定与惰性回填、`language` 与 `## Coverage`、`/scout` 与 `scout` Skill、分发契约(`engines.dsh` / `manifestVersion` / locale / icon)
|
|
294
|
+
- ✅ v0.9.2:真实宿主端到端门禁(六步场景链 + 完成标记负向对照,关闭 0.9.1 验证报告里的 U11 盲区)、精选面试问题**按下标逐条**对齐(关闭 D10)、render 整串上限加固、`@deepseek-ai/schemastery` 对齐 `~3.18.4`
|
|
295
|
+
- ⏭ v0.10.0(计划):client 面板、`ctx.storageDomain` 持久化重写、`presentationMeta` 载荷、对比矩阵升级与可扩展证据策略(**评分仍不做**)
|
|
178
296
|
|
|
179
297
|
## 社区
|
|
180
298
|
|
|
181
|
-
面向 DeepSeek Harness 的独立社区插件(Topic:`dsh-plugin`、`deepseek-harness`、`due-diligence`、`company-research`、`job-research`、`hr-tech`、`evidence-based
|
|
299
|
+
面向 DeepSeek Harness 的独立社区插件(Topic:`dsh-plugin`、`deepseek-harness`、`due-diligence`、`company-research`、`job-research`、`hr-tech`、`evidence-based`)。安装或启动遇到问题时,请用[兼容性问题模板](https://github.com/MaxHou-infinity/dsh-scout/issues/new?template=compatibility.yml)提供精确版本和脱敏日志;也欢迎其他 Issues / PR。
|
|
300
|
+
|
|
301
|
+
版本变更记录见 [CHANGELOG](CHANGELOG.md)。
|
package/assets/icon.svg
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" width="64" height="64" role="img" aria-labelledby="dsh-scout-icon-title">
|
|
2
|
+
<title id="dsh-scout-icon-title">司察 Scout — evidence-driven due diligence</title>
|
|
3
|
+
<rect x="4" y="4" width="56" height="56" rx="14" fill="#4D6BFE"/>
|
|
4
|
+
<circle cx="26" cy="25.5" r="13" fill="#FFFFFF"/>
|
|
5
|
+
<path d="M34 33.5 L43.5 43" fill="none" stroke="#FFFFFF" stroke-width="6" stroke-linecap="round"/>
|
|
6
|
+
<path d="M19.5 25.5 L24 30 L32.5 20" fill="none" stroke="#4D6BFE" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>
|
|
7
|
+
</svg>
|
package/dist/i18n.d.ts
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Localized strings for every human-facing dsh-scout surface.
|
|
3
|
+
*
|
|
4
|
+
* `zh-CN` is the default language and its strings must stay byte-identical to the
|
|
5
|
+
* pre-0.9.1 output; `en` is additive. This module only imports types so that
|
|
6
|
+
* `model.ts` can import it at runtime without creating an import cycle.
|
|
7
|
+
*/
|
|
8
|
+
import type { ClaimDimension, ClaimImpact, ClaimStatus, Decision, EvidenceLevel } from './model.js';
|
|
9
|
+
export declare const SCOUT_LANGUAGES: readonly ["zh-CN", "en"];
|
|
10
|
+
export type ScoutLanguage = typeof SCOUT_LANGUAGES[number];
|
|
11
|
+
export declare function isScoutLanguage(value: unknown): value is ScoutLanguage;
|
|
12
|
+
/** Resolve any value to a supported language, falling back to the `zh-CN` default. */
|
|
13
|
+
export declare function normalizeScoutLanguage(value: unknown): ScoutLanguage;
|
|
14
|
+
/** Fill `{placeholder}` slots in a localized template; unknown slots stay verbatim. */
|
|
15
|
+
export declare function formatScoutString(template: string, values: Record<string, string | number>): string;
|
|
16
|
+
export interface ScoutStrings {
|
|
17
|
+
language: ScoutLanguage;
|
|
18
|
+
/** Header labels of the evidence report. */
|
|
19
|
+
header: {
|
|
20
|
+
decision: string;
|
|
21
|
+
reason: string;
|
|
22
|
+
objective: string;
|
|
23
|
+
evidenceSummary: string;
|
|
24
|
+
};
|
|
25
|
+
/** Section headings shared by the report. */
|
|
26
|
+
headings: {
|
|
27
|
+
supportingEvidence: string;
|
|
28
|
+
unresolvedRisks: string;
|
|
29
|
+
roleHypotheses: string;
|
|
30
|
+
verificationChecklist: string;
|
|
31
|
+
claimLedger: string;
|
|
32
|
+
sources: string;
|
|
33
|
+
coverage: string;
|
|
34
|
+
interviewQuestions: string;
|
|
35
|
+
};
|
|
36
|
+
/** Claim rendering templates. */
|
|
37
|
+
claim: {
|
|
38
|
+
line: string;
|
|
39
|
+
noSourceIds: string;
|
|
40
|
+
history: string;
|
|
41
|
+
checklistLine: string;
|
|
42
|
+
};
|
|
43
|
+
/** Placeholders for empty sections. */
|
|
44
|
+
empty: {
|
|
45
|
+
noSources: string;
|
|
46
|
+
noClaims: string;
|
|
47
|
+
noSupportingEvidence: string;
|
|
48
|
+
noUnresolvedRisks: string;
|
|
49
|
+
noRoleHypotheses: string;
|
|
50
|
+
noChecklistItems: string;
|
|
51
|
+
};
|
|
52
|
+
/** Investigation coverage block. */
|
|
53
|
+
coverage: {
|
|
54
|
+
entry: string;
|
|
55
|
+
untouchedLine: string;
|
|
56
|
+
yes: string;
|
|
57
|
+
no: string;
|
|
58
|
+
none: string;
|
|
59
|
+
separator: string;
|
|
60
|
+
};
|
|
61
|
+
/** Decision labels for the three decision states. */
|
|
62
|
+
decisions: Record<Decision, string>;
|
|
63
|
+
/** One line per decision reason code; the missing-dimension one is a template. */
|
|
64
|
+
decisionReasons: {
|
|
65
|
+
identity: string;
|
|
66
|
+
unresolved: string;
|
|
67
|
+
missingDimension: string;
|
|
68
|
+
proceed: string;
|
|
69
|
+
blockingContradiction: string;
|
|
70
|
+
};
|
|
71
|
+
statuses: Record<ClaimStatus, string>;
|
|
72
|
+
evidenceLevels: Record<EvidenceLevel, string>;
|
|
73
|
+
impacts: Record<ClaimImpact, string>;
|
|
74
|
+
dimensions: Record<ClaimDimension, string>;
|
|
75
|
+
/** One interview question per dimension when the dimension has no verified evidence. */
|
|
76
|
+
questions: Record<ClaimDimension, string>;
|
|
77
|
+
defaults: {
|
|
78
|
+
decisionObjective: string;
|
|
79
|
+
fitQuestion: string;
|
|
80
|
+
initialDecisionReason: string;
|
|
81
|
+
interviewQuestions: string[];
|
|
82
|
+
};
|
|
83
|
+
/** Defaults for claims drafted by the `scout_ingest` batch path. */
|
|
84
|
+
ingest: {
|
|
85
|
+
/** Template with a `{sourceId}` placeholder. */
|
|
86
|
+
autoConfidenceNote: string;
|
|
87
|
+
autoNextAction: string;
|
|
88
|
+
};
|
|
89
|
+
comparison: {
|
|
90
|
+
title: string;
|
|
91
|
+
overviewHeading: string;
|
|
92
|
+
summary: string;
|
|
93
|
+
countsSuffix: string;
|
|
94
|
+
identityVerified: string;
|
|
95
|
+
identityUnverified: string;
|
|
96
|
+
decisionTableHeading: string;
|
|
97
|
+
tableHeader: string;
|
|
98
|
+
tableSeparator: string;
|
|
99
|
+
tableRow: string;
|
|
100
|
+
verifiedMark: string;
|
|
101
|
+
unverifiedMark: string;
|
|
102
|
+
detailHeading: string;
|
|
103
|
+
detailTitle: string;
|
|
104
|
+
verifiedHeading: string;
|
|
105
|
+
openHeading: string;
|
|
106
|
+
noVerified: string;
|
|
107
|
+
noOpen: string;
|
|
108
|
+
openItem: string;
|
|
109
|
+
questionsHeading: string;
|
|
110
|
+
disclaimer: string;
|
|
111
|
+
};
|
|
112
|
+
reportDisclaimer: string;
|
|
113
|
+
}
|
|
114
|
+
/** Look up the string table for a language; an unknown or missing language falls back to `zh-CN`. */
|
|
115
|
+
export declare function scoutStrings(lang: ScoutLanguage | undefined): ScoutStrings;
|