org-conveyor: 承認スコープ内自走ループ(ベルトコンベア)
窓口が人間から 承認スコープの輪郭 を受け取り、それを機械契約として articulate したうえで、
その内側を triage → /org-delegate → worker iteration → Codex round → verify(applicable なら必須)→ push → gh pr create → pr-watch CI 監視 → CI green まで 完了駆動で自走 し、PR ごとに
merge gate で停止する。人間は「レビュー待ち PR のキュー」を順次 merge するだけになる。
本スキルは 薄い orchestrator であって、実作業の機構は既存スキルに委譲する。本スキルが固有に持つのは
(1) 承認スコープ契約の articulate と gate、(2) 完了駆動ループとバックプレッシャー、(3) 観測可能性、
(4) 機械的退出条件 の 4 つだけ。受信モデル・ack・push/PR/CI・escalation の機構は下記スキルを呼ぶ:
他のループ系スキル(/loop / /work-discovery / /org-delegate)との違いは
.claude/skills/org-conveyor/references/rationale.md にまとめてある。
不変条件
- INV-1 merge 承認は人間 gate: スコープ契約は dispatch〜CI 監視を事前承認できるが、merge は事前承認の対象にしない。
CI green に到達したら停止し、PR を人間へ提示して merge を仰ぐ。bare「OK」を merge 承認と解釈しない。
- INV-2 scope 境界に触れたら halt: スコープ契約の述語に合致しない候補・判断・差分が現れたら、自走を止めて
/org-escalation 経由で人間に上げる(場当たり継続をしない)。
- INV-3 worker からの judgment escalation は人間へ: worker の「判断仰ぎ」「承認を仰ぎ」「スコープ拡張」「ブロッカー」は
窓口が一次承認せず
/org-escalation で人間へ。conveyor は escalation を自動判断しない。
- INV-4 propose-only の継承: 候補生成は
/work-discovery(決定的ツール)に委ね、conveyor は
その出力をスコープ契約で gate するだけ。候補の中身を自前調査・実装しない。
- INV-5 起動主体は窓口のみ: 委譲済み worker は本スキルを起動しない(「1 worker = 1 task = 1 scope」原則。
CLAUDE.md「役割の境界」)。
- INV-6
/loop の置換ではない: 時間駆動ではなく完了駆動で、間隔ポーリングをしない。PR キューに上限は設けない(人間の merge が natural gate。Step 2-9)。
輸送層(transport)両系
per-transport 認可(union 不可): 本スキルが直接使う transport ツールは free-pane 会計の list_panes と、pull フォールバック時のループ event ドレインの check_messages だけで、
allowed-tools には その deployment で active な単一 transport の面のみ を列挙する(broker + renga を union で並べると
非アクティブ transport のツールまで認可され per-transport auth モデルを迂回するため。設計 SoT:
notes/broker-skill-generator-design.md #9。union 却下)。本リポジトリの active transport は broker(コード既定
DEFAULT_TRANSPORT=broker、org-broker-channel 稼働中)なので allowlist は broker 面で render してある。renga で運用する
deployment(opt-in 切戻し)では、この surface を renga 面へ per-transport 再生成 する(mcp__org-broker__* →
mcp__renga-peers__*、引数形・セマンティクスは同一。settings.local.json の per-transport 生成と同じ境界。フル per-transport
render が要るなら他の transport 参照スキルと同じく .md.in + manifest 化が follow-up 候補)。送受信機構(ack・relay・escalation・
push / PR)の輸送依存差・二フレーム関係・spawn 儀式・エラー分岐は本スキルが呼ぶ各スキルが per-transport に持つので、総説
CLAUDE.md「輸送層(transport)両系」節とフル版注記 /org-escalation 冒頭の
同名 note を一次参照する(本スキルは重複コピーを置かない)。
cross-tab の free-pane 会計: renga の list_panes は caller のタブにスコープされるので、別タブの worker を数え落として
空き容量を過大申告しうる。空き枠の数え方(別タブ配置と overflow 配線時の扱いを含む)は
.claude/skills/work-discovery/SKILL.md の --free-panes 節を正本とし、conveyor もそれに従う。
- 実害の限定: この過大申告が生むのは誤ランキングと、runtime に拒否される派遣試行まで。実際の overspawn に至るのは
runtime の防止策を迂回する実装をした場合のみである(
delegate-plan は overflow 配線時に --peers-json 欠落を
input_invalid で拒否し、fleet ceiling を census + 未 bind 予約で数える)。
- 本リポジトリでは非該当: active transport は broker(コード既定
DEFAULT_TRANSPORT=broker)でタブ概念を持たないため、
上記は renga 面で背景タブ配置を配線した deployment にだけ効く。conveyor 自身に peer census を叩かせる設計にはしない
(allowed-tools は list_peers を許可しない。容量会計は dispatcher / runtime 側の出力を消費する)。
受信は transport ツールに依存しない: conveyor 固有の輸送依存は 完了 / CI 遷移の受信 に集約されるが、ここは
worker 報告・pr-watch の CI_COMPLETED / PR_MERGED が in-band push で注入される(broker は channel sidecar、renga は
<channel source="renga-peers">。pr-watch の tools/peer_notify.py: notify_peer は raw env 判定で active transport を選ぶ)。
in-band 注入の受信に tool 呼び出しは要らず、push 失効時の最終フォールバックは events テーブルのポーリング(Read / Bash、
transport 非依存)なので、broker の check_messages 単独待受や固定 sleep ポーリングに依存しない。したがって conveyor は
「CI_COMPLETED / PR_MERGED / worker 報告という semantic event が届いたこと」を契機にループを 1 周進める。受信機構の
per-transport 詳細(pr-watch の二フレーム受信注記)は呼び先の /org-pull-request 2b-i に委ねる。
Step 1: 承認スコープ契約を articulate する(起動時・人間ゲート)
ループを回す 前に、人間から受けた承認の輪郭を機械契約として articulate し、人間に確認を取る。
スコープ契約は /work-discovery の per-candidate 選択の代わりに置かれる 唯一の事前人間ゲート であり、
この確認なしにループを開始してはならない。
- テンプレート・フィールド定義・「何を事前承認し / 何を絶対に承認しないか」の境界は
.claude/skills/org-conveyor/references/scope-contract.md を一次参照する。
- 確定した契約は
.state/conveyor/scope-contract.md に書き出す(ループ中の gate 判定で読み戻す SoT)。書き出し前に
mkdir -p .state/conveyor で親ディレクトリを確保する(.state/ は gitignore 配下で fresh checkout には conveyor/
サブディレクトリが無いため。idempotent)。
- 契約が事前承認する範囲: スコープ述語に合致する候補に対する
triage 投入 → /org-delegate 派遣 → worker iteration → verify → push → gh pr create → pr-watch CI 監視。push / PR 作成の「ユーザー明示承認」
前提(/org-pull-request 2b-i)は、この起動時スコープ承認が満たす
(bare な per-PR OK ではなく、人間が明示した持続的スコープ承認の記録)。
- 契約が承認しない範囲: merge(INV-1)。merge は PR ごとの人間ゲートで、CI green で halt して提示する。
- スコープ述語は機械的に判定できる形で書く(例:
label:bug AND size:S、#637 の follow-up に限る、
PR #635 の review feedback round を ≤6 まで)。判定不能な候補は scope 縁として扱い投入しない(INV-2)。
- 並列上限は 起動時の free pane 数(バックプレッシャー節)。退出予算(Codex round 上限 / 連続 false-positive
閾値 / 時間予算 / 最大反復数)も契約に明記する(
.claude/skills/org-conveyor/references/exit-conditions.md)。
Step 2: 完了駆動ループ本体(ベルトコンベア)
スコープ契約確定後、以下を 完了駆動 で回す。各反復は「空き pane を埋める → 完了/CI 遷移を待つ →
進んだ分だけ次を投入する」の 1 周。固定 sleep でポーリングしない(state transition の到着を契機にする)。
- 観測可能性サマリを出力(反復開始時。「観測可能性」節)。
- triage:
/work-discovery を起動する。conveyor 文脈では
tools/work_discovery_scan.py --trigger post_merge --free-panes <空き pane 数> 相当で候補 JSON を得る
(空き枠があると同一条項内の parallelizable 候補のランクが上がりベルトを埋めやすい)。候補生成は決定的ツールに委ねる(INV-4)。
- 候補プールはゴール台帳(
registry/goals/)の条項に当たった候補だけに狭まっている(設計 §12.8)。スコープ述語はこの狭まったプールに対して評価する。
--repo 無しの暗黙 scan では goal 段が repo を解決できないので、gh repo view で slug を求めて --repo を明示する。
- スコープ内の repo が
goal_rank.goal_unset_repos[] / goal_rank.goal_errors[] に出たら「候補が無い」と読まず halt し、ゴール設定か --rank-mode legacy(人間が明示指示したときだけ)での実行かを人間に仰ぐ。
- scan が exit 2(判定段の失敗。
goal_rank.judge.status = failed / cooldown / budget_exhausted、fail-closed)なら候補ゼロと読まず halt し、状態と理由を人間へ伝える。
- scope gate: 各候補をスコープ契約の述語に照合する。
- 合致 + 空き pane あり → 投入対象。合致候補に対する派遣は契約で事前承認済みなので、per-candidate の
人間確認は しない(ここが
/work-discovery の hard-stop との差分)。
- 非合致 / 判定不能 → 投入しない。ベルトがその候補に触れざるを得ない(= スコープを使い切って外側しか残っていない等)
状況なら、自走を止め
/org-escalation で人間に上げて halt する(INV-2)。
- 派遣: 投入対象を空き pane 数まで
/org-delegate の Step 0 から回す。レーン選択
(軽量 / 重量)・brief 生成・ディスパッチャー経由派遣は org-delegate に委ねる。project 文脈はスコープ契約に
pre-resolve 済みとし、org-delegate が 人間入力を要するチェック項目(曖昧用語・OS 前提・incorporation 戦略等)に
当たったらそれは scope 縁 として halt する(自動で人間質問を埋めない)。
- worker iteration: worker が走り、受信モデル(push 一次 / pull フォールバック)で報告する。ack・進捗 Progress Log・
完了 REVIEW 遷移・監視/介入は
/org-delegate Step 5 に委ねる。判断仰ぎ/ブロッカーは
/org-escalation へ(INV-3)。本スキルはこれらの機構を再規定しない。
- verify(条件付き必須): worker 完了時、conveyor は
.claude/skills/org-conveyor/references/verify-evidence.md の
applicability classifier を適用する。app code に触れていれば worker が worktree 内で /verify(Claude Code 組込みスキル)
または同等の app 起動を必須実行し(実作業は worker に委譲=conveyor 自身は app を起動しない)、conveyor はその実行有無を gate し、
worker が返した再現コマンド + 出力 / スクショパスを エビデンスとして PR 本文 ## Test plan へ転記 する。判定不能 = scope 縁として halt(INV-2)。
並列 verify のポート衝突は .claude/skills/org-conveyor/references/dynamic-ports.md の動的ポート割当規律で避ける。
- push / PR / CI 監視:
/org-pull-request 2b-i を発動する(push → gh pr create →
pr-watch)。前提の「ユーザー明示承認」はスコープ契約の事前承認が満たす(Step 1)。CI_COMPLETED の到着で次へ。
- CI green → merge gate で halt: CI green に達したら merge せずに停止する。awaiting_user を emit
(
gate=ci_green_merge_gate、/org-pull-request 2b-i / /org-escalation
と同じ canonical emit)し、人間向け理解サマリ(full タスク)と PR を提示して merge を仰ぐ(INV-1)。
conveyor はこの PR についてここで停止する(ベルト全体は停止しない)。
- バックプレッシャー: 人間が merge し post-merge cleanup(
/org-pull-request 2b-ii)で
pane が解放されたら、解放枠に triage の次候補を即時投入する(2 へ戻る)。PR キューに上限は設けない
(未 merge PR が N 件溜まっても新規 triage を止めない)。人間の merge が自然なバックプレッシャー(natural gate) であり、
人間が merge を止めれば pane が解放されずベルトが自然に詰まって停止する。
- state transition 直後に観測可能性サマリを再出力(「観測可能性」節)。
- 退出条件チェック(
.claude/skills/org-conveyor/references/exit-conditions.md)。いずれか該当で halt。
再入と引き継ぎ: 窓口 context が長くなったら /secretary-handover →
/clear → /secretary-resume で引き継ぐ。スコープ契約 .state/conveyor/scope-contract.md
と TaskList が SoT なので、resume 後は契約を読み戻してベルトを継続できる(ループ状態をメモリに依存させない)。
観測可能性(必須・能動出力)
ベルトコンベアの稼働状況を 人間が一目で読めるタスクリスト要約 として能動出力する。これは任意の運用習慣ではなく
skill 契約であり、ベルト稼働中は省略しない(人間が「いまどこまで進んだか」を催促なしで把握できる状態を保つ)。
起動主体とパス解決
- 起動主体は窓口だけ(INV-5)。worker / dispatcher / curator は起動しない。
- 本スキル中の
tools/... / docs/... / .state/... 表記はリポジトリルート相対。窓口セッションの CWD は
リポジトリルートなのでそのまま実行できる。Windows では python3 を py -3 に読み替える(allowed-tools に両形登録済み)。
- references へのリンク(
references/...)は本 SKILL.md からの document-relative。表記規約は
docs/contributing/markdown-conventions.md に従う。