mcpField
H
harness-eval

harness-eval

github.com/tech-leads-clubエージェントワークフロー7.1k100 回インストール2 日前に更新
リポジトリ

harness-eval について

Harness Evalは、リポジトリ内のエージェントハーネスを評価するスキルです。正確性、冗長性、有用性のレポートを作成し、負荷の高い評価には事前承認を求めます。既定ではファイルを自動編集しません。

主な機能

  1. 01リポジトリの目録と主張を抽出
  2. 02スクリプトで参照パスとコマンドを確認
  3. 03任意の二重判定による冗長性評価
  4. 04任意の二重判定による有用性評価
  5. 05簡素化候補の参照元を確認

活用シーン

  1. 01エージェント向け説明のパスやコマンドを検証
  2. 02スキル内容の冗長性や有用性を評価
  3. 03ハーネスの簡素化前に評価レポートを確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/tech-leads-club/agent-skills --skill harness-eval

インストール後、Claude Code で/harness-evalを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
claims.schema.json
GLOSSARY.md
judge-prompts.md
PROTOCOL.md
scripts/
doc_scope.py
inventory_extract.py
merge_agreement.py
merge_usefulness.py
slim_fanin.py
surfaces_extract.py
track_a_correctness.py

詳細

ハーネス評価

スタックに依存しないハーネス評価を一通り実行し、レポートの作成までで停止します。ユーザーが Ship/Slim を確認したうえで明示的に依頼しない限り、AGENTS.md やスキルを自動編集しないでください。

ユーザーへの質問(最優先)

続行する前に停止して質問してください。 これらの確認手順を省略しないでください。任意のドキュメントを黙って含めたり、B/C の審査担当者を起動したりしないでください。

インベントリの後は、Q1(必要な場合)→ Q2 → Track A の順に進めます(A は必ず実行)。B/C は承認された場合のみ実行します。

Q1 — 任意のプロジェクトドキュメント(インベントリの後)

optional-docs-candidates.md に任意の種類が記載されている場合、Q2 / Track A の前に質問します。

Inventory found cited project docs outside the agent skill trees.

- **Always in scope:** skill-tree files (`.agents/skills`, `.cursor/skills`, `.claude/skills`)
- **Always excluded:** ADRs / RFCs / decision-record trees (never scored as T2)
- **Optional (default: omit):** see types/paths in `optional-docs-candidates.md`

Include any optional doc types or paths in this run?
Reply with: `none` (default), type ids (e.g. `docs`), and/or specific paths.

ユーザーの回答後に限り、--include-doc-type / --include-doc を指定してインベントリを再実行します。任意の種類がない場合は Q1 を省略します。

Q2 — Track B と C(Track A の前 — 予算)

ユーザーがあらかじめ費用を設定できるよう、Track A の前に質問します。次に実行する Track A は必須です(決定的で、モデルのトークンを約 0 消費します)。B/C は承認された場合のみ実行します。

Choose eval scope for this run (before Track A).

| Track | Question | Certainty | Token consumption |
|-------|----------|-----------|-------------------|
| **A — Correctness** | Cited path/command exists? | **Highest** — script only, no LLM. Prefers false negatives over false BROKEN. | **~0 model tokens** (always runs next) |
| **B — Redundancy** | Would an agent rediscover this cheaply without the harness? | **Medium** — dual LLM + plants; Ship only if trap PASS and both agree. Disagree → Hold. Less model-sensitive than C. | **High** — 2 judges × every claim (~N in this inventory). Each may spot-check the repo. |
| **C — Usefulness** | Does this surface change behavior vs theory/demo/overlap? | **Lowest / most subjective** — dual LLM + plants + fan-in; **model-sensitive**. Slim/Mixed need gates; prefer second-model check before large deletes. | **Highest** — 2 judges × every surface (whole files; often dominates the run). |

Notes: Ship (B) ≠ Slim (C). Rediscoverable ≠ useless. A always runs; B/C are optional.

Reply with one of: `A only`, `B`, `C`, or `B+C`.

判明している場合は、claims.md からクレーム数を記入します。抽出後の T0+T1+T2 の Markdown のおおよその数を提示するか、まだ実行していない場合は「surfaces_extract の実行後」と伝えます。

  • A only: Track A を実行し、04 を提示して停止します(B/C の審査担当者は起動しません)。
  • B: Track A を実行後、手順 4~6 を実行します。
  • C: Track A を実行後、手順 7~10 を実行します(C に B は不要です)。
  • B+C: Track A を実行後、手順 4~11 を実行します。

トリガーとなったメッセージでユーザーがすでに B/C/full eval を依頼している場合は、承認済みとして扱います。それでも費用がわかるよう、Q2 の表は一度提示してください。

このスキルのファイルを読み込む

このスキルは自己完結型です。プロトコル、スクリプト、審査用プロンプトは、このスキルのディレクトリ(SKILL.md を含むフォルダー)にあります。SKILL_DIR はそのディレクトリとして解決し、別のインストール先を決めつけないでください。

  • 最初の実行前に(スクリプトが失敗した場合は再度)references/PROTOCOL.md をすべて読んでください。
  • Track B または Track C の審査担当者を起動する際は、references/judge-prompts.md を読んでください。
  • 平易な用語の説明は references/GLOSSARY.md を参照してください(04 / 07 / 10 のレポート冒頭にも記載されています)。
  • クレーム記録の形式は references/claims.schema.json を参照してください(ツール用です。エージェントは毎回読み込む必要はありません)。
  • スクリプトは python3 "$SKILL_DIR/scripts/<name>.py" ... として実行してください。

実行結果(プロトコルを除く)は、対象リポジトリの .harness-eval/runs/<run-id>/ に保存します。

重要なルール

  1. デフォルトは報告のみです。 判定は修正ではありません。
  2. README は対象外です。 ハーネスの対象としても、再発見可能性/有用性の根拠としても扱いません。
  3. スタックに依存しません。 プロンプトやプラントで、パッケージマネージャー、DB、フレームワーク、フォルダー構成をハードコードしないでください。存在するマニフェスト(JS、Python、Make/Task、Rust、Go、PHP、Ruby/Rails、Java/Gradle/Maven、および bin/*)を検出してください。
  4. ドキュメントの対象範囲。 T2 には常にエージェントのスキルツリー参照(.agents/skills、.cursor/skills、.claude/skills)が含まれます。ADR / RFC(意思決定記録ツリー)は常に T2 の対象から除外します。その他の引用されたプロジェクト文書は任意です。デフォルトでは省略し、このスキルの先頭にある Q1 で確認してから、--include-doc-type / --include-doc を指定して再実行してください。
  5. 棚卸しの後は、常にトラック A を実行します(決定論的で高精度)。誤った BROKEN 判定よりも偽陰性を優先してください。プレースホルダー(SPEC_FOLDER、{x}、[feature])は決して BROKEN ではありません。str.lstrip('./') でパスを正規化しないでください。
  6. トラック B と C は、トラック A の前に Q2 を通じてユーザーの承認が必要です。 ユーザーが明示的に選択するまで、B/C の判定担当を起動しないでください。ユーザーは B のみ、C のみ、両方、または A のみを承認できます。
  7. トラック B には、二重判定担当とプラントが必要です。 Judge2 はブラインドであり、Judge1 のスコアや trap-key.json を読んではいけません。トラップゲートが PASS で、二重判定が REDUNDANT、かつ Judge2 のコストが 1 以下の場合にのみ Ship します。
  8. トラック C には、二重判定担当とプラントが必要です。 ブラインドの Judge2 は 08-usefulness-j1.md または usefulness-trap-key.json を読んではいけません。トラップが PASS で、二重判定が SLIM/ROUTING-ONLY、かつファンインが PASS の場合にのみ Slim します(他のハーネス対象がそのパスを SoT としてハードロードしていないこと。マージでは --seed だけでなく、スキルツリー全体に対して検証されます)。有用性はモデルに左右されます。両方のスコアファイルに model: <id> を記録してください。実行中は同じモデルを使うのが望ましく、大規模な Slim 削除の前には、2 つ目のモデルで再判定してください。
  9. KEEP / KEEP-CORE プラントは、デッキ内にすでにある主張/対象の逐語的なコピーにしてはいけません。
  10. サブエージェント: 許可リストにある非 fast モデルを使用してください(ポリシーが許す場合は、親と同じファミリーを優先)。*-fast モデルは使用しないでください。
  11. トラックを同一視しないでください。 トラック B の Ship はトラック C の Slim と同じではありません。再発見可能だからといって役に立たないとは限らず、役に立つからといって冗長でないとは限りません。
  12. Slim の適用/ファンイン。 「Slim fan-in blocked」に記載された Slim パス、または python3 "$SKILL_DIR/scripts/slim_fanin.py" --path <P> が参照元を報告する Slim パスは、同じ変更内でそれらの利用側を更新しない限り、スタブ化も削除もしないでください。
  13. Mixed/Slim の適用は自己完結させます。 REPO-DEMONSTRATED / THEORY を削除する場合は、ハーネス対象内の該当箇所を削除または圧縮してください。フェンス付きの説明用スニペット(または、それが担っていた契約)を See app/... / lib/... / test/... に置き換えてはいけません。これは SoT をコードツリーへのポインターに置き換えることになります。判定の根拠となるパスはスコア表にのみ記載してください。動作を変える契約を残す必要がある場合は、スキル内に短いルールまたはスニペットを残してください。
  14. Mixed の適用は機械的に行います。 二重判定が MIXED であるだけでは不十分です。マージ処理は、ID ごとに Keep-core 列から KEEP、Slim 列から CUT を記載した 11-mixed-apply.md を出力します。適用担当はそのファイルの指示にのみ従ってください。再判定、再設計、KEEP とは異なるパターンの考案はしないでください。Keep-core/Slim のセルが空の場合は、そのパスをスキップします(Hold)。

手順

ステップ 1:SKILL_DIR を解決する

SKILL_DIR を、この SKILL.md があるディレクトリに設定します。以下を確認してください。

  • $SKILL_DIR/references/PROTOCOL.md
  • $SKILL_DIR/scripts/inventory_extract.py
  • $SKILL_DIR/scripts/track_a_correctness.py
  • $SKILL_DIR/scripts/merge_agreement.py
  • $SKILL_DIR/scripts/surfaces_extract.py
  • $SKILL_DIR/scripts/merge_usefulness.py
  • $SKILL_DIR/scripts/slim_fanin.py
  • $SKILL_DIR/scripts/doc_scope.py

存在しない場合、スキルのインストールが壊れているため、停止してください。

ステップ 2:棚卸しと主張デッキ

対象リポジトリのルートから実行します。

RUN_ID=$(date -u +%Y-%m-%d)-full
python3 "$SKILL_DIR/scripts/inventory_extract.py" --root . --run-id "$RUN_ID"
# Optional scope: AGENTS.md + one-hop related skills only
# python3 "$SKILL_DIR/scripts/inventory_extract.py" --root . --run-id "$RUN_ID" --seed AGENTS.md

.harness-eval/runs/$RUN_ID/ に以下が生成される想定です:inventory.json、claims.jsonl、claims.md、trap-key.json、optional-docs-candidates.md(および .json)。

Step 2b: 任意のドキュメント — Q1(冒頭を参照)

optional-docs-candidates.md を読みます。任意のタイプが存在する場合は、ユーザーへの質問の Q1 を実行します。承認後にのみインベントリを再実行します。

python3 "$SKILL_DIR/scripts/inventory_extract.py" --root . --run-id "$RUN_ID" \
  --include-doc-type docs   # and/or --include-doc path
Step 2c: 予算を確認 — Q2(冒頭を参照)

Track A の前に、ユーザーへの質問の Q2 を実行します。回答(A only / B / C / B+C)を記録します。B および/または C が承認されていない限り、Step 4 以降を開始しないでください。

Step 3: Track A(決定論的)— 必ず実行
python3 "$SKILL_DIR/scripts/track_a_correctness.py" --root . --run-id "$RUN_ID"

想定される成果物:04-correctness.md(冒頭に用語の定義を含む)。.agents/... の参照先が解決されること(agents/... ではないこと)を抜き取り確認します。

Track A を要約します(問題の件数と注目すべきクラスター)。Q2 の回答が A only の場合は、ここで終了します。それ以外の場合は、承認された B および/または C のステップに進みます。

Step 4: Track B — Judge1

references/judge-prompts.md(Track B Judge1)を読みます。許可リストに登録されたモデルを使用し、独立したサブエージェントを起動します。.harness-eval/runs/$RUN_ID/claims.md を指定します。05-redundancy-j1.md(model: <id> を含む)を作成します。

Judge1 は inventory.json を読んでもかまいません。trap-key.json は読んではいけません。

Step 5: Track B — Judge2(ブラインド)

references/judge-prompts.md(Track B Judge2)を読みます。2 つ目のサブエージェントを起動します。06-blind-scores.md を作成します。

Judge2 が読むことを禁止するファイル:trap-key.json、05-redundancy-j1.md、07-agreement.md、過去の合意レポート。

Step 4 と Step 5 は並行して実行することを推奨します。

Step 6: Track B の合意を統合
python3 "$SKILL_DIR/scripts/merge_agreement.py" --run-dir .harness-eval/runs/$RUN_ID

想定される成果物:07-agreement.md(Ship/Review/Hold と これらの用語の意味)。トラップが FAIL の場合は、PROTOCOL に従って仕掛けを修正し、P00x を再採点して再統合します。Ship にしてはいけません。

Step 7: Track C — サーフェスデッキ
python3 "$SKILL_DIR/scripts/surfaces_extract.py" --root . --run-id "$RUN_ID"

想定される成果物:surfaces.md、surfaces.json、usefulness-trap-key.json。

Step 8: Track C — Usefulness Judge1

references/judge-prompts.md(Usefulness Judge1)を読みます。許可リストに登録されたモデルを使用してサブエージェントを起動します(ヘッダーに同じ ID を記録)。08-usefulness-j1.md を作成します。

usefulness-trap-key.json は読んではいけません。

Step 9: Track C — Usefulness Judge2(ブラインド)

Usefulness Judge2 のプロンプトを読みます。合意の安定性を高めるため、Step 8 と 同じモデル を使うことを推奨します。09-usefulness-j2.md を作成します。

読むことを禁止するもの:usefulness-trap-key.json、08-usefulness-j1.md、10-usefulness-agreement.md。また、有用性クラスの判断に Track B の 05/06/07 を使用してはいけません。

Step 8 と Step 9 は並行して実行することを推奨します。

Step 10: Track C の合意を統合
python3 "$SKILL_DIR/scripts/merge_usefulness.py" --run-dir .harness-eval/runs/$RUN_ID

想定される成果物:10-usefulness-agreement.md(Slim/Keep-core/Mixed/Hold と これらの用語の意味)、11-mixed-apply.md(各 Mixed ID の KEEP/CUT)、および slim-fanin.json。トラップが FAIL の場合は Slim にしてはいけません。slim-fanin-blocked のサーフェスは Hold です。Slim の適用候補ではありません。

Step 11: 結果を提示

合意レポート(それぞれ冒頭に用語の定義があります)に基づいて要約します。

  • Track A の問題件数 → 04-correctness.md
  • Track B のトラップと Ship/Review/Hold → 07-agreement.md
  • Track C のトラップ、ファンイン、および Slim/Keep-core/Mixed/Hold → 10-usefulness-agreement.md
  • Mixed の件数が 0 より大きい場合は 11-mixed-apply.md を明示します(Mixed の適用経路はこれだけです)
  • Track C で使用したモデル ID と、Slim がモデルに依存することを明示します
  • Slim のファンインがブロックされている行を明示します(seed の外にある利用側が含まれる場合があります)

ユーザーから Ship/Slim/Mixed の適用を依頼されない限り、ここで終了します。適用する場合:

  • Slim: Slim テーブルに記載されたパス(ファンインが PASS のもの)のみを対象とします。利用側を先に更新せずに、ファンインでブロックされたパスをスタブ化してはいけません。
  • Mixed: 11-mixed-apply.md を開き、ID ごとに KEEP/CUT のみを実行します(ルール 12)。Mixed のパス一覧だけを基に再判定してはいけません。カットしたデモの代わりに、コードツリーのパスポインターを追加してはいけません(ルール 11)。

例

例 1:ハーネス評価を完全に実行

ユーザーの依頼:「このリポジトリでハーネス評価を実行して」

実行内容:インベントリ → 必要に応じて Q1 → Q2(B/C の予算表)→ Track A → 承認された場合は Step 4〜11。B の判定者を並行して実行し、続いて C の判定者を実行します。合意結果を提示します(用語は各ファイルに記載されています)。

例 2:既存の実行結果で有用性のみを評価

ユーザーの依頼:「最後に実行した harness-eval の実行結果で Track C の有用性評価を実行して」

実行内容:その RUN_ID に対して Step 7〜11 を実行します(インベントリはすでに存在している必要があります)。

例 3: 誤ったスキル

ユーザーが「setup harness」/「init harness」と言った場合 → harness setup(このスキルではありません)。ユーザーが「specify feature」と言った場合 → tlc-spec-driven です。

トラブルシューティング

Trap ゲート FAIL(トラック B または C)

原因: KEEP/KEEP-CORE のプラントがデッキの重複であった、またはブラインドジャッジがファミリーを誤判定した。解決策: スキルの固定プラントテンプレートを使用し、プラントを再スコアリングし、再マージします。

トラック A で .agents/... が誤って欠落する

原因: パス正規化の不具合。解決策: スキルスクリプトは normalize_cite(./ のみを除去)を使用する必要があります。$SKILL_DIR/scripts/ からトラック A を再実行します。

サブエージェントがブロックされる

原因: モデルが欠落しているか許可リストにない、または *-fast がブロックされている。解決策: 許可リストにある非 fast モデルで再起動します。

モデル変更後にトラック C の Slim がおかしく見える

想定事項: 有用性はモデルに依存します。2 つ目のモデルで C1+C2 を再実行し、Slim 帯域の積集合が安全に削除できる集合です。

Mixed apply が規約を書き換えた / モジュールを削除した

原因: apply エージェントが KEEP/CUT に従わず、Mixed パスリストから再判定した。解決策: 11-mixed-apply.md 経由でのみ apply します。そのファイルが存在しない場合は merge_usefulness.py を再実行します。Keep-core/Slim のセルが曖昧な場合は、apply の前にそれらの ID を再スコアリングします。

T2 が空 / スキルの references/ がインベントリにない

原因: パス正規化が lstrip("./") を使用し、.agents/… を agents/… に変換した。解決策: doc_scope.normalize_rel は ./ プレフィックスのみを除去する必要があります(トラック A と同じルール)。

トラック C に ADR が出現した

原因: 古いインベントリがすべての 1 ホップの docs/** を T2 として扱っていた。解決策: v1.7+ では意思決定記録のツリーを除外します。ユーザーが承認したオプションのドキュメント種別(ADR/RFC は決して含まない)のみが T2 に入ることができます。

Slim スタブがそのファイルを読み込む別のスキルを壊した

原因: fan-in なしのコンテンツ OVERLAP/Slim — 古い実行、または apply がゲートをスキップした。解決策: チェックリスト本体を復元し、merge_usefulness.py で再マージします(fan-in はスキルツリー全体をスキャンします)。slim_fanin.py --path <P> で確認します。

スクリプトが見つからない

原因: スキルフォルダが不完全。解決策: $SKILL_DIR/scripts/ と references/ を復元します。

コメント