yoi/.yoi/tickets/00001KTJXS31R/item.md

9.2 KiB

title state created_at updated_at queued_by queued_at
Orchestrator Idle 時の queued Ticket 見落としを防ぐ inprogress 2026-06-08T06:12:35Z 2026-06-12T16:05:08Z workspace-panel 2026-06-12T14:49:40Z

背景

現在の Panel Queue automation は、主に次の遷移タイミングのイベントを扱っている。

ready -> queued
  -> workspace Orchestrator に通知

これだけでは、安定した orchestration には足りない。通知漏れ、Orchestrator restore/spawn、planning への差し戻し、capacity 制限、複数 Ticket の調整などにより、queued Ticket が残り続けることがある。

ただし、この Ticket は常時 polling する scheduler を作るものではない。目的は、実行可能な queued work があり、Orchestrator Pod の state が Idle で、active_inprogress が導出されていないときにだけ、bounded な work set を渡して starvation を防ぐことである。

ゴール

Orchestrator が queued work を見落とさず、かつ active_inprogress が導出されている間に無駄な re-kick を繰り返さないための session-lifetime work set discovery / re-kick policy を実装する。

Orchestrator Pod の state が Idle で、進められる work が存在する場合は、bounded attention により次の inspection または acceptance/routing に進める。一方で、implementation side effects は必ず queued -> inprogress acceptance の記録後に限定し、blind spawn や duplicate start を起こさない。

runtime 側で kick 可能かを見る判定は、Orchestrator Pod の state が Idle であることに限定する。re-kick を抑制するかどうかは、session-lifetime work set、role/session claims、visible Pod/worktree state から active_inprogress の有無として導出する。

現在の前提

  • authoritative な Ticket lifecycle は frontmatter の state で表す。
  • new_queued / planned_queued / active_inprogress は新しい core Ticket state ではなく、現在の Ticket state、session-lifetime work set、role/session claims、visible Pod/worktree state から導出する分類として扱う。
  • work set は Task と同じく session-lifetime の runtime state として扱い、Ticket ごとの durable artifact log として積まない。
  • work set が失われた場合でも、Ticket state = queued から new_queued として再検出できればよい。失われた session-level ordering / waiting reason は再 inspection で作り直す。
  • Panel / lifecycle hook は Orchestrator に attention / kick を与えてよいが、unattended scheduler loop や常時 polling にはしない。
  • queued は Orchestrator が routing / start-if-unblocked を検討できる状態であり、実装・Pod spawn・worktree 作成などの side effect は queued -> inprogress 記録後に限る。

Work-set classification

実装上は少なくとも次の区別を導出できるようにする。

  • new_queued: Ticket state = queued だが、現在の Orchestrator session work set にまだ取り込まれていない Ticket。
  • planned_queued: Orchestrator が確認し、session work set の order / waiting set に置いたが、まだ inprogress として acceptance していない queued Ticket。
  • active_inprogress: Orchestrator が acceptance 済みで、coder/reviewer/planning-sync/merge/cleanup などの delegated step の完了待ちとして記録・観測できる Ticket。
  • actionable_inprogress: inprogress だが、次の action が delegated step の完了待ちではなく、Orchestrator の routing/判断/記録を必要とする Ticket。

この分類の名前は内部実装名として固定しなくてよいが、意味上の区別は必要である。

要件

Work set discovery / re-kick

  • Orchestrator attention が必要な Ticket を、少なくとも次の情報から導出する。
    • Ticket frontmatter の state
    • Orchestrator session-lifetime work set。
    • role/session claims。
    • visible Pod/worktree state。
  • Panel open、Orchestrator restore/spawn、明示的な user action などの境界で、actionable work がある場合に bounded work list を Orchestrator へ提示できるようにする。
  • 無制限な background polling は避ける。明示イベント、Panel lifecycle kick、明示 user/Orchestrator action を優先する。
  • duplicate start を防ぐ。re-kick は inspection または次の planned item の acceptance を促すものであり、coder Pod を blind spawn しない。

Re-kick / starvation-prevention semantics

  • new_queued work が存在し、Orchestrator Pod の state が Idle の場合、Orchestrator に kick/notify して inspection と session work set への取り込みを促す。
  • active_inprogress が導出されず、Orchestrator Pod の state が Idle で、unblocked かつ capacity/policy 上開始可能な planned_queued work がある場合、Orchestrator に kick/notify して次の Ticket の acceptance/routing に進める。
  • active_inprogress が導出されている場合、queued/planned queued work が存在するだけでは re-kick しない。
  • planned_queued work を開始しない理由が dependency / conflict / dirty workspace / capacity / human gate 等で説明できる場合は、session work set 上の bounded waiting/blocking reason として保持する。
  • re-kick は attention signal と bounded context であり、queued -> inprogress acceptance や inspection を迂回する authority ではない。

Session work set semantics

Orchestrator は、意味のある routing 境界で session work set を更新する。

  • new queued work を確認し、session work set に取り込んだとき。
  • queued -> inprogress acceptance を記録したとき。
  • inprogress Ticket の次の action が delegated step 待ちか、Orchestrator action かを判断したとき。
  • capacity stop により planned queued / waiting と reason を残すとき。
  • merge-ready / done に到達し、active_inprogress が導出されなくなったため次の planned queued Ticket を検討するとき。

session work set は bounded で、Orchestrator の現在 session における判断補助として扱う。

  • 何を取り込んだか。
  • 次に acceptance / routing すべき候補は何か。
  • 何を waiting としたか。
  • waiting の理由は何か。
  • active_inprogress として re-kick を抑制する対象は何か。

これらは project-level の永続ログではなく、Task と同様に session lifetime の状態でよい。ユーザー判断や Ticket lifecycle に残すべき内容が生じた場合だけ、Ticket comment / state transition / resolution など既存の durable surface に記録する。

非目標

  • Panel 自体を scheduler にすること。
  • queued になっていない Ticket を自動開始すること。
  • active_inprogress が導出されている間に継続的な re-kick を行うこと。
  • Orchestrator の inspection と queued -> inprogress acceptance なしに coder/reviewer Pod を spawn すること。
  • full dependency graph solver を最初の実装で作ること。
  • new_queued / planned_queued / active_inprogress を core Ticket state として追加すること。
  • volatile な orchestration work set を Ticket ごとの durable artifact log として保存すること。

受け入れ条件

  • Orchestrator Pod の state が Idle のとき、new_queued work を検出して bounded work-list attention または session work set への取り込みに進める。
  • active_inprogress が導出されず、Orchestrator Pod の state が Idle で、planned_queued work が unblocked かつ capacity/policy 上開始可能なとき、Orchestrator が次の acceptance/routing を行える。
  • active_inprogress が導出されている間は、queued/planned work の存在だけで re-kick しない。
  • 開始しない planned_queued work には、session work set 上でユーザーに提示できる bounded waiting/blocking reason が残る。
  • 既存の human gate、queued -> inprogress acceptance step、dirty-workspace/dependency/conflict/capacity checks を迂回しない。
  • Ticket state、session work set、role/session claims、visible Pod/worktree state を確認し、duplicate Orchestrator/coder/reviewer/worktree start を起こさない。
  • missed/stale queued Tickets を、ユーザーが手で再 queue しなくても Orchestrator に提示できる。
  • Orchestrator session work set を失っても、queued Ticket を再検出して安全に再 inspection できる。

検証

  • nix build .#yoi を通す。
  • Ticket / panel / orchestrator routing 周辺の既存テストまたは追加テストで、少なくとも次の主要分岐を確認する。
    • Orchestrator Pod Idle state での queued detection。
    • active_inprogress 導出時の re-kick suppression。
    • session work set 上の waiting reason 保持。
    • duplicate-start prevention。
    • session work set が空でも queued Ticket から再検出できること。
  • 実装報告では、work-set classification に使った情報と、implementation side effects が queued -> inprogress 後に限定されていることを明示する。