用会话实际运行记录核对提交信息里的声明,对不上就拦下
30/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/10/21 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
相关生态插件(非 dsh 原生,按其对应运行时安装)
git clone https://github.com/Phocinae/dsh-evidence.git状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:已验证
是什么
生态应用
桌面端 / Web 外壳,不以 dsh plugin add 安装
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 11 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码v2.7.0🟢 扫描:未发现敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描未发现敏感能力:最多只发网络请求、读取自身元数据或只读文件,未发现执行命令、文件写入或敏感信息读取。
扫描于 2026/11/1(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
依赖的 DSH / Cordis 模块
@deepseek-ai/cordis给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
README
由 DeepSeek 最新模型翻译生成dsh-preclaim
仓库名与包名不一致: 仓库叫 dsh-evidence,npm 包叫 dsh-preclaim。两者是同一个插件。
提交信息里写「测试通过」,这只是一句声明。这个插件拿它跟会话实际跑过的命令对账——对不上就拦下提交。
DeepSeek Harness 插件。不用模型,不用服务,不联网,不要 API key。
$ git commit -m "fix: parser handles empty input; tests pass"
dsh-preclaim: this session has recorded no evidence at all, so this gate cannot
tell "it did not happen" from "I did not see it"
— asserted: CLAIM_TEST_PASSED
[review] commit anyway, or run the tests first?
为什么叫 preclaim,不叫 evidence-gate? 因为那些一眼就能想到的名字都被别人占了,其中几个还是问同一个问题的插件:dsh-evidence-gate(lory.top)、dsh-evidence(tudamu)、dsh-claim-gate、dsh-attest。
展开完整文档(README 剩余 1 节)
dsh-preclaim
仓库名与包名不一致: 仓库叫 dsh-evidence,npm 包叫 dsh-preclaim。两者是同一个插件。
提交信息里写「测试通过」,这只是一句声明。这个插件拿它跟会话实际跑过的命令对账——对不上就拦下提交。
DeepSeek Harness 插件。不用模型,不用服务,不联网,不要 API key。
$ git commit -m "fix: parser handles empty input; tests pass"
dsh-preclaim: this session has recorded no evidence at all, so this gate cannot
tell "it did not happen" from "I did not see it"
— asserted: CLAIM_TEST_PASSED
[review] commit anyway, or run the tests first?
为什么叫 preclaim,不叫 evidence-gate? 因为那些一眼就能想到的名字都被别人占了,其中几个还是问同一个问题的插件:dsh-evidence-gate(lory.top)、dsh-evidence(tudamu)、dsh-claim-gate、dsh-attest。项目设计文档查过 registry,挑了这个没人用的名字,它点明了正确的时机:声明写下来之前。 以后如果有人改回别人占用的名字,scripts/verify-artifacts.mjs 会让构建失败。
快速开始
dsh plugin --profile web add dsh-preclaim@0.1.3
装好就能用 evidence_status 和 pre-execute 闸门;闸门把会话里跑过的命令记进账本,在提交、推送、写 README 之前,拿声明跟账本对一遍。
为什么做这个,为什么不用模型
它要防的失败不是判断题。「提交信息声称测试通过」和「本会话没有记录到测试运行」都是事实,两者是否一致可以判定。这里放个模型,等于给一个是非题加上置信区间,而且偶尔会错得没人能复现。
所以整个插件是确定性的:
* tools/post-execute 记录跑过什么,写进会话的内存账本。
* tools/pre-execute 在受控动作执行前读账本。
这个分工带来三个结果,它们是设计本身,不是实现细节:
1. 声明不能自己给自己作证。 受审的动作永远不作为证据来源。提交信息写「跑了 pytest,全部通过」,对自己的检查毫无贡献。
2. 测试跑失败,不算「测试通过」的证据。 test-run 和 build-run 要求成功。ci-check 和 file-read 不要求:看到流水线是红的,也是看到了流水线;读文件就是读文件的证据,退出码是什么都一样。
3. 不从文字里推断任何东西。 账本只存宿主报告的内容,别的都不存。不读对话记录,不做启发式扫描。
安装
dsh plugin --profile <name> add dsh-preclaim@0.1.3
自带的补丁在激活时挂上闸门。每个配置项都有默认值,完全不用配置也能跑。
受控范围
Shell 调用:运行带断言性质的 git 动词 —— commit、push、tag。commit 把提交信息带在命令里;push 通过它携带的提交来断言,所以只检查命令文本,提交范围留给人工判断。
只读动词(status、log、diff、show、branch、rev-parse 等)一律不拦截,--dry-run、--help、-h、--version 也不拦截:这些都不会做出持久性声明。git fetch && git commit -m x 只拦截 commit,不拦截 fetch。
README 类写入 —— README、CHANGELOG、docs//.md、/README.md。README 是项目声明自己做什么、能不能跑通的地方。普通源码写入不管;管的话等于给每次编辑都加一道闸。工作目录之外的写入完全不判断。
什么算一条声明
| 模式 | 它注意到什么 | 由什么来应答 |
| CLAIM_TEST_PASSED | 声称测试通过 | 一次记录在案的测试运行 |
| CLAIM_VERIFIED | 声称某事已验证 | 无可观测证据 → tool_unverified |
| CLAIM_RAN_CHECK | 声称跑过检查 | 一次记录在案的测试运行 |
| CLAIM_BUILD_OK | 声称构建成功 | 一次记录在案的构建 |
| CLAIM_CLI_ASSERTION | 提到某次命令行调用 | 一次 CI 观测 |
| CLAIM_DEPENDENCY | 断言某个平台依赖 | 无可观测证据 → tool_unverified |
| CLAIM_LINE_REF | 引用某一行 | 一次文件读取 |
| CLAIM_COUNT | 引用某个计数 | 无可观测证据 → tool_unverified |
| CLAIM_HASH_REF | 引用某个提交哈希 | 无可观测证据 → tool_unverified |
| CLAIM_FILE_EXISTS | 引用某个文件 | 一次文件读取 |
最后一列背后有一条规则:证据必须和它应答的声明对得上。 file-read 能应答对文件或行的引用,因为读那个文件就是这层关联。它不能应答「已验证」—— 读了某个文件不等于验证了那条声明。早先的版本把它当成能应答,结果只要读过任何东西,git commit -m "verified on Windows" 就能通过。
有四种声明对应不到任何证据,这不是疏漏。它们是这道闸能观测、却无法裁定的声明,所以它如实说明并发出询问(tool_unverified),而不是扣一顶自己撑不住的帽子。
如果没有任何模式匹配,动作以 no-claim-in-action 放行。这些模式刻意做成语法层面的:网撒得越宽,诚实工作被误拦的次数越多,而一道总喊狼来了的闸最终会被关掉 —— 关掉之后就什么都不查了。
未命中时会发生什么
| 情况 | 判定 | 原因 |
| 不是受监视的动作 | allow | 没什么可查 |
| 受监视的动作,但不带声明 | allow | 仍然没什么可查 |
| 每条声明都有记录在案的证据支撑 | allow | 声明与记录一致 |
| 有声明但无证据,台账非空 | review | 声明没有支撑 |
| 台账为空 | review,并说明原因 | 分不清「事情没发生」还是「我没看见」 |
| 一条没有可观察证据能够回答的声明 | review(tool_unverified) | 这是这道关卡的局限,不是指控 |
| 关卡自身抛出异常 | review | 缺陷不能变成静默放行 |
其中有两行值得再读一遍。
空账本出现在插件于会话中途加载,或记录失败的时候。在这种状态下报告「测试没有运行」,会是一个自信的错误答案。关卡改为说出它实际知道的东西——而空账本不可能产出通过,也不可能产出事实性指控。
tool_unverified 是对这条插件永远无法核查的声明给出的诚实答案。一条写着 reverts abc1234 的提交引用了哈希;账本观察到的东西既不能证实也不能推翻它。称其为「无凭据」会是指控,而关卡支撑不起这个指控,所以它如实说明并发出询问。
设置 decision: deny 可以直接拒绝,而不是询问。
配置
- insert:
- id: preclaim
name: dsh-preclaim
config:
triggerTools: [pwsh, bash, write, edit, str_replace_editor]
readmeGlobs: ['README', 'CHANGELOG', 'docs//.md', '/README.md']
decision: review # review | deny
audit: true
ledgerLimit: 500
pushMessageLimit: 20
这里刻意没有任何配置值能让无凭据的声明通过。decision 只在询问与拒绝之间选择,仅此而已——带关闭开关的关卡,就是会被关掉的关卡。resolveConfig 在遇到 decision: allow 时抛出异常。
pushMessageLimit 限制一次推送要核查多少条提交信息,这样开销不会随仓库年龄增长。上限生效时会报告出来,因为静默截断的检查读起来像一次完整检查。
evidence_status 工具
evidence_status({ text: "fix: tests pass" })
报告账本状态、这段文本做出了哪些声明、会话是否掌握证据,以及关卡会如何判定。请在行动之前调用它,这样一次拦截的代价是重写,而不是一个被拒绝的操作。
两个关键的解析细节
先剥离 ANSI 转义,再做其他任何事。 捕获的输出即使经过管道也可能带有转义序列,所以一个标志可能以 \u001b[1;33m--version\u001b[0m 的形式到达。此时所有纯文本模式都匹配不上,关卡会静默地不再识别它本该检查的命令。
按不在引号内的操作符拆分命令。 只按 ; 拆分会把 git commit -m "a; b" 切成两半,剩下的那一半不再像一条提交——于是消息里的声明会被完全漏掉。
这两点都有测试固定。
它不做什么
它不读对话记录,不调用模型,也不判断工作做得好不好。它只检查一件很窄的事:一条声明和会话对自身的记录是否一致。
它也不持久化账本。证据是本次会话的属性,所以从磁盘恢复的账本,会是另一次运行的证据。
这是安全带,不是沙箱。 这里的一切都是对账本做文本匹配。git commit -m "$(cat claim.txt)"、模式识别不出的测试命令,或者干脆不用 git,都能绕开它。它拦的是普通情况——声明写得比实际工作稍微早一点——它挡不住存心欺骗它的会话。别把它说成能挡。
有意尚未构建
项目设计里写明了可选的第二层:确定性层落进灰色地带时,问本地 150M Phocinae 模型一次,服务不可达就按失败处理。这一层不在本次发布里。 结果对象已经带上它将来要填的字段(model_verdict、model_calls),model_calls 报 0,因为它是真实计数器。
之所以先不做,是因为价值要靠测量,而价值在确定性层。加一层模型调用,需要和其他所有东西一样的证据标准——测量,不是假设。把计数器发出去、报 0,比发一层没人测过的更诚实。
环境要求
Node ^22.19.0 || >=24.0.0。无运行时依赖。@deepseek-ai/cordis 是可选 peer。
测试
npm test # 64 tests, no host required
npm run verify:artifacts # what npm publish would actually ship
测试套件覆盖 shell 解析(ANSI、引号、操作符、-C、只读动词、dry-run 抑制)、声明表、账本按类型区分的成功规则、路径规范化后的 glob 匹配、next() 调用纪律,以及「绝不能放行」的路径:未知决策、门内抛异常、没有工具名的载荷。
许可证
Apache-2.0。预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
Phocinae/dsh-evidence
用会话实际运行记录核对提交信息里的声明,对不上就拦下
相关插件 · 开发 / 工程
隐私简历生成器reactive-resume/reactive-resume
Reactive Resume 已迁至 GitHub 上的…
★ 45,125已汉化MCP
71.7
AI 架构文档生成器sopaco/deepwiki-rs
🚀 Litho 已进化为 Terrain —— 给你的 AI 智能体一张会呼吸的代码库地图。
★ 3,157已汉化DSH
70.8
长时任务执行闭环AMAP-ML/LongHorizon-Harness
面向 Computer-Use Agent 的 Loop Engineering
★ 1,764已汉化DSH
70.5
AI 编程纪律方法包GanyuanRan/Aegis
让 AI 编程 agent 变得可信:少返工、更安全、说“完成”前先给证据。
★ 1,384已汉化DSH
69.6
多代理编排运行时Enderfga/claw-orchestrator
面向编程智能体的运行时。把 Claude Code、Codex、Antigravity、Grok…
★ 586已汉化MCP
69.4
记忆进化插件csyangwen/dsh-memory-evolve
dsh-memory-evolve 使用场景指南
★ 461已汉化DSH
67.9