From d1442848c4f2504ff6e758c826fbe96b48a6359b Mon Sep 17 00:00:00 2001 From: jianf <2198972886@qq.com> Date: Fri, 30 Oct 2026 15:02:38 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20README=20=E8=A1=A5=E5=89=8D=E7=BD=AE?= =?UTF-8?q?=E5=87=86=E5=A4=87=EF=BC=88=E5=B9=B2=E5=87=80=20clone=20?= =?UTF-8?q?=E7=9B=B4=E6=8E=A5=E8=B7=91=20npm=20test=20=E4=BC=9A=E7=BA=A2?= =?UTF-8?q?=204=20=E4=B8=AA=E6=96=87=E4=BB=B6=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 缺口(评审复现,我独立复现确认) git archive HEAD 到空目录、原样 npm test: # tests 34 # pass 30 # fail 4 not ok test/loader.test.js / phase-b-g.test.js / phase-b-h.test.js / plugin.test.js 根因:Cannot find package '@deepseek-ai/cordis'。 而 README 全文对 link-dsh.sh / node_modules / 前置准备零命中 —— 正文只写「npm test 是 how many 的权威」,默认读者已经跑过 link-dsh.sh, 而这个前提谁都没写。 这与本轮刚修的那个缺口同族:判据/文档声称的能力,在没有守卫的地方悄悄不成立。 (刚删掉 README 计数,理由是「没守卫就会漂」;「npm test 是权威」这句话 同样没有守卫 —— 它默认了一个没人写下来的前置。) 修法(按裁定选 ①,不用 pretest 钩子) README §Verify 开头新增「Prerequisite: link the harness packages first」: - 说清本仓零运行时依赖,@deepseek-ai/* 全部是 peer, 必须来自机器上已装的 dsh(vendoring 会与它要运行的 harness 漂开) - 给命令 bash scripts/link-dsh.sh - 明确写出跳过它的症状:四个文件 ERR_MODULE_NOT_FOUND (loader / plugin / guard / http 四套,与实测逐一对齐), 并说明这是缺前置的正常形态,不是树坏了 - 补非默认安装根的可选参数 按裁定的第二条不加判据去测「干净 clone 能跑测试」(成本高于收益),写清楚就够。 顺带一处:README 的计数禁令只匹配数字形态(119 tests / 10 checkpoints / 10/10 passed),新段落用了英文「four files」,不被误报 —— 在守卫里加注释说明这个 scope,以及为什么不去匹配文字形态 (「四个文件报 ERR_MODULE_NOT_FOUND」是合法的散文,再往下写就变成小解析器)。 验证 - 干净 clone 复现:无链接 4 红;bash scripts/link-dsh.sh 之后 120/120、check 10/10 - README 描述的失败文件清单与实测逐一一致 - npm test 连跑 5 次 120/120 - npm run check 3 次,exit=0、10 条全绿 - README 计数禁令仍绿(未误报新段落) - 无 .orig / .rej 残留,未 amend / 未 force push --- README.md | 27 +++++++++++++++++++++++++++ test/phase-b-g-static.test.js | 7 +++++++ 2 files changed, 34 insertions(+) diff --git a/README.md b/README.md index f0984ef..2c05e89 100644 --- a/README.md +++ b/README.md @@ -644,6 +644,33 @@ because they will bite anyone writing a second dsh service plugin. ## Verify +### Prerequisite: link the harness packages first + +This repository has **no runtime dependencies** — `lib/` uses only `node:` +built-ins. Everything it imports from `@deepseek-ai/*` is a **peer** that must +come from the dsh install already on the machine, which is why none of it is +bundled here (vendoring a copy would let it drift from the harness it is supposed +to run inside). + +So a fresh clone needs one setup step before the suite can run: + +```bash +bash scripts/link-dsh.sh # symlinks the installed dsh packages into node_modules +``` + +**If you skip it, `npm test` fails with four files reporting +`ERR_MODULE_NOT_FOUND: Cannot find package '@deepseek-ai/cordis'`** (loader, +plugin, guard and http suites). That is the expected symptom of a missing setup +step, not a broken tree — run the script and it goes green. + +The script takes an optional argument for a non-default install root: + +```bash +bash scripts/link-dsh.sh /path/to/global/node_modules +``` + +### Run + ```bash npm test # the full suite npm run check # human-readable evidence, one line per checkpoint diff --git a/test/phase-b-g-static.test.js b/test/phase-b-g-static.test.js index dfcac56..4a2de6b 100644 --- a/test/phase-b-g-static.test.js +++ b/test/phase-b-g-static.test.js @@ -232,6 +232,13 @@ test('scripts/checkpoints.js registers checkpoints AND refuses to pass with zero // // So the invariant is now the opposite: the README must NOT state a count. If // someone re-adds one, this fails and the reason is right here. +// +// Scope: this matches DIGIT forms ("119 tests", "10 checkpoints", "10/10 …"). +// It does not try to catch a count spelled out in words ("four files"), because +// the README legitimately needs prose like "four files report ERR_MODULE_NOT_FOUND +// — that is the missing-setup symptom" and a prose-matching rule would either +// fire on that or grow into a mini parser. The rule targets the shape a +// maintainer actually writes when pasting a run result, which is digits. test('README states no test or checkpoint counts', () => { const readme = readFileSync(join(new URL('..', import.meta.url).pathname, 'README.md'), 'utf8')