--- name: latch description: | 指示文書(AGENTS.md, SKILL.md, システムプロンプト)の候補を, 要件を固定したまま作り分け, 弱いモデル(Claude Haiku, GPT Luna)で並列実行した振る舞いを境界ケースで照合し, 文書を実際に読むモデルでも保持版を後退させない候補だけを採用する. ユーザーが latch による指示文書の比較実験を求めた場合に使用する. disable-model-invocation: true --- # Latch 私は, 指示文書を候補間の振る舞い比較で改善し, 保持版を後退させる候補を採用しない. 弱いモデルは指示の不足を見つける検出器として使い, 採否の最後に, 文書を実際に読むモデル(ゲートモデル)で後退していないことを確かめる. 弱いモデルで足りた指示が強いモデルにも最適だとは限らないからである. 隔離, 並列実行, 匿名化, 判定計算, 判定規則のシミュレーション, 要因計画は, この SKILL.md と同じディレクトリの `scripts/` に任せ, 私は判断を要する部分を受け持つ. ファイル形式と隔離の仕組みは `scripts/README.md` にある. ## 実験ディレクトリ 私は実験を新しいディレクトリ(例: `~/latch/<対象名>/`)に作り, その外のファイルを作成も変更もしない. 実験ディレクトリは, 祖先に `CLAUDE.md`, `CLAUDE.local.md`, `AGENTS.md`, `AGENTS.override.md`, `.agents/`, ホーム以外の `.claude/`, `.git` のない場所に作る. Claude Code は祖先の `CLAUDE.md` を, Codex は git ルートからの `AGENTS.md` を全試行に読み込むからである. 対象の文書や資料は読むだけにし, 現行文書はフロントマターを含めてそのまま `variants/baseline_original.md` に複製し, その元の絶対パスを `plan.json` の `source` に書く. 試行ごとに複製する作業環境は, 実験ディレクトリの `env/` に作る. `env/` には比較する文書を含めず, 文書が操作する外部の対象(tmux, Obsidian の Vault, 実リポジトリなど)は, 偽コマンドや複製で置き換える. 試行に要る環境変数と偽コマンドの置き場所は `plan.json` の `env_vars` と `path_prepend` に書き, CLI の設定ファイル(`.claude/settings.json`, `.codex/config.toml` など)を作って渡さない. ## 要件の行 私は, 既存文書があればその内容を, なければユーザーの要件を, 1行1要件で `p.tsv` に書き出す. 各行には適用条件, 様相(義務, 禁止, 許可), 強さ, 行為, 順序, 重大かどうかを書く. 重大とは, 1回の違反も許さない行であり, その判定の規則は事前登録で `results.md` に書く. ## 境界ケース 私は候補を書く前に, 期待行動が条件で切り替わる箇所ごとに境界ケースを `cases.jsonl` に書く. 現行文書のもとで失敗した実際の記録があれば, それをケースの元にする. 各ケースには入力, 行ごとの期待行動, 合否の証拠(ツール履歴, 成果物, 最終報告)を付け, 履歴や成果物で判定できる行は機械判定にする. 手順そのものが要件である行だけを経路(`tool`, `order`)で判定し, ほかの行は結果(`file`, `unchanged`, `final`)で判定する. 強いモデルは想定外の正しい経路を取るからである. ケースの入力は文書を名指しせず, 文書に従うかどうかで観察できる結果が変わる依頼にする. 期待行動を変えない言い換えは, そのケースの `inputs` に並べる. 禁止の行には違反を誘う入力を含め, 環境でも強制される禁止は試行と成否を別の行にする. 環境で強制されない禁止は, 別の手段での実現も捕まえられるよう, 呼び出しの照合(`no_tool`)に加えて効果の証拠(`unchanged` か成果物)で判定する. 許可の行では, 許された行為を選ばなかったことを違反に数えない. 私は強いモデルに固有の失敗もケースに含める. 頼まれていないことまでやることは, 期待した成果物を `exclude` に入れた `unchanged` で判定し, 確認を求めすぎて止まることは `final` か `judged` で判定する. 私はケースを select(4つ以上)と holdout に分け, holdout を候補の選定に使わない. 可能なら, 候補を読んでいない別セッションにケースを書かせる. ## 候補 私はラウンドを2段に分ける. - 探索段: 同じ行を満たさせる方針が互いに異なる候補を4〜6個作る(手順を指定する, 完了状態だけを指定する, 義務と許可の境を示す, 条件と例外を示す, 対照用例を示す, など). 任意の2候補について体裁でなく方針の差を一文で言えるようにし, 箇条書き, 表, 見出しの違いだけの候補は調整段に回す. 例外を足すなど適用条件を変える候補は p の改版として扱い, 意図して変える行を `plan.json` の `changed_rows` に書き, その行の新しい期待行動をケースに足す. - 調整段: 探索段で残った候補の行をすべて固定し, 表現だけを変える(発話内力, 丁寧さ, 明示の量). 表現は1軸ずつ比べず, 言い換える文とその代わりの文を要因として `factors.json` に書き, `scripts/factorial.py` の要因計画で比べる. 強さを固定して言い回しを比べる要因計画と, 強さ自体を動かす要因計画は分ける. 要件を運ばない文(`trace.tsv` に引用されない理由, 例, 補足)は, 外す水準を持つ要因にして寄与を測る. 私は, 外せると出た文を外した候補や, 要因ごとに最良の水準を選んだ候補を作り, 通常のラウンドで保持版と比べる. 別々には外せる文も, まとめて外すと効くことがあるからである. 私は候補ごとに, 狙う振る舞いの変化と, それを確かめるケースを実験ディレクトリの `hypotheses.md` に書く. `variants/` には比較する文書だけを置く. 強調表現は p に含まれる分を超えて加えない. 候補ごとに各行を表した文を `trace.tsv` に引用し, 準備のうちに `scripts/check_trace.py` を通るまで直す. 意味が保たれているかは自分で確かめる. `variants/` には候補のほか, 対照として現行文書の原文(`baseline_original`), 文書なし(`baseline_none`), 保持版のバイト単位の複製である A/A 対照(保持版が `baseline_original` なら `baseline_aa`, 候補 `` なら `baseline_aa_`)を置く. 候補が差分なら, 現行全体と差分を組み込んだ全体を置き, regression ケースで比べる. ## 事前登録 私は実行前に `plan.json` を書き, 結果を見てから変えない. 決めるのは, 通常の行で拒否する低下幅(`reject_drop`), 信頼限界の水準(`confidence`), select と holdout の両方で求める最小改善幅(`min_gain`), 改善がなくても採用する短縮率(`min_shrink`), 意図して変える行の合格率, 反復回数(3以上), 追加試行の上限, 探索モデル, 推論強度(Luna は high を主条件とする), ゲートモデルである. ゲートモデル(`gate`)には, この文書を実際に読むモデルを書く. 文書は各 CLI が普段読み込む位置(`CLAUDE.md`, `AGENTS.md`, スキルのディレクトリなど)に置く. 私は, A/A の誤棄却率と誤採用率, 想定する改善幅での採用率について求める基準を `results.md` に書いてから, 登録した表のまま `scripts/simulate.py` を流し, その結果を `results.md` に書く. 前ラウンドの採点があれば `--from-runs` で合格率を与える. 基準を満たさなければ, 反復回数かケースを増やしてから登録する. 同じ時点で, 私は `results.md` に採否の規則を文章で書く: - 重大な行は, 保持版がそのモデルで違反していなければ候補の1回の違反で拒否し, 保持版も違反していれば候補の違反率が確かに低いことを求める. - 通常の行は, ケースをまたいだ低下量の信頼限界で判定する. 下限が `reject_drop` 以上なら拒否し, 上限が `reject_drop` 未満なら非劣性とし, その間なら追加試行を足す. 上限に達しても決まらなければ保持版を据え置く. - 探索モデルのすべての行で非劣性が確かめられ, かつ次のどちらかを満たす候補を, ゲートモデルでも全行が非劣性なら採用する. 一つは, 少なくとも一方の探索モデルで最小改善幅以上の改善が select で示され, holdout でも再現したこと. もう一つは, 文書の文字数が保持版の `1 - min_shrink` 倍以下であること. - A/A 対照が採用される判定になったラウンドでは, 全候補で保持版を据え置く. - 同点や判定不能は保持版を据え置く. - 採用した候補はそのファイルのまま `variants/` に残し, 次ラウンドの `--held` に渡して保持版にする. ## 実行と判定 私は実験ディレクトリの `run.sh` に `"$SKILL_DIR/scripts/latch.sh" . --held <保持版>` を書く. `SKILL_DIR` はこの SKILL.md のあるディレクトリの絶対パスであり, 初回の保持版は `baseline_original`, 以降は前ラウンドで採用した候補である. `run.sh` は準備を終えた実験ディレクトリでそのまま最後まで動くように書き, 手作業の前提や, 前提が欠けたときに止める確認を置かない. 準備中に作れなかったものは `plan.json` の項目や `env/` の偽コマンドで代わりに用意し, それでも用意できなければ最終報告に書く. `latch.sh` は trace の確認, 祖先の走査と実CLIでの混入確認, 試行, 採点, 判定を順に行う. その後, 判定が求める追加試行と, 探索モデルを通った候補のゲートモデルでの試行を, 上限まで自動で足して判定し直す. ## 次ラウンドと報告 採用した候補を保持版とし, 採用しなかった候補は `variants/` から実験ディレクトリの `rounds//` に移す. `variants/` の文書はすべて試行と判定の対象になるからである. 私は, 失敗した試行の記録(`runs//history.jsonl`, `last.txt`)を行ごとに読み, 失敗の型を `results.md` に書く. judged の判定の一部を人が確かめ, 審査員との一致率を `results.md` に書く. そのうえで, 次に動かす1軸とその理由を `results.md` に書く. 改善が止まるか予算に達したら終了する. 最終報告には, 作成したファイルの一覧, `run.sh` の起動方法, まだ行っていない工程(試行, 採点, 判定, 記録の読み込み, 人による確認)を書く.