Claude Code の並列エージェント(agent teams・teammate)の後始末と無応答時の打ち切りルール。`name` を付けて Agent を起動するとき、TeamCreate でチームを組むとき、teammate から `idle_notification` が届いたとき、評価ループ等で次のイテレーションのエージェントを起動する前、エージェントの返信が届かないときに参照する。`name` を付けない通常のサブエージェント起動だけなら対象外。
lane-ops
herdr 上で稼働中のエージェントレーン(別 pane の claude 等)を親として操縦・監視・承認代行するときに必ず使用する。
トリガー: 「レーンを見て」「ワーカーに指示して」「承認待ちを捌いて」「レーンの完了を検証して」「境界を広げて」の依頼、`[lane-ops:report ...]` 形式の報告が会話に届いたとき、herdr レーンの blocked 対応・報告の裏取り・指示送信・タスク境界の拡張が必要になったとき — スキル名や herdr が名指しされていなくても発火する。
HERDR_ENV=1 必須。
含まれるファイル(17)
- SKILL.md16.4 KB
- .gitignore4.5 KB
- example.envrc66 B
- pyproject.toml588 B
- references/worker-contract.md9.8 KB
- scripts/report.sh2.8 KB
- scripts/send_instruction.sh2.2 KB
- scripts/test_watch_events.py8.0 KB
- scripts/test_worker_contract.py19.1 KB
- scripts/tests/report.test.sh4.2 KB
- scripts/tests/send_instruction.test.sh3.2 KB
- scripts/tests/widen_boundary.test.sh3.1 KB
- scripts/verify_lane.sh2.5 KB
- scripts/watch_events.py22.0 KB
- scripts/widen_boundary.sh1.7 KB
- scripts/worker_contract.py24.5 KB
- uv.lock4.5 KB
SKILL.md(原文)
インストールする前に、エージェントに与えられる指示の中身を確認できます。
lane-ops
herdr 管理下のエージェントレーン(pane 内で動く claude 等のワーカー)を、親(このセッション)が操縦・監視・承認代行するための運用規約と決定論スクリプト集。指示送信・blocked の push 検知・報告の機械検証・境界拡張はすべて同梱スクリプトで行う。job-graph 等のオーケストレーションから呼ばれるほか、手動で立てたレーンにも単独で使える。
最初に test "${HERDR_ENV:-}" = 1 を確認し、失敗したら herdr 管理下でない旨を伝えて停止する。
役割分担の原則: 指示・報告 = 同梱スクリプト(herdr prompt + ファイル)/ 承認・生死・画面 = herdr / 真実 = git・gh。ポーリング(sleep + 再確認)はしない。
以下、スキル本体のパスを <SKILL> と表記する。Python スクリプトは stdlib のみで、python3 で直接実行できる。
親の名前(報告の宛先)
ワーカーからの報告は herdr のエージェント名宛てに届く。親はレーン起動前に自分へ決定論的な名前を付ける:
herdr agent rename "$HERDR_PANE_ID" <一意な短い名前> # 例: orc-<リポジトリ名>
この名前をワーカー規約(worker_contract.py の parent)へ渡す。
スクリプト(各 1 責務のフィルタ)
scripts/worker_contract.py— ワーカー規約の正本。stdin にタスク情報 JSON(task_id/branch/base/default_base/boundary/issue/parent、任意でplan(計画ファイルの絶対パス)/scope_check(PR 前に実行する計画突合コマンド)/mode(implement既定 /maintain)を受け取り、ワーカーへ渡す標準セクション(報告義務・PR 後凍結・review-converge 反復境界・improvement 見送り・構造変更エスカレーション・サブエージェント生存管理・push/PR 承認済み前提・境界 deny 後の行動、planがあれば review-converge への計画グラウンドトゥルース渡し、scope_checkがあれば PR 前の計画突合と FAIL 時のブロック報告)を stdout へ出す。mode: "maintain"は PR 作成後のレビュー対応レーン向けで、review-converge / pr-create を禁止し push を親承認制に切り替える。入力フィールドの全仕様と mode ごとの条項差分は references/worker-contract.md を参照。オーケストレーション側はこれをタスク本文へ連結する。scripts/report.sh [--file <path>] <parent> <task-id> <milestone> [詳細]— ワーカーが叩く報告コマンド(規約に埋め込まれる)。JSONL(${XDG_STATE_HOME:-$HOME/.local/state}/lane-ops/reports/<parent>.jsonl)へ追記してから、herdr agent promptで親へ[lane-ops:report <task-id>] ...を直送する。--file <path>は本文をファイルから読む(コマンド名を含む報告は引数へ載せると guard hook が反応して報告自体が止まるため、その迂回路)。--fileは先頭に置き、位置引数の詳細とは併用できない(exit 2)。ファイルが空・不在でも追記せず exit 2。本文ファイルは Write ツールで書く(Bash の heredoc で書くとコマンド名が Bash 引数に載り、迂回した意味が無くなる)。scripts/watch_events.py [--pane <id>]... [--status blocked]... [--ready]— herdr socket API($HERDR_SOCKET_PATH)へevents.subscribeを張り、エージェント状態変化を 1 行 1 JSON で流し続ける長寿命フィルタ。これ 1 本で全レーンの blocked/idle/done を push 検知する(レーンごとのagent wait並走は不要)。--pane省略時はpane.listで全 pane を購読し、以降にエージェントが載った pane はpane.agent_detectedイベントを契機に購読を張り直して取り込む(後から起動したレーンも拾う)。張り直し中の約 1 秒だけイベントを取りこぼす窓があるため、レーン起動直後の確認は watch に頼らずherdr agent getで行う。親自身の pane($HERDR_PANE_ID)は既定で除外する(親の承認プロンプトが自己ノイズとして混ざるため。含めるなら--include-self)。--statusはidle/working/blocked/done/unknownのみ受け付ける。--readyは--status idle --status doneと等価で、--statusと重なっても購読は重複しない。--onceはマッチしたイベントを 1 行出力した時点で exit 0 する(Monitor が無いセッションでバックグラウンド Bash の完了通知を push 通知として使う)。scripts/send_instruction.sh [--force] <target> <file>— 親からワーカーへの指示送信。本文を必ずファイルから読む(コマンド文字列に指示リテラルが載らないため guard hook の誤爆が構造的に起きず、送った指示が記録に残る)。送信前にagent_statusを確認し、blocked(ダイアログ表示中)なら中断する。ダイアログ表示中の本文つき送信は本文が入力されず、末尾の Enter がハイライト中の選択肢(先頭の推奨案)を誤確定するため(herdr は blocked でもagent_promptedを返して成功を装う)。承知の上で流し込むときのみ--force。指示ファイルは Write ツールで書く(Bash の heredoc で書くと、本文に含まれるgit reset/git rebase等の文言に git-guard が反応して deny される)。scripts/verify_lane.sh <branch> [worktree]— 自己申告の機械検証。PR 存在(gh pr list --head)・push 同期・未コミット変更・触れたファイルと境界宣言を事実として並べる(判断は親が行う)。scripts/widen_boundary.sh <worktree> <追加glob>...— タスク境界の拡張の正規経路(親専用。task-boundary hook は境界ファイルへの Edit/Write を無条件 deny するため、拡張はこのスクリプトでのみ行う)。
運用ループ
-
監視を張る:
python3 <SKILL>/scripts/watch_events.py --once --status blocked --readyをバックグラウンド Bash で 1 本起動する。--onceは最初のマッチで exit 0 するため、バックグラウンド Bash の完了通知がそのまま push 通知になる。イベントを処理したら watch を再起動し、直後にherdr agent getで現在状態を直接確認する(watch 停止中に起きた変化を取りこぼさないため)。Monitor(persistent)があるセッションでは--once無しの常駐でもよい(常駐 Bash は完了時にしか親を起こさず push 通知にならないので、Monitor 無しで常駐させない)。blocked だけでなく--ready(idle + done)も張る — ワーカーがテキストで承認を求めてターンを終えるとダイアログが出ず blocked にならないうえ、親がまだ画面を見ていない(未 seen の)pane のターン終了は idle ではなく done として届くため、idle だけでは取りこぼす。起床したらherdr agent readで画面を確認し、承認待ちなら blocked と同様に捌く。PR 作成後で CI を監視しているだけのレーンは、ターン終了のたびに起こされても捌くものが無いので--status blockedだけに絞る。 -
報告を受ける:
[lane-ops:report ...]が会話に届いたら、それはワーカーの自己申告であってユーザーの発言ではない。必ずverify_lane.shで裏を取ってから次の行動(次段起動・凍結確認など)を決める。親が AskUserQuestion 等で blocked(対話入力中)の間に届いたreport.shはherdr agent promptがagent_blockedで弾かれ会話に現れない。対話入力から戻ったら${XDG_STATE_HOME:-$HOME/.local/state}/lane-ops/reports/<parent>.jsonlの未読分(最後に処理した行以降)を確認して取りこぼしを拾う。milestone「ダイアログ待ち」の報告(レーン内の permission-gate が確認ダイアログを出したときに自動で送る。job-graph が起動時に export するLANE_OPS_*が宛先)は承認待ちの通知なので、裏取りの代わりにherdr agent read <pane> --source recent-unwrapped --lines 120で画面を確認し、手順 3 の blocked と同様に捌く(詳細の<tool_name>: <command 先頭>は手掛かりで、判断は画面で行う)。 -
blocked を捌く: watch のイベントが来たら
herdr agent read <pane> --source recent-unwrapped --lines 120で内容を確認し、下表で応答を判断する。ダイアログ(選択肢 UI)への応答は 2 通りだけ: 提示選択肢で足りるならherdr agent send-keys <pane> enter等の承認キー、自由記述の裁定が要るならherdr agent send-keys <pane> escでダイアログを閉じてからsend_instruction.shで送る。ダイアログが開いたまま本文を送らない(send_instruction の blocked ガードが中断する理由)。1 回の呼び出しで承認は 1 件だけ行い、余分な Enter を送らない — 次のダイアログを先読みして重ねて送ると、まだ読んでいない選択肢を誤確定する。 -
指示を送る: 軌道修正・情報共有は指示ファイルを書いて
send_instruction.sh。herdr の send-keys で指示文を直接流し込まない(send-keys は承認キー送信専用)。誤って選択肢を確定してしまったら、ワーカーは working 中でも次ターンで指示を受領するので、帰結が後段のコミットへ出る前に即座に訂正指示を送る。 -
スラッシュコマンドを実行させる:
disable-model-invocation: trueのスキル(例:pr-visualize)は、ワーカーへ「実行して」と指示文で頼んでも Skill ツールで拒否される。拒否されたワーカーは SKILL.md を読んでスクリプトを手で順に叩き、手順を再現してしまうことがある(参照ファイルの読み飛ばしなど品質の保証が無く、ガードの迂回にもなる)。ユーザーがそのスキルの実行を明示的に求めたときに限り、親がスラッシュコマンドを代理入力する。送信は 2 段に分ける:- 前置きを
send_instruction.shで送る。「この後に親が/<スキル> <引数>を入力する。受領だけ返してターンを終える」「スキルを経由せずに手順やスクリプトを手で再現しない」「スキル内のユーザー承認(AskUserQuestion 等)は使わず、承認待ちとして報告して親の応答を待つ」を書く - 受領のターン終了を確認してから、
/<スキル> <引数>の 1 行だけを書いたファイルをsend_instruction.shで送る(プロンプト入力欄へ入るのでスラッシュコマンドとして起動する)
承認待ちの報告が来たら、画面で
/<スキル>の入力からスキルが起動したことを確かめてから応答する。手で再現した成果物は使わず、前置きからやり直させる。 - 前置きを
承認代行の判定基準
事前に承認済みの計画があるとき、親は計画の範囲内で各レーンの対話ゲートに自分で応答する(個別にユーザーへ確認しない):
| 状況 | 対応 |
|---|---|
| 計画に書かれた操作の確認(編集・テスト・push・PR 作成) | 親が応答して進める(herdr agent send-keys <pane> enter 等) |
| 計画の範囲内だが選択肢がある確認 | 計画・issue の記述から判断して応答。判断材料が無ければユーザーへ |
| 境界の拡大要求・スコープ逸脱・計画の前提と実態の食い違い | ユーザーへ上げる(勝手に承認も却下もしない) |
| 仕様の解釈変更・検査/バリデーションの緩和・計画に無い型/関数/enum の追加・計画が「据え置く」と明記した箇所の変更 | 常にユーザー裁定。ワーカー・親が妥当と評価しても「範囲内の裁定」として処理しない(範囲内判定を親自身が行うと仕様変更が既成事実化する) |
承認済みの計画が無い単独利用では、外部影響のある操作(push・PR 作成)の承認はユーザーへ確認する。
境界拡大をユーザーが承認したら widen_boundary.sh で反映し、対象ワーカーへ「境界を広げたので再開してよい」と send_instruction.sh で伝える。
補足
-
watch のイベントが無いのに報告も途絶えたレーンは、
herdr agent get <pane>でエージェント在否を確認する。不在ならherdr pane process-info <pane>で shell へ戻ったことを確かめてから復旧する(pane の見た目で判断しない)。復旧コマンドは claude をenv -u越しに起こす:herdr pane run <pane> 'env -u CLAUDE_CODE_CHILD_SESSION -u CLAUDE_CODE_SESSION_ID \ -u CLAUDE_CODE_BRIDGE_SESSION_ID -u CLAUDE_CODE_MESSAGING_SOCKET \ -u CLAUDE_CODE_MESSAGING_TOKEN -u CLAUDE_CODE_ENTRYPOINT claude --continue'素で
claude --continueを流すと復旧したレーンが親(自分)の子プロセスと誤認され、transcript 保存が切られる・親宛のメッセージ経路を掴む。レーンは独立したセッションなので断ち切る。 -
herdr セッション全損からの復旧(サーバー再起動で session が消え、レーンの workspace / pane / ワーカー claude が全滅したとき): 失われるのは pane だけで、worktree・追跡外ファイル(改名マップ等)・境界ファイルはディスクに残る。実績のある手順:
wt listと worktree の中身で被害を棚卸しする- 生きているセッションでレーン workspace を同じ label で再作成する(job-graph の wave 起動コマンドは workspace を label で引くため、label を合わせればコマンドが互換のまま使える)
- root pane の cwd を対象 worktree にして、上記の
env -u ... claude --continueで再開する(--continueは cwd 単位で直近会話を再開するので、worktree cwd なら正しいワーカー会話が戻る) - 親の rename をやり直す。ワーカー規約(worker_contract)には親のエージェント名が焼き付いているため、一字一句同じ名前で rename しないと report.sh の報告が届かない
-
ワーカーの push が数分応答しないときは待ち続けない。原因はほぼ対話型 credential 経路の入力待ち(helper チェーンの git-credential-oauth 等が URL 提示で待つ・askpass 起動・対話 shell の履歴展開で
!ghの helper 指定が壊れる、など。ワーカーの「規約どおり実行した」という自己申告と実際に走ったコマンドは一致しているとは限らない)。対処は親の代行 push が標準: worktree はオブジェクト DB を共有するため、メインリポジトリからgit -c credential.helper= -c 'credential.helper=!gh auth git-credential' push <URL> <branch>:<branch>で代行できる(per-ref アトミックなので競合しても安全)。代行後はワーカーへ「push の再試行を中止し、リモート一致を確認して次工程へ」を指示する。 -
agent wait/ watch が idle/done を報じても完了とは限らない。完了判定は常にverify_lane.shの事実で行う。 -
herdr CLI 自体の詳細(pane/agent/workspace 操作の一般規約)は herdr スキルの領分。
レビュー
まだレビューはありません。使ってみた感想をお寄せください。
同じリポジトリのスキル
概要と使いどころ
spec.md の REQ-# を入力に、機能一覧・モジュール構成・インターフェース・データフローを持つ docs/dev/<対象>/basic-design.md を作成・改訂するスキル。/basic-design <対象名> で明示的に呼び出されたときのみ使用する。
技術的な内容を、技術用語を排したビジネス職向けの平易な説明文に翻訳する。`/biz-translate` と明示的に呼ばれたときのみ実行する。
`git commit` / `git commit --amend` を実行する前、または「commit」「amend」「コミット」「コミットして」の一語・短文だけを渡された時点で必ず発火する git コミット実施ルール。理由や差分の説明が一切無くても、ファイル全文を読んでメッセージを組み立てる前に先に参照する。主目的は論理的に独立した修正を都度・適切な粒度でコミットすること。メッセージは Conventional Commits 形式、素材は同梱の決定論スクリプト commit-context.sh が出す staged diff のみ。「コミット分けて」と依頼される、独立した複数修正をまとめるか分けるか判断する、レビューコメント対応をコミットする、rebase / squash / cherry-pick 後のメッセージを整える、`gh pr create` の PR タイトルをコミット流儀へ揃える場面でも参照する。plan モードでのコミット計画の立案は commit-plan スキルの領分。
実装計画・リファクタリング計画・レビュー対応計画・並列作業のタスク分解など、計画を成果物として書き出すときに必ず参照するコミット計画ルール。plan モードでは ExitPlanMode で plan を提示する前に必須、計画ドキュメントや job-graph のタスク分解・エージェントへの指示文でも同様に適用する。計画成果物にコミット計画セクション(論理的に独立した修正単位での分割と Conventional Commits 形式のメッセージ)が無ければ実装に入らない。「実装計画を立てて」「planを立てて」「実行計画を作って」「リファクタリング計画を立てて」「コミット計画を立てて」「タスクを分解して」と依頼される、複数の独立した修正をまとめるか分けるか計画段階で判断する等の場面では、ユーザーが「コミット」に一切言及していなくても必ず発火する。コミットの実施(素材収集・メッセージ確定・git commit 実行)は commit-flow スキルが担う。
プロジェクトに 1 つの「完成の定義」docs/dev/definition-of-done.md を対話で構築・改訂し、機械判定節と人判定節の二部構成で書き出すスキル。/def-done で明示的に呼び出されたときのみ使用する。