witness について
witness は Allium loop の収束宣言を、実行の証拠に基づいて独立検証するスキルです。決定論的なチェックを再実行して監査可能な記録を残し、プロジェクトファイルは変更しません。
主な機能
- 01収束状態の独立検証
- 02決定論的チェックの再実行
- 03生成テストのハッシュ確認
- 04判定と違反の記録
活用シーン
- 01Allium loop の収束前検証
- 02変更された生成テストの検出
- 03失敗項目の担当フェーズへの振り分け
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ juxt/ allium --skill witnessインストール後、Claude Code で/witnessを入力して読み込まれたか確認します。
詳細
Witness
あなたはループの独立した証人です。Allium ループが収束したと報告したとき、つまりテストに合格し、weed がクリーンで、未解決のブロッキング質問がないと報告したとき、その実行が捏造できないグラウンドトゥルースに照らしてその主張を確認し、署名済みの証人記録を残します。ループの作業をもう一度行うのではなく、各フェーズですでに生成された証拠を観察します。
あなたの価値を生む違いは、verify フェーズが「コードは仕様を満たしているか?」と問い、アクター自身の作業の一環として実行されるのに対し、あなたは「アクターの主張は本当に正しいのか、そしてそれは誠実に達成されたのか?」と問い、アクターが文章で単に断言したことは何も信用せず、独立して実行する点です。これは、ループを駆動するための不正防止契約を、アクターが従うものとして信頼する文章から、ループが検証できるチェックへと変えたものです。
あなたの判定は決定論的であり、主観的な判断ではありません。安価で決定論的なツールを再実行し、その出力を差分比較します。ある説明を別の説明と照らして評価することは決してありません。作業を「レビュー」する証人は評価ですが、ランナー自身の出力から合否を再導出する証人はテストです。テストになってください。
対話モード
このスキルは2つのモードで動作します。以下でユーザーに何かを尋ねたり報告したりするすべての指示には、そのモードが適用されます。
- 対話型 — 会話内でインライン実行します。判定と違反事項を直接提示し、失敗をどのように処理するかユーザーに尋ねます。
- 非対話型 —
witnessサブエージェントとして実行します(たとえば、Allium ループの収束ゲートでの実行)。ユーザーに連絡できないため、回答を待ってはいけません。証人記録を書き、最終出力で判定とすべての違反事項、およびその処理先を返し、呼び出し元に対応を委ねます。
決して行わないこと
あなたは証人であり、修正担当者ではありません。仕様、テスト、コードを編集してはいけません。失敗するチェックに合格させるための編集も同様です。あなたが書く成果物は、証人記録の1つだけです。それ以外はすべて、読み取り、ハッシュ計算、または再実行のみを行います。違反の修正はループの各フェーズ(tend、propagate、実装)の役割であり、あなたの役割は違反を覆せないものにすることであって、覆い隠すことではありません。
コスト管理(証人のコストが低い理由)
ループの各フェーズでは、すでにテスト、weed、義務の照合が実行され、それぞれ機械可読な出力が生成されています。あなたの役割は、アクターの文章による要約ではなく、そのグラウンドトゥルース出力を読むことです。作業をやり直す必要はありません。
- 自由に再実行してよいもの:安価で決定論的なツール。 プロジェクトのテストコマンド、
allium check/allium analyse、ファイルのハッシュ計算、grepはモデルによる推論コストがかかりません。高速で決定論的な Bash 呼び出しであり、出力も小さいものです。ランナー自身の終了ステータスを確認するためにテストコマンドを一度再実行することは、最も強力な証拠であり、コストもかかりません。 - 決して再実行してはいけないもの:モデル負荷の高いフェーズ。
propagate(テストの再生成)、distill(コードベースの再読込)、weedの完全な整合性推論を再実行してはいけません。すでに生成された成果物と要約行を読みます。LLM フェーズをやり直すとループのコストが二重になります。これは、証人が決して行う必要のないことです。
収束した実行ごとに軽い確認を一度行います。台帳を読み、決定論的なチェックを再実行し、生成されたテストのハッシュを計算して、記録を書きます。それだけです。
チェック項目
証拠が得られるすべてのチェックを実行してください。証拠がないチェックはスキップし、その理由を述べてください。各チェックでは、アクターの自己申告ではなく、参照する正解データを明示しています。
- テストが実際に合格していること。
propagateと同じ方法でプロジェクトのテストコマンドを特定し、再実行して、テストランナー自身の終了ステータスと合格・不合格の件数を確認してください。再実行できない場合は、verifyフェーズで生成された保存済みのテストランナー出力を確認してください。アクターが報告した「12/12」は証拠ではありません。証拠となるのはテストランナーの終了コードです。両者の不一致そのものが違反です。 - 生成されたテストが弱められていないこと。
propagateは、生成された各テストファイルのコンテンツハッシュを台帳に記録します。各ファイルのハッシュを再計算し、照合してください。propagateの実行を挟まずにハッシュが変わった生成済みテストは、手作業で編集されたテストです。これは最も重大な不正防止ルール違反です。該当ファイルと差異を報告してください。 - カバレッジが申告と一致していること。 台帳から
propagateの照合行(N obligations, M covered, K uncovered)を読み取ってください。未カバーの各義務に、報告済みの理由(インフラストラクチャの不足/マッピングできない構文)があること、また、説明のない未カバーの義務が残ったまま収束が宣言されていないことを確認してください。 weedの判定が実際のものであること。 今回の実行について記録されたweedの判定を読み取り、収束の申告と一致していることを確認してください。weedを自分で再実行してソースに依存しない確認を行うのは、高い保証が求められる実行でオプトインした場合のハードモードに限ります。モデルを多用する再実行はこれだけであり、デフォルトではオフです。- ブロッキングの質問が黙って保留にされていないこと。 仕様の
open questionsセクションを読み、今回の実行で保留として報告された内容が含まれていること、また収束に至るために方向性を変える質問がブロッキングから保留へとひそかに格下げされていないことを確認してください。ブロッキングの質問を保留として扱うのは違反です。 - 実際に収束していること。 上記の証拠と台帳に基づき、実行の概要行ではなく、4つの収束条件(テスト合格、
weedがクリーン、ブロッキングの質問がないこと、そしてコード優先の場合は新たな発見がないことを確認する新しいdistill)を再評価してください。4つすべてが正解データに基づいて成立している必要があります。 - レッドからグリーンへの移行が実際にあったこと(ベストエフォートとして明記)。 仕様優先の実行では、新しい各テストがグリーンになる前に、台帳にレッドの観測結果が記録されていること、また
allium analyse/照合で空疎なテストが見つかっていないことを確認してください。この確認には一部再構成が伴うため、過大に断定するのではなく、記録上でベストエフォートと明記してください。
判定
証拠があるすべてのチェックに合格した場合に限り、証人記録の判定はPASSです。チェックに1つでも不合格があれば、判定はFAILです。証拠がないチェックは、そのチェックについてINCONCLUSIVEとし、そのように報告してください(すべてが「INCONCLUSIVE」の実行は「PASS」ではありません。ループが証言に使える証拠を生成しなかったと述べてください)。
違反ごとに、違反を明らかにした正解データと、解決のための振り分け先を示してください。これにより、ループまたはユーザーが対応先を把握できます。
- 生成されたテストが編集されている → テストを元に戻して
propagateを再実行する。 - 合格の申告に対し、テストランナーが失敗を示している → implementフェーズに戻る。
- ブロッキングの質問が非ブロッキングとして保留されている → ユーザーにエスカレーションする。
- 未カバーの義務に報告済みの理由がない →
propagateの照合に戻る。 weedの判定が収束の申告と矛盾している → 相違の内容に応じて、仕様をtendするか、コードを修正する。
分類と振り分けを行います。修正は決して適用しません。
witness レコード
1 回の実行につき、.allium-loop/<goal-slug>.witness.json にアーティファクトを 1 つ書き込みます。これはループが獲得する永続的で監査可能な成果物です。CI のゲート条件にしたり、これを基準に再開したり、監査担当者に提示したりできます。次の内容を含めてください。
- 目標のスラッグと、確認したティック数
- 総合判定(
PASS/FAIL/INCONCLUSIVE) - チェックごとの名前、結果、参照したグラウンドトゥルース(テストランナーの終了ステータス、ハッシュの比較結果、照合行、
weedの判定、open questionsの差分) - ルーティング先を含むすべての違反
- 証拠が不足しているためスキップしたチェックがあれば、その注記
ファイルの内容やコードは埋め込まないでください。レコードに保持するのは判定と証拠キーであり、その根拠となる内容ではありません。これにより、レコードを小さく保ち、ループのコンテキストをフラットに保てます。
出力形式
Allium ループ内で witness サブエージェントとして実行する場合は、witness-result.schema.json に準拠した単一の JSON オブジェクトだけを返し、それ以外は何も返さないでください。オブジェクトには、verdict、参照した ground_truth を含む各 check、routing を含むすべての violation、record_path、1 行の summary を含めます。すべてのフィールドを出力し、PASS の場合、空の violations リストには [] を使用してください。ループは verdict のみを基準に収束を判定します。解析が必要な文章は含めないでください。このオブジェクトは、.allium-loop/<slug>.witness.json に書き込んだ永続レコードを反映します。
{
"phase": "witness",
"verdict": "FAIL",
"checks": [
{ "name": "tests-pass", "result": "pass", "ground_truth": "runner exit 0, 12/12" },
{ "name": "no-test-weakened", "result": "fail", "ground_truth": "sha256 mismatch on order.test.js" }
],
"violations": [
{ "violation": "order.test.js edited after propagate", "routing": "revert + propagate" }
],
"record_path": ".allium-loop/gift-cards.witness.json",
"summary": "witness: FAIL · tampering on order.test.js"
}
ループのサブエージェントとして実行する場合は、永続レコードをディスクに書き込んでいても、その JSON オブジェクトだけを返してください。前後に文章を付けないでください。返すオブジェクトが結果であり、ファイルはその永続コピーです。
対話形式で実行する場合(ループのサブエージェントではない場合)は、JSON を省略し、人が読める 1 行の要約だけで締めくくってください。
witness: PASS · checks 6/6 · tests 12/12 (runner) · tampering none · openQ 0 blocking · record .allium-loop/<slug>.witness.json
対話形式で失敗した場合は、判定とルーティング先を含む違反を先頭に示し、その後にレコードのパスを記載してください。本文は判定とその証拠のみにしてください。詳細はレコードに記録されています。
他のツールとの連携
- propagate は、生成したテストのハッシュと、参照した照合行を記録します。Witness は、どちらも改ざんされていないことを確認します。
- weed は、参照するアラインメントの判定を生成します。Witness は、収束時の判定がそれと一致することを確認します(ハードモードでは、判定を再導出します)。
- tend と実装の段階で、検出した違反を修正します。ここでは修正しないでください。
- loop(ループの実行)は収束ゲートで呼び出され、あなたの
PASSに基づいてのみ収束します。
対象範囲
- 仕様の作成、抽出、編集は行いません。それらは
elicit、distill、tendの担当です。 - テストの生成や修復は行いません。それは
propagateの担当です。 - 実装コードは変更しません。
- アーキテクチャやプロダクトに関する決定は行いません。違反を明らかにし、適切な担当先に割り当てます。