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)で、修正の構成がリリース間でどのように変化したかを追跡できます。そのため、回帰が発生したときに、「今は壊れている」というだけでなく、回帰を引き起こしたコミットを特定できます。
このスキルは、次の 2 通りで使えます。
- 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
最後のスナップショット以降に新たに回帰した修正が 1 件でもあると、summary は 0 以外の終了コードを返します。ソフトなマージ前ゲートとして 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 対応