关于 witness
witness 是用于签署已记录修复清单并跟踪其版本历史的工具包,帮助项目维护者验证修复,并定位回归问题出现的提交。
主要功能
- 01签署已记录修复的清单
- 02验证签名和修复标记
- 03跟踪跨版本的修复历史
- 04定位引入回归的相关提交
- 05在其他项目中初始化工具包
适用场景
- 01以已记录修复的验证作为发布门槛
- 02检查修复标记是否消失
- 03通过历史记录追踪新出现的回归
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ ruvnet/ ruflo --skill witness安装后在 Claude Code 中输入/witness确认已加载。
详细介绍
Witness — 加密修复回归跟踪
Witness 工具包让你在每次发布时都附带一份已签名清单,其中列出代码库中所有有文档记录的修复,以及对应的 sha256 + 标记子串。任何拥有相同 git 提交的人都可以重新推导出公钥,并在不提交私钥的情况下验证签名。
时间历史记录(JSONL)会跟踪各个版本中修复项的变化情况,因此出现回归时,你可以精确定位引入回归的提交,而不只是知道“现在出问题了”。
此工具有两种用法:
- 在 ruflo 内部 — 由 ruflo 自己的 CI 用于把关发布(参见
.github/workflows/v3-ci.yml中的witness-verify作业)。 - 在你自己的项目中 — 将
plugins/ruflo-core/scripts/witness/复制到你的仓库中,运行init.mjs,在witness-fixes.json中登记修复,然后在发布流水线中调用regen.mjs。
快速开始(适用于任何项目)
# One-time bootstrap — creates verification.md.json,
# verification-history.jsonl, and witness-fixes.json template
node plugins/ruflo-core/scripts/witness/init.mjs --root .
# Edit witness-fixes.json: add { id, desc, file, marker } per fix.
# A "marker" is a distinctive substring that MUST appear in `file`
# while the fix is present. If someone reverts the fix, the marker
# disappears and `verify` reports it as `regressed`.
# Regenerate the manifest (signing requires @noble/ed25519)
npm i @noble/ed25519
node plugins/ruflo-core/scripts/witness/regen.mjs \
--manifest verification.md.json \
--history verification-history.jsonl \
--fixes witness-fixes.json
# Verify markers are present in the live tree
node plugins/ruflo-core/scripts/witness/verify.mjs \
--manifest verification.md.json
# Or authenticate the manifest and check source markers in a clean clone.
# Generated dist/ entries are explicitly reported as skipped.
node plugins/ruflo-core/scripts/witness/verify.mjs \
--manifest verification.md.json --source-only
# For a CI hash tripwire, also fail when a file changes but its marker remains.
node plugins/ruflo-core/scripts/witness/verify.mjs \
--manifest verification.md.json --source-only --strict
不使用 --strict 时,保留标记但 SHA 发生变化的情况会被报告,但退出码为 0。
--strict 会使此类变化以退出码 1 结束,同时不会改变签名或缺失文件检查的行为。
时间查询(ADR-103)
# Latest snapshot vs. previous
node plugins/ruflo-core/scripts/witness/history.mjs \
--history verification-history.jsonl summary
# For each currently-regressed fix, find the commit that introduced it
node plugins/ruflo-core/scripts/witness/history.mjs \
--history verification-history.jsonl regressions
# Status timeline for a specific fix
node plugins/ruflo-core/scripts/witness/history.mjs \
--history verification-history.jsonl timeline --id F1
# Machine-readable for CI
node plugins/ruflo-core/scripts/witness/history.mjs \
--history verification-history.jsonl summary --json
如果自上次快照以来有任何修复新出现回归,summary 会以非零退出码结束 — 可将它加入 CI,作为软性合并前检查。
反模式
- 手动编辑
verification.md.json— 始终通过regen.mjs重新生成,否则签名会失效。 - 标记过于通用(
'function'、'import')— 选择足够独特的内容,避免grep与无关代码误匹配。 - 跳过历史记录追加 — 不使用
--history,就无法二分查找回归是何时引入的。 - 只提交其中一个文件 —
verification.md.json和verification-history.jsonl必须在同一个提交中;JSONL 能让未来的你验证已签名清单是否为该历史记录中的最新版本。
文件
scripts/witness/lib.mjs— 共享的重新生成 / 历史记录逻辑。scripts/witness/regen.mjs— CLI:签名并追加历史记录。scripts/witness/history.mjs— CLI:查询时间日志。scripts/witness/init.mjs— CLI:在全新项目中初始化。scripts/witness/verify.mjs— CLI:验证签名和标记。
在 ruflo 的 CI 中
v3-ci.yml 中的 witness-verify 作业会在行为冒烟测试之后、publish 之前运行。失败情形:
| 失败 | 原因 |
|---|---|
signatureValid: no | 清单被手动编辑;重新运行 regen |
regressed: > 0 | 已记录的修复自签发后丢失了标记 |
missing: > 0 | 引用的 dist 文件已不存在;重新构建或移除该条目 |
scope: source-only | 已检查签名和源代码标记;有意跳过生成的条目 |
评论
支持 Markdown