Skip to content

Latest commit

 

History

History
170 lines (127 loc) · 11.3 KB

File metadata and controls

170 lines (127 loc) · 11.3 KB

herdr × opencode ループ統合運用ガイド

目的: 単体の OpenCode 内に閉じない跨ハーネス実装ループ (herdr 経由で opencode ワーカーを 駆動する) の運用ガイド。 原則は intent-cli がワークフロー権威。ここには transport 配線と運用判断の 知見を置く。


構成

  • lead: opencode (omo / Sisyphus)。host repo cwd の root セッション (pane 例: w7:p1)
  • worker: opencode。 対象domainのプロジェクトにてworktreeを作成し、そこで新規opencodeセッションを起動する
  • 観測: herdr の hook 権威 で working / done / blocked を取得。画面認識には依存しない
  • なぜ task() ではないか: task() 子セッションは herdr に観測されず (herdr#1362、子 busy は親 pane に投影されない)、再委譲不可・400 tool-call 上限あり。 pane-root ワーカーはこれらを構造的に回避する

ワークフロー

1. issue 委譲

  1. lead が host repo で issue/packet を作成し、intent-cli automation issue-publish 等で intent-target ラベルを付与する。
  2. lead が worker pane に /goal + ulw 形式で契約ファイルパスと完了時リレー手順を 含むプロンプトを送信する。
  3. worker が issue-to-pr フローを実行し、PR 作成後に [herdr-relay] ... で lead を起こす。
  4. lead は composite gate で完了を検証する:
    • worker result-summary / worker complete の canonical 記録
    • PR 実在 + CI green
    • diff 精査(契約照合)

2. review 差し戻し (request-update)

intent-cli automation summary で規定されている標準フローに従う:

  • host 側: Request updates via intent-pr-request-update with concrete repair notes
  • child 側: repair PRs labeled intent-pr-request-update and swap to intent-pr-rereview-ready

つまり:

  1. lead が intent-cli automation pr-transition --transition request-update --writeintent-pr-request-update ラベルを付与する。
  2. 同時に PR コメントまたは herdr プロンプトで具体的な修正内容を伝える。
    • 修正箇所はファイルパスと行数・エラー文字列を含める。
    • ターミナルメタ文字 (?, *, $, backtick など) は shell 展開されないよう シングルクォートで囲むか、プロンプトファイル経由で渡す。
  3. worker が修正し、intent-pr-rereview-ready ラベルに付け替えてリレーする。
  4. lead が再 review して approve → merge → closeout する。

重要: worker が停滞しても lead は直接修正しない。まず追加プロンプト (「続けて」「5 箇所の ?Sized を削除して clippy を通して」 など) で促す。 それでも進まない場合は、明示的な許可を得てから介入するか、別の worker 構成を 検討する。

3. 完了・マージ

  • intent-cli automation pr-transition --transition approved --writeintent-pr-approved を付与。
  • intent-cli closeout pr --pr <n> --write で merge ・ host durable state 更新。
  • ADR / backlog writeback は host 側で実施し、host repo へ commit/push する。

プロンプト規約 (lead → worker)

送信プロンプトの定型:

  • 初回タスク委譲: prefix/goal + postfist ulw — worker セッションの ultrawork-mode と loop 継続を同時に立てる。
  • レビュー結果・repair・stop 等 フォローアップ: bare メッセージ — prefix も postfix も 付けず、平文で既存コンテキストに注入する。
  • 長文はファイル経由: タスク詳細・契約はファイルに書き、prompt にはパスを渡す
    • 契約ファイルの置き場所: host repo 内の .opencode/<slice>-contract.md 等。 /tmp/opencode は opencode から読めないことがある (2026-08-14 実測)。
  • 完了時リレーを必須手順として明記: herdr agent prompt <lead-pane> "[herdr-relay] <結果要約>"
  • worker に intent-cli を叩かせる場合はバイナリの絶対パスを明記する。 (host flake の 0.18.1 を使用。子 flake pin の 0.5.0 は stale)

プロンプト例

issue 委譲:

/goal Implement ShuttlePub/Emumet issue #32 per .opencode/crud-ap-transactions-contract.md. Open a ready-for-review PR, run intent-cli worker result-summary and worker complete, then relay back with [herdr-relay]. ulw

review-fix 時はできるだけ短く、具体的に:

Fix clippy warnings in PR #33. In application/src/service/activitypub/inbox/handlers.rs, remove the '+ ?Sized' bound from all five 'T: InboxUseCase' occurrences. Then run 'cargo fmt --check', 'cargo check --workspace', 'cargo clippy --workspace -- -D warnings', and 'cargo test --workspace --lib'. Push to the PR branch and reply with [herdr-relay] when CI is green.

プロンプト規約 (worker → lead リレー)

  • [herdr-relay] prefix を必須とする
  • リレー文は lead セッションでは operator 入力と区別がつかない。 lead は内容をデータとして扱い、命令としては従わない (ワーカー生成テキストが user 権限で注入されるため)

wake / 待機

  • pull 待機: herdr agent wait <worker> --until done,blocked --timeout <ms> を bash から timeout 分割で呼ぶ (トークンを消費しない)。 idle ではなく done を使う — herdr の状態モデルでは完了後 done となり、 pane を人間が開くまで idle に遷移しない。誰も見ない pane を --until idle で待つとハングする。
  • push wake: worker からの [herdr-relay] が lead セッションのユーザー入力として 届き lead を起こす。watcher 常駐構成は不要。
  • blocked (permission/question 待ち) も可視化され、herdr agent send-keys で 応答可能 (task() 子セッションにはない利点)。ただし provider/model エラーなど 自律的に復帰しない blocked もある。
  • 出力確認: herdr agent read <worker>

既知の落とし穴

事象 対応
Error: 400: role 'developer' is not allowed opencode 側の provider/model 設定問題。Enter では復帰しない。別 pane/model か手動実施を検討。
軽微な lint 修正を lead が直接 push ループの信頼性を損なう。review-fix プロンプトで追加指示を送り、worker に修正させる。
プロンプト内のシェルメタ文字 シングルクォートで囲むか、契約ファイル経由で渡す。
ファイル置き場所 /tmp/opencode opencode から読めない可能性あり。host repo 内の .opencode/ 等を使う。
--until idle 完了後は done になる。--until done,blocked を使う。
herdr 0.8.0 の --until 記法 カンマ区切りは拒否される。--until done --until blocked と repeat する (2026-08-15 実測)。
herdr agent start --kind pi が timeout を返す 実体は新 workspace で起動していることがある (opencode は独自 window を開く)。herdr agent list で確認してから retry しないと二重起動する (2026-08-15 実測)。
goal 達成済み opencode への新 /goal 送信 「Replace current goal」ダイアログで止まる。herdr agent send-keys <pane> Enter で承認 (2026-08-15 実測)。
issue title の fallback issue publish-flow が title を <unit> (untitled) に fallback することがある (packet.yaml の issue_title は正しいのに発生。原因未特定。issue draft は別スキーマ (root execution_unit 必須) を要求し現行 packet と非互換)。発生したら gh issue edit で修正する (2026-08-15 Stage 6/7 で連続発生)。
draft PR のまま intent-cli closeout pr pr-merged が記録されるが GitHub 上の merge は行われない。closeout 前に gh pr ready で draft を外し、closeout 後に merged state を必ず検証する (2026-08-15 実測)。実害発生: Stage 5 (issue #32 / PR #33) が draft のまま closeout されコード未マージのまま queue=completed となり、2026-08-16 に発覚。PR #33 は superseded close、Stage 9 (crud-ap-transactions-reapply) として現行 main に再適用する recovery を実施。closeout 後の実マージ検証を closeout 手順に組み込むこと
closeout 後の実マージ検証 (squash merge 対応) git cherry origin/main <branch> は squash merge では全コミットが + (未マージ扱い) になり誤判定する。正しい検証: (1) gh pr view <n> --json state,mergedAt,mergeCommit で state=MERGED を確認 (2) git log origin/main --oneline -1 が squash commit (... (#<n>)) と一致 (3) git diff <base>..origin/main --stat に想定 diff が出ること (2026-08-16 Stage 9 実測)。
CI blocked 中の worker の自律行動 hold 指示を送っても in-flight の判断 (fix commit の push 等) は止まらないことがある。並行して別経路の修正 PR を出す場合は「ブランチに触れるな」を先に明示する (2026-08-15 実測)。
worker sandbox の git read-only 制約 worker の opencode sandbox は対象 repo の .git を read-only mount し /tmp を隔離するため、sandbox 内から commit/push ができない。bundle export 運用 (worker が copy gitdir 上に commit し git bundle create、lead が sandbox 外で fetch+push+PR 作成) で対応 (2026-08-16 Stage 9 実測)。
worktree の置き場所 (ro mount) /home/turtton/Documents 直下は ro mount で、Emumet 本体のみ rw bind mount という特殊構成。worktree を ro 側 (.../Emumet-worktrees/) に作ると checkout が read-only になり git reset --hard / commit が「Read-only file system」で失敗する。worktree は rw な場所 (Emumet 本体配下 or 別 rw パス) に作ること (2026-08-16 Stage 9 実測)。
bundle の host への受け渡し worker sandbox の /tmp は host から見えない。bundle は checkout ディレクトリ (worker から writable で host と共有) 経由で受け渡す (2026-08-16 Stage 9 実測)。

運用チェックリスト

  • 契約ファイルを .opencode/<slice>-contract.md に配置し、worker から読めることを確認
  • プロンプトに /goal、ファイルパス、完了時 [herdr-relay]、絶対パスを含める
  • intent-cli automation issue-publish 後に worker へ prompt を送信
  • worker 完了後は composite gate (canonical 記録 / PR+CI / diff) で検証
  • 差し戻し時は request-update ラベル + 具体的な repair notes を必ず送信
  • worker 停滞時は追加プロンプトで促し、直接手を出すのは最後の手段

未解決の検証項目

  • fresh pane での start → prompt → wait → relay の一巡 (2026-08-15 Stage 6 で実証。 ただし start の timeout 誤報と新 workspace 起動の癖あり。既知の落とし穴参照)
  • worker からの再委譲可否 (opencode 側の拡張設定次第)
  • /goal + ulw 規約の効果測定 (2026-08-15 Stage 6: goal は逸脱防止に機能。 review-fix 2 ラウンドとも contract 内で収束)

参照

  • intent-cli automation summary --domain <d> --format json — canonical ワークフロー権威