DeepSeek Harness Hub
← 返回列表

文件变更回执jwilson411/dsh-mutation-receipt

DeepSeek Harnessspec-screened在 GitHub 查看 ↗
未验证

记录文件触碰的路径与哈希,不存内容

尚未跑自动兼容性验证,可查看页面内的依赖与入口分析。 · 最近上游提交 2026/9/1 · 已提供中文文档

DeepSeek Harness 插件:仅追加的 JSONL,记录文件系统触碰(路径、操作、前后 sha256),不包含文件内容

综合分
28.4
GitHub 分
28.4
用户评分
★ Stars
0
周下载量
安装插件(需先安装 dsh CLI 引擎:npm install -g @deepseek-ai/dsh)
dsh plugin --profile web add jwilson411/dsh-mutation-receipt
该插件未发布到 npm,走 GitHub 源安装(pnpm 若拦截 prepare 脚本,按其提示在 pnpm-workspace.yaml 的 allowBuilds 中放行后重跑)
数据截至 2026/9/16(元数据每日更新 · 实装验证按队列轮转,单条结论的验证时间见上方)
依赖的 DSH / Cordis 模块
@deepseek-ai/dsh-tools@deepseek-ai/cordis
用户评分
还没有人投票,来当第一个
订阅周报,不错过优质插件更新
每周一封 · 高评分插件 + 新用户活动

README

dsh-mutation-receipt

一个 DeepSeek Harness 函数插件,将文件系统触碰转化为可引用、仅追加的 JSONL 回执:每个文件一行,记录路径、发生了什么,以及变更前后的 sha256。

它不携带任何文件内容。这就是整个设计约束。招聘经理、审计员或审查者可以询问智能体触碰了什么,并得到一份即使在他们无权阅读所描述文件时仍被允许阅读的回执——而且这份回执对任何窃取它的人都毫无价值。

{"ts":"2026-09-01T05:34:13.000Z","session_id":"sess-1","op":"create","path":"notes/hello.txt","sha256_before":null,"sha256_after":"a948904f2f0f479b8f8197694b30184b0d2ed1c1cd2a1ec0fb85d299a192a447","byte_len_after":12}

它不是什么

在依赖它做任何事之前,请先读这份清单。

- 不是备份。 摘要可以证明一个文件曾经是什么。它无法把文件找回来。没有恢复功能,也永远不会有——回执不包含字节内容。
- 不是 DLP 即服务。 它记录主机报告给它的触碰。它不扫描、不分类、不拦截、不阻止任何东西,也无法告诉你移动的内容是否敏感。
- 不是云上传器。 没有文件内容、没有回执、没有任何路径会离开本机。该库不打开任何套接字,也不进行任何形式的网络调用;回执是你拥有的本地文件,可以删除。
- 它不存储文件内容。 不是片段,不是差异,不是“预览”。如果调用方传入 contents、body、data、text 或 diff 字段,这些键会被丢弃而不是被记录。
- 它不会遍历你的文件系统。 没有爬取,没有监视器,不遍历你的主目录或任何主机挂载点。当主机告诉它某个文件发生了变化时,它写一行;除此之外什么都不做。
- 不是完整记录。 它只知道主机报告的内容。一次从未调用 recordMutation 的写入,就是回执从未听说过的一次写入,回执也不会假装不是这样。

安装

dsh plugin --profile default add github:jwilson411/dsh-mutation-receipt

基于固定在 0.1.1-rc.2 的 harness RC 构建
(@deepseek-ai/dsh-tools@0.1.1-rc.2、@deepseek-ai/cordis@^4.0.1)。Node
=22.14.0。

安装程序从 package.json 读取 dsh.bundle.patch,并将
cordis.patch.yml 组合为配置文件的一层。该文件
插入一行,id: mutation-receipt,带有空的 config。

主机调用 recordMutation(...)

这个 RC 没有可供订阅的文件系统变更事件。
@deepseek-ai/dsh-tools@0.1.1-rc.2 发布两个会话事件——
tool/code-dispatch-start 和 tool/code-dispatch——两者都不是文件
写入。订阅一个虚构的 file/mutation 会产生一个能干净加载却静默地什么都不记录的插件,这比没有回执还糟
全部。因此,宿主是知道文件发生变化的一方,并且由宿主来声明:

import { recordMutation } from 'dsh-mutation-receipt'

// 在写入之前,如果你希望记录一次更新:一旦你覆盖了之前的字节,它们就
// 不复存在了,而这个包不会去猜测它们。
const { sha256: before } = hashFile('notes/hello.txt', workspaceRoot)

writeFileSync(join(workspaceRoot, 'notes/hello.txt'), next)

recordMutation({
workspaceRoot,                      // 必填;每个路径都相对于此
receiptPath,                        // 必填;仅追加的 JSONL
sessionId: 'sess-1',                // 可选,可以为 null
op: 'update',                       // 'create' | 'update' | 'delete'
path: 'notes/hello.txt',            // 相对路径,或根目录下的绝对路径
sha256_before: before,              // update 必填;delete 也必填
})

apply 返回相同的辅助函数,但已绑定此部署的根目录、回执路径和会话 ID,因此拥有插件实例的宿主无需再重复声明它们:

const receipt = plugin.apply(ctx, { workspaceRoot, receiptPath })
receipt.recordMutation({ op: 'create', path: 'notes/hello.txt' })

每个操作需要什么

| op       | sha256_before                        | sha256_after                    | byte_len_after |
| -------- | -------------------------------------- | --------------------------------- | ---------------- |
| create | 始终为 null —— 之前不存在             | 来自磁盘,或由调用方提供            | 来自磁盘,或由调用方提供 |
| update | 必须由调用方提供                    | 来自磁盘,或由调用方提供            | 来自磁盘,或由调用方提供 |
| delete | 必填,除非文件仍可读取              | 始终为 null                     | 始终为 null    |

操作需要但无法推导出的哈希是一个错误(MissingHashError,代码 MUTATION_RECEIPT_HASH),绝不会是一个被悄悄折入该行的 null。三个操作之外的 op 会抛出 InvalidMutationOpError。

其他导出

- hashFile(path, workspaceRoot) → { sha256, byte_len }
- readReceipt(receiptPath) → 按文件顺序返回每一解析行
- summarizeReceipt(lines, { limit }) → { plugin, total, counts, lines }
- relativizePath(workspaceRoot, path) → 存储形式,或抛出错误
- MutationReceiptError、MutationPathError、InvalidMutationOpError、
MissingHashError

路径策略

工作区根目录是回执的作用域,而不是一个提示。

- 存储的路径始终相对于配置的 workspaceRoot,采用 POSIX 风格:/ 分隔符,无前导斜杠,无盘符。
- 根目录下的绝对路径会被相对化,并以该形式存储。
- 根目录之外的绝对路径会被拒绝。任何通过 .. 向上爬出的路径,以及任何其现有路径段通过符号链接解析到外部某处的路径,也会被拒绝。该检查是对最长路径进行真正的 realpath
现有祖先目录,因此符号链接的父目录无法将写入偷运出去。
- 被拒绝的路径会抛出 MutationPathError(代码 MUTATION_RECEIPT_PATH),并且
不会追加任何行。

值得明确说明的后果是:回执从不披露它是在机器上的何处生成的。没有主目录、没有挂载点、没有任何类型的绝对路径会进入该文件。

工具:mutation_receipt

在 apply 内部针对 tools 服务注册。一个工具,仅此而已。

参数 —— 两者均可选:

| 名称         | 类型    | 含义                                                     |
| ------------ | ------- | ----------------------------------------------------------- |
| limit      | integer | 返回多少条末尾行,最旧的在前。默认 20。 |
| session_id | string  | 仅报告在此会话 id 下记录的行。            |

返回:

{
"plugin": "dsh-mutation-receipt",
"total": 3,
"counts": { "create": 1, "update": 1, "delete": 1 },
"lines": [ /* the last N matching lines */ ]
}

counts 和 total 覆盖整个回执(在可选的会话过滤之后)——而不仅仅是返回的窗口。lines 是尾部:最后 N 条匹配行,其中最旧的在前,因此你可以按事情发生的顺序向下阅读。

该工具不返回文件内容,它也不是恢复路径。

CLI:mutation-receipt show

mutation-receipt show [--receipt ] [--root ] [-n ] [--json]

与该工具读取的是同一个文件。

| 选项            | 含义                                                                    |
| ----------------- | -------------------------------------------------------------------------- |
| --receipt  | 回执文件。默认 $DSH_MUTATION_RECEIPT_PATH,否则为 ./mutation-receipt.jsonl。 |
| --root    | 工作区根目录,为提供上下文而报告。                                       |
| -n, --limit  | 要打印的末尾行,最旧的在前。默认 20。                          |
| --json          | 输出摘要对象而不是表格。                               |
| -h, --help      | 用法。                                                                      |

文本模式是一个简短的表格——ts、op、path、sha256_after(删除时为 -)。没有文件内容,因为没有内容可打印。

配置

在后续补丁层中的 mutation-receipt 行上设置。请注意,以 id 为目标的补丁会替换该行的整个 config,而不是合并到其中,因此覆盖必须重新声明它想要保留的每一个键。

| 键             | 默认值              | 含义                                                       |
| --------------- | -------------------- | ------------------------------------------------------------- |
| workspaceRoot | process.cwd()      | 每个存储的路径都相对于此;在此之外会被拒绝。  |
| receiptPath   | mutation-receipt.jsonl | 仅追加的 JSONL。父目录会被创建。     |
| sessionId     | null               | 会标记在此部署所记录的行上。                    |
| limit         | 20                 | mutation_receipt 的默认窗口。                         |

DSH_MUTATION_RECEIPT_ROOT、DSH_MUTATION_RECEIPT_PATH 和
DSH_MUTATION_RECEIPT_SESSION_ID 仅在配置未指定时适用——
该补丁是部署所声明的意图,因此其优先级高于环境变量。

许可证

MIT。版权所有 (c) 2026 jwilson411。

上游仓库有新提交时邮件通知你(每天最多一封,无更新不打扰),随时一键退订。

💬 加入 DPharness 群聊

插件用法、部署报错、新插件第一时间同步——群里问,比一个人翻文档快。

点击加入 QQ 群
DPharness 群聊二维码,手机 QQ 扫码进群
扫码进群