dsh-fixture-bad-plugin(测试夹具,不要当真插件用)
用途:验证 dsh-contract-check 能不能在加载时发现违规的 render 契约。
它故意注册了两个工具:
| 工具 | 行为 | 期望判定 |
|---|---|---|
fixture_bad_render |
render 返回裸字符串(就是当年 dsh-ssh-ops 那个 bug) |
🔴 violation → 角标变黄 |
fixture_unknown_render |
render 委托给辅助函数,静态判不出形态 |
见下(初版预期写错了) |
✅ 实机验证结果(2026-09-20,第一次真正走通黄灯)
颜色: yellow
状态条: 无耗 · 检查 23 个插件 · 违规 2 · 不可判定 1
[violation] fixture_bad_render 返回字符串,违反 render(): ContentBlock[] 契约
[violation] fixture_unknown_render 实测返回对象(不是数组),违反契约(实测)
[unknown] doublecheck_report 静态判不准,实测又抛异常
两点值得记下来:
fixture_unknown_render被判成 violation 而不是 unknown,这是对的。 我原本以为"静态判不准 = unknown",但实测探针把它抓出来了: 它的 render 返回传进去的值,而它声明的输出 schema 是对象 → 真调用时返回的一定不是数组。 这正好说明实测探针的价值:静态看不透的东西,跑一次就清楚了。doublecheck_report仍是 unknown:实测时 render 抛了Cannot read properties of null (reading 'length')—— 假数据不合形状,归 unknown (抛异常绝不判违规,这是零误报原则的一部分)。
⚠️ 先读:这个夹具造成过一次事故(2026-09-19)
症状:把它加进 profile 的 bundles 后,DSH 起不来 —— 整个插件树加载失败。
根因:上一版源码里有 import { defineTool } from "@deepseek-ai/dsh-tools",
而夹具目录没有 node_modules。pnpm 的 link: 让 Node 按真实路径解析 →
找不到包 → ERR_MODULE_NOT_FOUND → 插件树整体失败。
两个教训:
- "扫源码 OK" ≠ "能加载"。离线扫描只看文件存不存在、形态对不对,
完全不涉及模块解析 —— 所以它当时报了
ok,然后 DSH 挂了。 - 把测试夹具装进运行环境的 profile 之前,必须先证明它能被加载。
已修:夹具改成零外部 import(直接用裸定义对象调 ctx.tools.register()),
从根上不可能再因解析失败拖垮启动。
已加闸门:scripts/preflight.mjs —— 装之前必须先跑;它自己也有自测(selftest.mjs)。
⚠️ 第二个坑:pnpm install 不会补建新加的 link: 依赖
2026-09-20 实测:把夹具加进 dependencies(link: 形式)后跑 pnpm install,
它回一句 "Already up to date" 就结束了 —— lockfile 更新了,但 node_modules 里的链接没建。
此时直接重启,DSH 解析不到这个包,又是"整个插件树起不来"(跟上次症状一样,根因不同)。
pnpm install --force 也一样跳过。
判据(装完必查):
Test-Path 'D:\tool\dsh_data\profiles\web\node_modules\dsh-fixture-bad-plugin'
补建(就是 pnpm 给其它 link: 依赖建的那种 Junction):
cd D:\tool\dsh_data\profiles\web
New-Item -ItemType Junction -Path node_modules\dsh-fixture-bad-plugin `
-Target D:\tool\claude_code\dsh-fixture-bad-plugin
使用流程(顺序不能换)
# ① 预检:证明它能被加载(不通过就别装)
node D:\tool\claude_code\dsh-fixture-bad-plugin\scripts\preflight.mjs
# ② 装进 profile(脚本会备份配置、写完校验)
node D:\tool\claude_code\dsh-fixture-bad-plugin\scripts\profile-link.mjs --apply
# ③ 确认 node_modules 里有链接(见上面那个 pnpm 坑;没有就手工建 Junction)
Test-Path D:\tool\dsh_data\profiles\web\node_modules\dsh-fixture-bad-plugin
# ④ 重启 DSH(你重启,不是我)
期望看到
- 会话头部圆点变 🟡 黄
- 悬停状态条出现
违规 2 /contract-check/status的findings里点名fixture_bad_render- 绿灯 → 黄灯的颜色变化就是这条链路走通的证据
⏹ 验证完立刻移除
一键(双击即可,不需要 AI 在场):
D:\tool\claude_code\dsh-fixture-bad-plugin\紧急回滚.bat
或命令行:
node D:\tool\claude_code\dsh-fixture-bad-plugin\scripts\profile-link.mjs --remove
# 然后重启 DSH
卸载脚本删链接时用的是
rmdir而不是递归删除: 在 Junction 上递归删除会跟进目标目录,把夹具源码本身删光。 (2026-09-20 卸完已核对:夹具源文件全部完好。)
上一次就是忘在这一步:夹具留在 profile 里,于是任何原因导致的加载失败 都会先被怀疑到它头上(而且它确实就是凶手)。
No comments yet. Be the first to write one.