エージェント・ハーネス設計 v5 — 子ワークツリーのエージェントセッション(実装 = OpenCode Muse・レビュー = codex astra)へ Orca orchestration で割り振る¶
ユーザー指示(2026-09-09): 「開発の仕組みとして Orca のオーケストレーションスキルを使って、実装・テストは codex gpt-6-astra max、レビューは codex gpt-6-astra max で、子ワークツリーで codex のセッションを立てて、そこに割り振るようにしてほしい。exec で実行するやり方を変えたい。」
ユーザー指示(2026-09-09 10:05・追記): 「今、実装・テストは gpt-6-astra がやっているが、キリの良いタイミングで、OpenCode の Muse Spark 1.3 Contributor の xhigh に変更して。」→ 走行中の codex 2 本は完走させ、次の投入から実装・テストは OpenCode(Muse Spark 1.3 Contributor・xhigh)。レビューは codex gpt-6-astra max のまま。投入の形(Orca orchestration の supervised loop)は変えない。
v4(2026-09-04・OpenCode 形 C + codex exec の一発実行)を置き換える。本書は運用の正典で、Routing の要約は AGENTS.md の Routing 節にある。
役割¶
| 役割 | 担当 | 場所 |
|---|---|---|
| 設計・仕様書・検証ゲート・リリース・bd・Notion | Claude(Fable 5.1・コーディネーター) | wastelink-coordinator |
| 実装・テスト | OpenCode agent implementer = Muse Spark 1.3(meta/muse-spark-1.3・reasoning max。2026-09-11 に Contributor xhigh から切替) |
exec-astra / exec-muse(並行 2 本まで・1 ワークツリーに同時 1 dispatch) |
| レビュー | codex gpt-6-astra(reasoning max) |
review-sol(同時 1 dispatch) |
実装(Muse)とレビュー(codex astra)は 2026-09-09 10:05 以降は別モデルに戻った。同一モデル期間(2026-09-06〜09-09 午前)の独立性低下はユーザー承知だった。
投入の形(supervised loop)¶
台帳(Run / Task / Dispatch)・完了検知(worker_done)・ターミナル寿命を Orca orchestration が持つ。コーディネーターは .worker-specs/*.md の仕様書を書き、Orca に「このワークツリーにエージェントのセッション(実装 = OpenCode・レビュー = codex)を立ててこの仕様書をやらせる」と頼むだけにする。
# 1. Run はコーディネーターのターミナルに 1 つ bind する(初回のみ・以後は run-current で確認)
orca orchestration run-create --objective "waste-link 開発 <期間>: 実装/テスト = OpenCode Muse Spark 1.3 max(exec-astra / exec-muse ほか)・レビュー = codex gpt-6-astra max(review-sol)" --json
# 2. 仕様書を対象ワークツリーの .worker-specs/ に置く(絶対パスで参照する)
# 他ワークツリーの成果物(verdict 等)は投入前にコピーする
# 3. Task を作り、エージェントのセッションを立てて注入する。Orca の launcher(worker-start --agent)は Claude / Codex / Cursor だけで
# OpenCode を起こせず、codex には --effort max を許さないため、どちらも端末を custom argv で立ててから worker-start --terminal で注入する
orca orchestration task-create --spec "Implement the task in /Users/<me>/orca/workspaces/waste-link/exec-astra/.worker-specs/<name>.md. Work only in this worktree. Write the report to .worker-specs/<name>-report.md, then send worker_done once." --json
# 3a. 実装・テスト = OpenCode(agent implementer = Muse Spark 1.3・max はグローバル設定が権威・--auto は deny 以外の権限確認を自動許可)
orca terminal create --worktree path:/Users/<me>/orca/workspaces/waste-link/exec-astra --title muse-<name> --command 'opencode --agent implementer --model meta/muse-spark-1.3 --auto' --json # --model を明示(agent frontmatter の固定より優先・下記「OpenCode の起動と reasoning」)
orca terminal wait --terminal <handle> --for tui-idle --timeout-ms 90000 --json # さらに画面に "Muse Spark 1.3 Meta · max" が出るまで待つ
# 3b. レビュー = codex(gpt-6-astra・reasoning max・fast OFF)
orca terminal create --worktree path:/Users/<me>/orca/workspaces/waste-link/review-sol --title astra-review-<name> \
--command 'env CODEX_HOME=$HOME/.codex codex --dangerously-bypass-approvals-and-sandbox --model gpt-6-astra -c model_reasoning_effort="max" -c service_tier="default"' --json
orca terminal wait --terminal <handle> --for tui-idle --timeout-ms 90000 --json # さらに画面に "gpt-6-astra max" が出るまで待つ
# 3c. 注入(共通)
orca orchestration worker-start --task <task_id> --terminal <handle> --worktree path:<worktree> --timeout-ms 120000 --json
# 注入後 10 秒で作業表示が出ず composer に貼られたまま idle なら Enter を 1 回送る: orca terminal send --terminal <handle> --text "" --enter --json
# 4. 完了を待つ(sleep/poll しない・15〜60 分の作業は rolling wait)
orca orchestration check --wait --types worker_done,escalation,question --timeout-ms 900000 --json # stdout だけを parse する
# 5. 受け取ったら次の所有者を決めてから ack する
orca orchestration worker-release --dispatch <dispatch_id> --json # custom argv 経路の端末は retained になるので続けて terminal close する
orca terminal close --terminal <handle> --json
orca orchestration check --ack <delivery_id> --json
worker-start --terminal <handle>は 既存の TUI(OpenCode / codex)に Task の spec と lifecycle preamble を注入し、その端末を Dispatch の監督下に置く(--agent codex --effort xhighの launcher 経路は Orca が端末を作る点だけが違う)。ワーカーは.worker-specs/<name>-report.mdを書いた後、1 回だけorca orchestration send --type worker_done … --outcome succeeded|failedを送る。check --waitの timeout とcount: 0は checkpoint であってワーカーの失敗ではない。worker-show --dispatch/worker-read --dispatchで生存を見る。- worker_done を受けたら必ず
worker-release(または同じターミナルへの次 dispatch)を済ませてから ack / 次の wait へ進む。worker-readは release 後も読める(transcript を archive する)。 - レビューは同じ形で
review-solに投入する(仕様書 =review-sol/.worker-specs/review-<name>.md・verdict =review-*-verdict.mdの最終行VERDICT: APPROVE|BLOCK)。review-only のworker_doneがコーディネーターに届いても、コーディネーターがコードを直すのではなく R2 の仕様書で実装ワーカーへ差し戻す。 - マージは APPROVE と CI 全 pass の両方が揃ってから(変更なし)。
OpenCode(実装・テスト)の起動と reasoning¶
- agent は リポジトリの
.opencode/agent/implementer.md(model: meta/muse-spark-1.3・permission deny)。reasoning max の権威はグローバル~/.config/opencode/opencode.jsonのprovider.meta.models.muse-spark-1.3.options.reasoningEffort(Meta のインストールスクリプト再実行でhighに上書きされるので都度確認。Contributor 版は models.dev の reasoning_options が xhigh までで max を受けない)。 - 起動は
opencode --agent implementer --model meta/muse-spark-1.3 --auto(muse-launch.sh・MUSE_MODELで上書き可)。モデルは CLI の--modelが権威: agent frontmatter のmodel:固定はワークツリーのブランチに入っているファイル内容で効くため、リポジトリ側を変えても各ワーカーブランチへ merge されるまで旧モデルのまま動く(2026-09-11 に E3-R4 が Contributor で走った実測)。CLI の--modelは frontmatter の固定より優先する(opencode run --agent implementer -m meta/muse-spark-1.1の応答がmuse-spark-1.1になることを SQLite で確認)。グローバル設定のagent.implementer.model上書きはopencode runがセッション作成前に停止したため採らない。 実際の応答モデルは TUI の status 行ではなく OpenCode の SQLite(~/.local/share/opencode/opencode.db・message.data.modelID)で確認する(status 行はグローバル既定modelを表示する)。--autoは「ask」の権限確認を自動許可する(deny リスト =.opencode/opencode.json/implementer.mdの bd close/delete/dolt push/edit・force push・reset --hard・main 切替はそのまま効く)。 TUI の status 行がImplementer auto · Muse Spark 1.3 Meta · maxになってから注入する(2026-09-10 まではMuse Spark 1.3 Contributor Meta · xhigh)。 - bash ツールは TUI プロセスの子なので
orca orchestration sendの送信元 identity はその端末で成立する(v4 の形 C で起きた「serve 側の identity で却下」は起きない)。 - 注入後に composer へ貼られたままになることがある(スモークでは Enter が必要・本番投入では不要。model 表示待ちの長さ次第)。10 秒で作業表示が無ければ Enter を 1 回送る。
worker-releaseはretained(external_terminal)になるのでorca terminal closeを自分で行う(codex と同じ)。- 実測(2026-09-09 10:40 スモーク・OpenCode 1.18.27): 報告書 1 枚 +
worker_doneまで 22.2 秒・$0.01、model 自己申告muse-spark-1.3-contributor、identity 却下なし。直後の本番投入(wl-ondy R2)は Enter 追送なしで進行。 - 共通プロンプト
.opencode/agent/implementer.mdは v5 に合わせて更新(R5): bd は notes を含め一切操作しない/完了通知は注入された preamble の ID・capability でworker_doneを 1 回(v4 の「指示書内ORCA_TASK_IDがあるときだけ」「プロセス終了が完了信号」の条件は削除)/レビュア表記を codex gpt-6-astra に更新。指示書(.worker-specs/*.md)が正典で、共通プロンプトは共通規律。
reasoning effort の扱い(codex = レビュー)¶
- codex(レビュー)の既定は reasoning
max(ユーザー指示 2026-09-09「GPT のセッションをあげるときは gpt-6-astra で reasoning は max」)。 - fast モードは OFF(ユーザー指示 2026-09-09「codex のセッションで fast はオフ」)。codex の
/fastは~/.codex/config.tomlのservice_tierを"fast"に書き、"default"が OFF。起動時に-c service_tier="default"を明示して、共有 config の状態に依存しない。 worker-start --effortは Orca が model ごとに検証する。gpt-6-astraはxhighまでで、maxはinvalid_argument(実測 2026-09-09・Orca 1.4.197:Agent codex model gpt-6-astra does not support effort max。版依存なので更新時に再確認)。したがって launcher 経路(--agent codex --effort xhigh)は使わず、次の custom argv 経路でmaxを与える(supervision は維持される):
orca terminal create --worktree path:<worktree> --title astra-worker \
--command 'env CODEX_HOME=$HOME/.codex codex --dangerously-bypass-approvals-and-sandbox --model gpt-6-astra -c model_reasoning_effort="max" -c service_tier="default"' --json
orca terminal wait --terminal <handle> --for tui-idle --timeout-ms 90000 --json
# 画面に "model: gpt-6-astra max" が出るまで待ってから注入する(model: loading 中の注入は Enter が落ちる)
orca orchestration worker-start --task <task_id> --terminal <handle> --worktree path:<worktree> --json
# 注入後 10 秒で画面が "[Pasted Content …]" のまま idle なら Enter を 1 回送る
orca terminal send --terminal <handle> --text "" --enter --json
制約(実測 2026-09-09): (1) --dangerously-bypass-approvals-and-sandbox を付けないと codex が orca status / orca orchestration send の実行ごとに承認プロンプトで止まる。(2) 注入が model: loading 中に届くと本文が composer に貼られたまま送信されない。(3) コーディネーターが作ったターミナルは worker-release で retained(external_terminal)になるので、orca terminal close --terminal <handle> を自分で行う。(4) worker-read は hook 由来の transcript を持たず terminal 出力の fallback になる。この 4 点はコーディネーター側の起動スクリプト(terminal create → tui-idle → model 表示待ち → worker-start --terminal → 未送信なら Enter / release → close)で機械的に手当てする。実測(2026-09-09・wl-ntv): model 表示待ちを入れると注入は 1 回で送信され、Enter の追送は不要だった。
実測(2026-09-09 スモーク・Orca 1.4.197・codex-cli 0.153.2・OpenCode 1.18.27)¶
以下の挙動(effort の上限・承認プロンプト・Enter の脱落・retained・認証経路)は上記の版と起動設定での実測で、Orca / codex / OpenCode の版が変われば再確認する。
| 経路 | 結果 |
|---|---|
custom argv(opencode --agent implementer --auto)→ worker-start --terminal(exec-muse・10:40) |
起動 → model 表示待ち → 注入(Enter 1 回)→ 報告書 → worker_done まで 22.2 秒。identity 却下なし。release は retained → terminal close |
worker-start --agent codex --model gpt-6-astra --effort xhigh(exec-astra) |
起動 → 注入 → worker_done まで 36 秒。worker-release で agent terminal を自動 close。transcript archive 済み |
custom argv(model_reasoning_effort="max"・承認 bypass 無し) |
注入は貼られたまま停止(Enter 追加で進行)→ 承認プロンプト 2 回(手動 p)→ worker_done。release は retained |
codex の認証は ~/.codex/auth.json が使われる(Orca の launcher 経由でも 401 は出なかった)。codex exec 時代の CODEX_HOME 上書きは custom argv 経路でだけ必要。
廃止したもの¶
codex exec --dangerously-bypass-approvals-and-sandbox -m gpt-6-astra …の一発実行 +teeログ + 完了マーカー +astra-monitor.sh(pgrep監視)。- OpenCode 形 C(
opencode serve常駐 +opencode run --attach)。OpenCode 自体は 2026-09-09 10:05 から TUI +worker-start --terminalの形で実装担当に復帰した(.opencode/の設定はそのまま使う・bd wl-lvpi は保留)。 - 指示書末尾に
ORCA_TASK_ID/ORCA_DISPATCH_IDを手で追記する運用(preamble が注入する)。
変えないもの¶
- ワーカーの bd 規約(
.beads/PRIME.md「ワーカー別の bd 規約」): claim / close / dep / create はコーディネーターだけ。仕様書に明記する。 - 検証ゲート(
pnpm verify・docker proof 全流し・S1・ミューテーション)とレビューの 3 工程(不変条件 / fail-closed / 歯)。 - prod-critical の main マージは人間ゲート。
- 秘密値を仕様書・報告書・チャットに書かない。
判断の記録¶
- 2026-09-09 ユーザー: 「Orca のオーケストレーションスキルで、子ワークツリーの codex セッションに割り振る。exec 方式は変える」→ 本書。
- 2026-09-09 コーディネーター: 既定 effort は
xhigh(Orca の launcher がmaxを拒否・custom argv 経路は 4 つの手当が要る)。maxが必要なら custom argv 経路を明示して使う。 - 2026-09-09 ユーザー(R3): 「GPT のセッションをあげるときは gpt-6-astra で reasoning は max」「codex のセッションで fast はオフ」→ 上の判断を改め、custom argv 経路(max・
-c service_tier="default")を既定に変更。launcher 経路は Orca がmaxを受け付けるようになったら再評価する。 - 2026-09-09 10:05 ユーザー: 「実装・テストはキリの良いタイミングで OpenCode の Muse Spark 1.3 Contributor の xhigh に変更」→ 走行中の codex astra 2 本(wl-bey / wl-ntv)は完走させ、次の投入(wl-ondy R2・10:45)から OpenCode。レビューは codex astra max のまま。スモーク(10:40・22 秒)で
worker_doneまで確認してから切り替えた。 - 2026-09-09 13:30 コーディネーター(R5・#749 レビュー所見 B1〜B3): 共通プロンプト
implementer.mdに残っていた v4 規約(bd notes・ORCA_TASK_ID条件・プロセス終了)を v5 に揃え、初版の判断記録は原文を復元して R3 を別行の追記に戻した。 - 2026-09-09 15:40 コーディネーター(R6・#749 R2 レビュー所見):
implementer.mdの質問経路を Orca のask/ask --resumeに揃え、回答の未着だけでfailed完了しない規約にした。OpenCode ネイティブの question ツール(deny)と Orca のaskを区別。 - 2026-09-11 00:50 ユーザー: 「Opencode で実行するタスクは Muse Spark 1.3 Contributor xhigh から Muse Spark 1.3 max に変更してください。ハーネスも更新して。」→ agent
implementerのmodelをmeta/muse-spark-1.3、グローバル設定にmuse-spark-1.3のreasoningEffort: maxを追加(models.dev: Contributor は xhigh まで・1.3 本体は max まで。単価は Contributor の 12〜20 倍 = 入力 1.25 / 出力 4.25 USD per M tokens 対 0.10 / 0.20)。走行中の 4 本(E2-R2 / F1-R2 / E1-R4 / F3 merge)は Contributor xhigh で完走させ、次の投入から 1.3 max。launcher(muse-launch.sh)の待ち文言をMuse Spark 1.3 Meta+maxへ。レビュー(codex gpt-6-astra max)は変更なし。 同日 13:00 の実測: agent frontmatter だけを変えた最初の投入(E3-R4)は status 行がMuse Spark 1.3 Meta · maxでも SQLite のmodelIDはmuse-spark-1.3-contributor(ワーカーブランチの frontmatter が旧固定のまま)。launcher に--model meta/muse-spark-1.3を明示して以降の投入(F3-R4 再投入)から切替。E3-R4 は Contributor のまま完走させる。API 直叩き(/v1/responses・effort max)は 2.8 秒・reasoning 231 tokens でOK(xhigh と同等)。 - ⚖ 意思決定ログ(Notion)2026-09-09「開発ハーネス v5」に記録済み。