claude-harness-refs-update: 参照資料の鮮度チェックと更新
claude-harness の参照資料は 2 層 — 蒸留版 (skills/*/references/*.md。harness-design と ui-design が持つ) と原典 clone (~/.claude/references/<repo>/)。このスキルは鮮度チェックから再蒸留までを 1 コマンドで回す。参照資料の更新機構はこのスキルが一元所有する: scripts/check-freshness.sh が検出、DISTILLING.md が更新レシピと再蒸留プロンプト雛形、scripts/frontmatter.sh が install.sh と共用のパーサ、ADOPTION.md が「原典の変更を自分のハーネスに取り込むか」の判断台帳。参照スキル側 (harness-design / ui-design) は蒸留版を持つだけで、判定も規約も持たない。更新の入口はこのスキルだけ (スラッシュコマンドを増やさない)。
引数: repo 名 (例 12-factor-agents) を渡すとその repo だけを対象にする。--check で鮮度チェックのみ (更新に進まない)。無引数なら全 repo を対象に更新まで進む。
Process (run in order)
前提を解決する。
- 当日日付を控える:
date +%F。distilled_atに使う。サブエージェントは当日日付を知らないので、後で必ずプロンプトに埋める。 - このスキルの実体パスを解決する:
SELF="$(readlink -f "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/claude-harness-refs-update")"。以降$SELF/scripts/check-freshness.sh/$SELF/DISTILLING.mdを使う (skills/ は symlink なので実体パスを取るためreadlink -f)。 - claude-harness リポジトリのルートを解決する:
ROOT="$(dirname "$(dirname "$SELF")")"。蒸留版はharness-designとui-designの各スキル配下にあるので、出力先は$ROOT/skills/<skill>/references/<repo>.mdになる (どのスキルかは手順1の STALE 行に併記される)。 - 原典ルート:
REFS="${CLAUDE_CONFIG_DIR:-$HOME/.claude}/references"。clone は$REFS/<repo>。
- 当日日付を控える:
鮮度チェック —
bash "$SELF/scripts/check-freshness.sh"を実行 (fetch あり = 最新 upstream を反映)。1 ファイル 1 行で、行頭タグは「次にやること」を示す:OK/BEHIND(pull) /STALE(再蒸留) /REVIEW(知識ベースの棚卸し) /MISS/ERR/NOTE。BEHIND と STALE が同時に立つ repo は pull が先なのでBEHIND行だけが出る (/ 蒸留版も遅れが併記される)。NOTEは「判定できなかった」であって「最新」ではないので exit 1 側に数える — したがって exit 0 は全件検証済みを意味する。引数に repo 名があれば、その repo の行だけを対象にする (スクリプトに絞り込み機能はないので出力からフィルタ)。引数が--checkなら結果を提示してここで終了。exit 0 (= 要対応なし) なら「更新不要」と伝えて終了。MISS / ERR を処理 —
MISS(clone がない/壊れ) はinstall.sh --with-referencesを案内して中断する (clone がないと更新できない)。ERRは 2 種類:distilled_commitが履歴にない場合は行に併記された復旧コマンドに従う。frontmatter が 3 形式のどれでもない場合はDISTILLING.md「frontmatter の形式」を見て、その資料が蒸留版 (形式 1) / 知識ベース (形式 2) / 対象外 (形式 3) のどれなのかを決めて frontmatter を直す。BEHIND を解消 — 各該当 clone を
git -C "$REFS/<repo>" pull --ff-only。pull で新コミットが来ると STALE に変わるので、pull 後にcheck-freshness.shを取り直して STALE を再評価する (順序を守る — 古い HEAD で蒸留しないため)。STALE を再蒸留 — STALE の各リポジトリを
general-purposeサブエージェントに並列委譲する (Agenttool。蒸留版を Write するので Explore 不可)。各プロンプトは$SELF/DISTILLING.mdの「再蒸留プロンプト雛形」に次を埋めて作る:- 原典 clone パス
$REFS/<repo>と owner/repo - 出力ファイル
$ROOT/<STALE 行に併記された蒸留版パス>(例skills/ui-design/references/hallmark.md)。どのスキルの蒸留版かを取り違えないため、パスは推測せず STALE 行の記載を使う - 重点領域 — 既存蒸留版の索引が扱っている範囲を引き継ぐ
- 差分 —
git -C "$REFS/<repo>" log --oneline <distilled_commit>..HEADの内容 (何が変わったか。蒸留版に影響する変更だけ本文へ反映する判断材料) - 当日日付 (手順0の
date +%F) をdistilled_atとして明示 - 構成規約は
DISTILLING.mdに従うこと (frontmatter 3 キー /## Contents/## まず押さえる/ 索引テーブル /## 蒸留の範囲外/ 250 行以内 / 実際に Read した事実だけ・推測で書かない)
各サブエージェントは蒸留版 1 ファイルを Write し、frontmatter の
distilled_commitを clone の新 HEAD・distilled_atを当日に更新、最後に 2 本立てで返す — (a) 行数・使った SHA・内容の 3 行要約、(b) 取り込み候補 (DISTILLING.md「取り込み候補の抽出」の 4 点セット。該当なしなら「候補なし」と明示)。雛形にこの返却契約が入っているので、プロンプトから落とさない。- 原典 clone パス
REVIEW を棚卸し —
REVIEWは出所 clone を持たない知識ベース (avoid-ai-slop-*等) の期限切れ。SHA 差分がないので機械的な更新はできない。該当ファイルの主張を読み、出典 URL の生存と撤回、記述が前提にしているモデル世代・流行の変化を確認して本文を直す。委譲するならgeneral-purposeサブエージェント (WebFetch/WebSearch が要る)。直したらreviewed_atを当日に更新する。中身を見ずに日付だけ進めるのは禁止 (SHA の無言 bump と同じ)。見直した結果「変更不要」なら、その判断理由を commit message に書いて日付を進める。棚卸しで出典の撤回や前提の陳腐化が見つかったら、それも手順6の取り込み候補として扱う (知識ベースは自作なので、影響先は蒸留版ではなく自分のハーネスや文書規約になりやすい)。取り込み候補を照合して台帳に記録 — サブエージェントと手順5が返した取り込み候補を集める。 提示する前に、その候補が実際にこのハーネスに当たっているかを grep で確認する。 照合先:
$ROOT—skills/*/SKILL.mdの frontmatter (name の予約語・description の字数と書きぶり)、skills/*/references/、claude-md/、install.sh${CLAUDE_CONFIG_DIR:-$HOME/.claude}—settings.json/settings.local.json/CLAUDE.md、および対象プロジェクトの.claude/
「該当あり」と「該当なし (原典の記述としては正しいが、このハーネスには当たらない)」を分け、後者は深刻度を
FYIに落とす。grep せずに「影響あり」と言わない — 推測での警告は台帳を腐らせる。確認できたものをBREAKING→RECOMMENDED→FYIの順に提示し、ADOPTION.md へ追記する (書式は同ファイル冒頭)。台帳には前回までの未対応項目も残っているので、それも併せて提示する。候補ゼロなら「今回は取り込み候補なし」と明示する (黙って省略しない)。集約と確認 — 更新したファイル一覧と各 3 行要約、取り込み候補の件数 (深刻度別) を提示する。
bash "$SELF/scripts/check-freshness.sh" --offlineを再実行し、exit 0 に戻ったことを確認する。ここまでの変更は作業ツリーに残す。commit (ユーザーが望むときのみ) — 変更内容と、各リポジトリの差分 3 行要約を含む commit message 案を提示して承認を得てから commit する。SHA だけの無言 bump をしない (内容への影響なしと判断して SHA だけ進める場合も、その理由を message に書く)。
ADOPTION.mdの追記も同じ commit に含める。承認がなければ diff を残して終了。個人リポジトリなので main への直接 commit でよい。
Gotchas
- サブエージェントは当日日付を知らない → 手順0の
date +%Fを必ずプロンプトに埋める (distilled_atの正確性)。 - BEHIND を pull してから STALE を再評価する。順序を逆にすると古い HEAD で蒸留してしまう。
- 出力先は symlink 越しでなく
readlink -fで解決した実体パスを使う。蒸留版が属するスキルは repo ごとに違う (harness-design/ui-design) ので、STALE 行のパスをそのまま使い、harness-design決め打ちにしない。 check-freshness.shに repo 絞り込みはない → 特定 repo 指定時は全走査の出力からフィルタする。- 再蒸留は必ず
DISTILLING.mdの構成規約をプロンプトに渡す (250 行以内 / 索引駆動 / 推測で書かない)。規約をサブエージェントの記憶任せにしない。 REVIEWは SHA 差分が無いので「何が変わったか」を機械的に出せない。出典の生存と、記述が前提にしているモデル世代・流行の変化を人手 (または Web 検索できるサブエージェント) で確認する。- 蒸留版を最新にしただけで終わらせない。原典が変わっても自分のハーネスは自動では直らない → 手順6の取り込み候補まで回す。
- 取り込み候補は必ず grep で実ハーネスに当てて深刻度を決める。原典の記述が正しくても、このハーネスに当たらなければ
FYI。推測での「影響あり」は台帳を腐らせる。 - 二次資料 (
claude-code-best-practice等) 由来の候補は、公式 docs との食い違いが原典側の誤検出である場合がある。原典の changelog が自ら INVALID にした項目を取り込み候補に昇格させない。 - 新規リポジトリの追加は別作業 (
DISTILLING.md「新規リポジトリの追加」)。このスキルは既存蒸留版の更新に使う。
Quick checklist
-
date +%Fを控え、サブエージェントにdistilled_atとして渡した -
MISS/ERRを先に解消した (clone 未取得ならinstall.sh --with-references) - BEHIND を
git pull --ff-onlyしてから STALE を再評価した - 各再蒸留が
DISTILLING.mdの規約 (frontmatter 3 キー / 250 行以内 / 推測で書かない) に従った -
distilled_commitを clone の新 HEAD に、distilled_atを当日に更新した -
REVIEWは出典と前提の生存を確認したうえでreviewed_atを進めた (日付だけの bump をしていない) - 各サブエージェントから取り込み候補を受け取った (該当なしの明示も受け取った)
- 取り込み候補を実ハーネスに grep で当てて深刻度を確定し、
ADOPTION.mdに追記した - 台帳の未対応項目 (前回以前の分を含む) を提示した
-
check-freshness.shが exit 0 に戻った - commit する場合、message に差分 3 行要約を含め、
ADOPTION.mdの追記も同じ commit に入れた (SHA だけの無言 bump をしない)