Belweave/belay

コマンドで計測可能な目標(すべてのテスト通過、監査完了、高速化、小型化、ツール移植、UIやテキストの洗練など)に、小さな検証済みのステップを積み重ねて到達します。各変更はロックされたチェックで評価され、成功すればコミット、失敗すれば元に戻されます。ユーザーが「belay」「hill climb」「climb this」「keep going until it passes」と言ったときや、測定可能な目標に向けた長時間の無人実行を希望するとき、または登山の再開や報告を依頼したときに使用します。

belay とは?

Belayは、AIエージェント(Claude Code、Cursor、Codexなど)向けのスキルで、コマンドで評価可能な目標を小さなステップの積み重ねで達成します。`scripts/belay.py`というPythonスクリプトが中心的な役割を果たし、ステップごとにチェックコマンドを実行し、成功すればコミット、失敗すれば変更を元に戻します。このスキルは、テストの修正、パフォーマンスの最適化、UIの改善、コードの監査など、幅広いタスクに適用可能です。ユーザーは「belay」などのキーワードで起動し、カードを使って目標を定義します。チェックは出力する数値で評価され、ガードやホールドアウトで品質を担保します。ローカルファイルシステムに状態を保存し、クラッシュ後も再開可能です。重要なのは、チェックを決して欺かないことと、人間の判断を必要とする質問のみをユーザーに投げかけることです。このスキルは、長時間の無人実行や、反復的な改善が必要な開発タスクに特に有用です。

対応~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Belweave/belay/tree/HEAD/skills/belay

Installed? Explore more 生産性&コラボレーション skills: steipete/gemini, steipete/gh-issues, steipete/skill-creator · View all 6 →

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

belay は何をしますか?

目標を小さなステップで達成します。チェックが人間の介入なしに各ステップを評価します。 scripts/belay.py がスコアを管理します。あなたが編集し、チェックを実行し、成功ならコミット、失敗なら元に戻し、ログを記録します。自分でスコアを書き留めることはなく、ステップが「基本的に」合格したと判断することもありません。

すべての目標は、数値を出力するコマンドという同じ形になります。高速化は時間やカウントです。監査は、発見事項ごとに1つの失敗テストの数です。移植は一致する出力の数です。UIは審査員のスコアです。

作業の進め方:

  • ユーザーが登山を開始し、その場を離れます。 進捗報告のために止まらないでください。ユーザーが読むのはカード、ユーザーだけが答えられる質問、そしてレポートの3つだけです。ハーネスに質問ツールがあれば、それを使って質問してください。
  • 状態はディスクに保存され、チャットには残りません。 カード、ログ、メモ、最後のチェック出力は .belay/<name>/ の下にあります。圧縮やクラッシュの後は、status で一度にすべてを復元できます。
  • スリープループで待つことはしないでください。 長時間かかるコマンドはバックグラウンドで実行し、その間に次のステップを計画してください。
  • BELAY は、このファイルの隣にある scripts/belay.py の絶対パスです。 各コマンドにフルパスを記述してください。ターゲットリポジトリの内部から実行してください。渡すパスとコマンドはリポジトリルートからの相対パスです。
  • 登山は独自のブランチ climb/<name> を作成します。 元に戻されたステップはツリーをリセットし、git が無視しない追跡されていないファイルを削除します。このチェックアウトで他の誰かが作業している場合は、別のワークツリーで登山を行ってください。この作業用にすでにブランチが作成されている場合は、--here を渡してください。

1. 開始前に再開する

python3 "$BELAY" list を実行します。この目標の登山が存在する場合は、そのブランチに切り替え、status <name> を実行し、ステップ4に進みます。クラッシュ後や新しいセッション後の「続行」とは、これを意味します。最初からやり直さないでください。

2. チェックを構築する

登山はチェックの質に依存します。間違ったものを測定するチェックは、実行全体を間違ったものの改善に費やします。まずは大まかなチェックを動かし、後で relock を使って洗練させます。

自問してください:目標が達成されたことを確認するために何を実行しますか?そのコマンドが数値を出力するようにしてください。状況に最も適した強力な形式を使用します:完全一致またはテスト数、次に作業のカウント(クエリ、ラウンドトリップ、バイト数)、次にクロック、そして味覚以外に判断方法がない場合のみモデル審査員を使用します。

目標スコア
バグまたは機能修正からではなく、仕様から書かれた失敗テスト
監査、安定化、「X を動作させる」失敗テスト、発見事項ごとに1つ
速度またはサイズ時間の背後にある作業のカウント、または時間自体
移植またはクローン実際のツールと一致する出力
複数の目標を同時に最も悪い基準に対する進捗
見た目、感触、文章ルーブリックと適切な例を含む judge.py

各目標のレシピは references/checks.md にあります。チェックを書く前に、自分の目標に合った部分を読んでください。

リポジトリにあるものを使用してください。--score '<regex>' は、--score '(\d+) failed' のように、任意のテストランナーの出力からスコアを読み取ります。最後に一致する行を取得し、キャプチャした数値を合計します。一致がない合格実行はスコア0になります。--score がない場合、チェックの標準出力の最後の行がそのままの数値である必要があります。--check を繰り返して複数のコマンドを同時に実行できます。それらのスコアは加算されます。登山が編集する他のチェックアウトごとに --repo <path> を追加します。ステップはその後、それらすべてで一緒に保持されるか元に戻されます。

チェックを信頼する前に証明してください:

  • 失敗できること。 意図的にコードを壊し、スコアが悪化することを確認します。git checkout -- <file> で復元します。
  • 成功を確認できること。 小さな実際の改善がスコアを動かす必要があります。
  • 安定していること。 3回実行します。コード変更なしでスコアが変動する場合は、クロックをカウントに置き換えるか、--runs 3、変動以上の --min-gain(スコアが大きく減少する場合は 3% などのパーセント)、および --paired を使用します。
  • ごまかせないこと。 実行ごとに入力を変え、参照と比較します。答えをハードコードするなど、不正を1つ手動で試し、チェックまたはガードがそれをキャッチすることを確認します。
  • 高速であること。 すべてのステップでチェック時間を支払います。ステップを2分未満にします:ステップごとにサンプルまたはカウントをスコアリングし、完全なスイートまたはタイムドランはガードまたはホールドアウトとして保持します。
  • バーに到達可能であること。 現在の設計で可能な最良を計算します。バーがそれを超えている場合は、その旨をカードに記載し、到達可能なバーを提案します。

スコアが測定しないものをすべて保護します:

  • ガード(--guard、終了コード0でパス)。変更するコードが触れるものをリストアップします:呼び出し元、他のプラットフォーム、保存されたデータ、公開API。それぞれにガードが必要です:今日パスするテスト、型チェック、lint、ビルド。スコアが失敗カウントの場合、これらのパスするテストを独自のファイルにガードとして保持し、クラッシュが「失敗の減少」としてパスできないようにします。
  • ロック(--lock)チェック、テスト、フィクスチャ、およびホールドアウト。try はロックされたファイルが異なる場合、スコアリングを拒否します。--lock パスの下の新しいファイルは、登山ブランチの最初のコミットになります。他のコミットされていない変更は init を停止します。
  • ホールドアウト(--holdout)、チェックがサンプル、ベンチマーク、または審査員を使用する場合:登山が決して訓練しないケースで、.belay/<name>/holdout/ の下に保持されます。それらを再度開かないでください。スコアが上昇してもホールドアウトが上昇しない場合、登山はオーバーフィッティングしています。停止してその旨を伝えてください。

監査とオープンな目標。 目標がカバーする内容を .belay/<name>/notes.md のチェックリストとしてリストアップします。エリアごとにバグを探します。実際の発見事項ごとに、仕様またはバグレポートから1つの失敗テストを書きます。後のステップで新しいバグが見つかった場合は、そのテストを追加し、relock --why "found <bug>" を実行します。スコアは正当な理由で上昇し、ログにはその理由が示されます。ユーザーの判断が必要な発見事項は、スコアではなく、メモとレポートに記載します。

3. カード、次に init

決定するために、カードとそれだけを含む1つのメッセージを送信します:

登山カード: build-speed

目標: コールドビルドを2倍高速化、同じ出力

スコアビルド秒数の中央値、低いほど良い:現在47.0、目標23.5
チェック./scripts/bench-build.sh、3回実行、ペア、最小ゲイン3%
ガードnpm test、npm run typecheck
ホールドアウト12のサンプルアプリのうち3つ
ロックscripts/bench-build.sh、test/、samples/
制限なし(ステップあたり約2分)

あなたの回答が必要です: なし

go と返信するか、行を変更してください。

すべての行を最良の選択で埋めてください。ユーザーが目標をバーなしで与えた場合は、「2倍高速」や「すべてのサンプルが一致」など、野心的でチェック可能なものを提案します。「go」を待ちます。これにより、カード、ブランチ、およびそのコミットが承認されます。ユーザーがすでに尋ねずに実行するように指示した場合、または目標が小さくバーに疑いがない場合は、待機をスキップし、カードをレポートの先頭に配置します。その後は、自分で調べたり決定したりできることを尋ねないでください。

python3 "$BELAY" init build-speed --goal "cold build 2x faster" \
  --check ./scripts/bench-build.sh --direction min --target 2x \
  --runs 3 --paired --min-gain 3% --guard "npm test" --guard "npm run typecheck" \
  --holdout ./scripts/bench-holdout.sh --lock scripts --lock test \
  --lock .belay/build-speed/holdout

バックエンドとフロントエンドにわたる監査:

python3 "$BELAY" init billing-audit --goal "every billing finding fixed" \
  --check "pytest tests/billing -q" --check "cd ../web && npx vitest run billing" \
  --score '(\d+) failed' --direction min --target 0 --repo ../web \
  --guard "pytest tests/legacy -q" --guard "cd ../web && npx tsc --noEmit" \
  --lock tests/billing --lock ../web/src/billing/__tests__

init はブランチを作成し、ベースラインを測定し、ガードがすでに失敗している場合は開始を拒否します。最初のステップの前に、警告された内容を修正してください。ユーザーが制限を指定した場合にのみ、--max-hours または --max-steps を設定します。指定がない場合、登山はバーが満たされるか行き詰まるまで実行されます。

4. 登山

各ステップは1つのアイデア、1つの変更、1つの try です:

  1. アイデアを選びます。ログがすでに元に戻したものを、何が違うかを説明できない限り再試行しないでください。審査員が使用されている場合は、.belay/judge-notes.md を読んでください。
  2. 1つの理由で1つの変更を行い、その効果を推測します。推測をアイデアに入れます:"cache the parser (expect -10%)"。推測が大きく外れた場合、コードのモデルが間違っています。次のステップの前にプロファイリングします。
  3. python3 "$BELAY" try "<idea>"。成功をコミットするか、ツリーをリセットします。どちらにせよ、次に進みます。ステップの完全なチェック出力は .belay/<name>/last.txt にあり、最良のステップの出力は best.txt にあります。チェックを再実行する代わりにこれらを読んでください。
  4. チェックの実行中はツリーを編集しないでください。登山を変更する belay.py コマンドは同時に1つだけ実行されます。別のコマンドがまだ実行中であると表示された場合は、それが終わるのを待ちます。
  5. 5ステップごとに、.belay/<name>/notes.md を数行で更新します:うまくいっていること、うまくいっていないこと、次に試すこと。次のセッションはここから再開します。

チェックが2回元に戻したアイデアを信じている場合、チェックはそれを評価できていません。チェックをより細かくし、relock してください。ステップをパスさせるためにロックされたファイルを編集しないでください。

チェックを決して欺かないでください

以下のそれぞれはスコアを上げますが、作業を悪化させます。try が保持しても、それぞれは失敗した登山です:

  • チェックが使用する入力を特殊ケース化する、または期待される出力をハードコードまたはキャッシュする。
  • テストをスキップ、弱体化、削除する、またはエラーをキャッチして隠す。
  • コードを高速化する代わりに、ベンチマークが行う作業を減らす。
  • relock を使用して、難しいケースを削除または緩和し、バーを満たす。Relock はチェックをより正確にするためだけに行います。バーに到達できない場合は、測定したフロアを報告します。
  • ホールドアウトを読む。

真の勝利は、チェックがこれまで見たことのない入力でも、同じコードをより良くします。前進する唯一の方法がこれらのいずれかである場合、チェックが間違っています。その旨を伝えてください。

常に再評価し続ける

スコアはユーザーが望むものの代用品にすぎません。それが依然として正しいことを確認してください:

  • 保持された10ステップごと、およびバー到達時: 実際のものを自分で確認します。アプリを開き、出力を読み、スクリーンショットを表示します。完全なテストスイートと holdout を実行します。スコアと実際のものが乖離した場合は、チェックを修正し、relock --why "..." を実行します。
  • ガードがキャッチしなかった何かが壊れた場合: git bisect run <failing command> でステップを見つけ、try --fix "<what broke>" で修復します。これにより、スコアを維持する変更が保持されます。唯一の修復方法がそのステップのゲインを放棄することである場合は、git revert でステップを元に戻し、relock --why "reverted step N: broke X" を実行します。不足していたガードを追加します。
  • レポートの前: git diff <start>..HEAD を1つの変更として、新鮮な目でレビューします。削除されたテスト、飲み込まれたエラー、オフにされた機能、変更されたデフォルト、データおよびAPIの変更を探します。try --fix で修復し、レポートが測定された数値を引用できるように、チェックと holdout --why final をもう一度実行します。

5. 行き詰まった場合

try と status は、5ステップゲインがないと PLATEAU を表示します。アイデアを試すのをやめ、障害を見つけます。推測する前に測定します:

  • 時間やエラーカウントは実際どこから来ていますか?プロファイリングします。
  • チェックは不安定ですか、小さなゲインを見るには粗すぎますか、または問題を見逃していますか?
  • 小さなステップでは到達できない、より大きなアイデアがありますか?
  • 次の10ステップを変えるためのツール、アクセス、データ、または計算リソースは何ですか?

python3 "$BELAY" review "<what you found>" で記録し、PLATEAU を5ステップ静めます。修正できるものは修正します:より高速なチェック、より細かいメトリクス、異なるアプローチ。ユーザーにのみ尋ねます。アクセスやお金など、ユーザーだけが提供できるものについて、他のすべてのアイデアを使い果たした後にのみ尋ねます。

6. 停止して報告する

以下のいずれかが真になった場合に停止します:

  • try が BAR REACHED を表示します。自動的にホールドアウトを実行します。フラットなホールドアウトでの目に見える勝利は勝利ではありません。
  • status が STUCK を表示します:2回のブロッカーレビューがあり、その間にゲインがありません。
  • try が「Budget used」で拒否します。
  • ホールドアウトがスコアと一致しません。
  • 次のステップにユーザーだけが提供できるものが必要です。

その後、上記の最終レビューを実行し、.belay/<name>/data/ を削除し、レポートを送信します。10秒で読めるようにします:

登山 build-speed: バー到達

47.1秒 → 18.7秒、2.5倍高速化(目標23.5秒、ステップ41で到達)

ホールドアウト51.0秒 → 20.2秒、スコアとともに移動
ステップ52ステップ中19保持
安全性保持されたすべてのステップでガードがパス。完全スイートと最終レビューはクリーン
ブランチclimb/build-speed、19コミット

うまくいったこと

  • 増分型キャッシュ: −12秒

試して元に戻したこと

  • swc への置き換え: 3つのガードを壊した

あなたの次の行動

  • レビュー: git log --oneline 1a2b3c4..climb/build-speed

見出しは次のいずれかです:バー到達、行き詰まり、予算消費、ホールドアウト不一致、あなたが必要。スクリプトが測定した数値を引用し、推定値は決して使用しません。途中でチェックやバーを変更した場合は、その旨を見出しに記載します。最大のゲインを最初に。セクションごとに最大3箇条。空のセクションはスキップします。

ユーザーがさらに望む場合は、同じ主張に対して raise 2x --why "..." でより厳しいバーを設定し、登山を続けます。新しい目標に決して切り替えないでください。

サブエージェント

ハーネスがサブエージェントを起動できる場合は、セットアップ中の並行読み取り、およびブロッカーレビューと最終レビューのための新鮮な視点のために使用します。ファイルダンプではなく、結論を求めます。登山ツリーに書き込むのはあなただけです。try がツリーをリセットするためです。ヘルパーは読み取り、または独自のワークツリーでパッチを作成し、あなたが適用して try できるようにします。サブエージェントがない場合は、インラインで行います。

コマンド

コマンド機能
init <name> --goal "..." --check "..." --direction min|maxベースライン、ブランチ、ロック。オプション:--check(繰り返し可)、--score '<regex>'、--target(数値または 2x)、--guard(繰り返し可)、--lock(繰り返し可)、--holdout、--repo(繰り返し可)、--runs、--paired、--min-gain、--timeout、--max-hours、--max-steps、--here
try "<idea>" [--fix]編集をスコアリングし、保持または元に戻します。--fix はスコアを維持する修復を保持します
status [name]スコア、最後のステップ、メモ、PLATEAU または STUCK
relock --why "..."変更されたチェックを受け入れ、再度測定します
holdout --why "..."今すぐホールドアウトを実行します
review "<found>"ブロッカーレビューを記録します
raise <bar> --why "..."このバーに到達した後、より厳しいバーを設定します
budget [--hours N] [--steps N]予算を設定または更新します

関連スキル