From 095441dbd19dfd57ec5ff912e4bc5a067d3a98cb Mon Sep 17 00:00:00 2001 From: Hare Date: Wed, 10 Jun 2026 16:58:12 +0900 Subject: [PATCH] ticket: record new objectives and tickets --- .yoi/objectives/00001KTR7MZWH/item.md | 73 ++++++++ .yoi/objectives/00001KTR80WMN/item.md | 63 +++++++ .yoi/tickets/00001KST8H4M0/item.md | 4 +- .yoi/tickets/00001KST8H4M0/resolution.md | 14 ++ .yoi/tickets/00001KST8H4M0/thread.md | 156 ++++++++++++++++++ .yoi/tickets/00001KTR6D3C5/artifacts/.gitkeep | 0 .yoi/tickets/00001KTR6D3C5/item.md | 56 +++++++ .yoi/tickets/00001KTR6D3C5/thread.md | 41 +++++ .yoi/tickets/00001KTR6YVDB/artifacts/.gitkeep | 0 .yoi/tickets/00001KTR6YVDB/item.md | 56 +++++++ .yoi/tickets/00001KTR6YVDB/thread.md | 32 ++++ .yoi/tickets/00001KTR81P9X/artifacts/.gitkeep | 0 .yoi/tickets/00001KTR81P9X/item.md | 76 +++++++++ .yoi/tickets/00001KTR81P9X/thread.md | 7 + .yoi/tickets/00001KTR82RB7/artifacts/.gitkeep | 0 .yoi/tickets/00001KTR82RB7/item.md | 100 +++++++++++ .yoi/tickets/00001KTR82RB7/thread.md | 7 + .yoi/tickets/00001KTR83D6E/artifacts/.gitkeep | 0 .yoi/tickets/00001KTR83D6E/item.md | 64 +++++++ .yoi/tickets/00001KTR83D6E/thread.md | 7 + 20 files changed, 754 insertions(+), 2 deletions(-) create mode 100644 .yoi/objectives/00001KTR7MZWH/item.md create mode 100644 .yoi/objectives/00001KTR80WMN/item.md create mode 100644 .yoi/tickets/00001KST8H4M0/resolution.md create mode 100644 .yoi/tickets/00001KTR6D3C5/artifacts/.gitkeep create mode 100644 .yoi/tickets/00001KTR6D3C5/item.md create mode 100644 .yoi/tickets/00001KTR6D3C5/thread.md create mode 100644 .yoi/tickets/00001KTR6YVDB/artifacts/.gitkeep create mode 100644 .yoi/tickets/00001KTR6YVDB/item.md create mode 100644 .yoi/tickets/00001KTR6YVDB/thread.md create mode 100644 .yoi/tickets/00001KTR81P9X/artifacts/.gitkeep create mode 100644 .yoi/tickets/00001KTR81P9X/item.md create mode 100644 .yoi/tickets/00001KTR81P9X/thread.md create mode 100644 .yoi/tickets/00001KTR82RB7/artifacts/.gitkeep create mode 100644 .yoi/tickets/00001KTR82RB7/item.md create mode 100644 .yoi/tickets/00001KTR82RB7/thread.md create mode 100644 .yoi/tickets/00001KTR83D6E/artifacts/.gitkeep create mode 100644 .yoi/tickets/00001KTR83D6E/item.md create mode 100644 .yoi/tickets/00001KTR83D6E/thread.md diff --git a/.yoi/objectives/00001KTR7MZWH/item.md b/.yoi/objectives/00001KTR7MZWH/item.md new file mode 100644 index 00000000..5231446b --- /dev/null +++ b/.yoi/objectives/00001KTR7MZWH/item.md @@ -0,0 +1,73 @@ +--- +title: "ネイティブGUIアプリケーション" +state: "active" +created_at: "2026-06-10T07:41:18Z" +updated_at: "2026-06-10T07:41:18Z" +linked_tickets: [] +--- + +## Goal + +Yoi の Pod / Ticket / Orchestrator / workflow 操作を、TUI だけでなくネイティブ GUI から扱えるようにする。 + +最初の到達点は、既存の runtime / Ticket backend / Pod protocol / Profile / workflow authority を再実装せずに、workspace の状態を視覚的に把握し、選択した Pod・Ticket・role action に対して安全に操作できる desktop GUI client を持つこと。GUI は core authority ではなく client surface とし、既存 CLI/TUI と同じ durable state・同じ protocol・同じ permission/prompt/workflow 境界を使う。 + +## Motivation / background + +現在の TUI / Panel は dogfooding 可能な状態まで進んでいるが、複数 Pod・複数 Ticket・Orchestrator 状態・session output・role launch・review/merge dossier を同時に扱うには、terminal UI の表示密度・視覚的状態表現・スクロール/選択/比較操作に限界が出ている。 + +ネイティブ GUI があると、以下をより自然に扱える。 + +- live / stored Pod、Ticket lane、Orchestrator progress、Companion/Intake 状態の同時表示。 +- Ticket body/thread/artifacts、Pod output、validation evidence、diff/report の並列閲覧。 +- composer target、role action、queue/routing/attach/restore の明確な affordance。 +- long-running orchestration の通知、状態変化、失敗診断の視覚化。 +- 将来的な review / merge-ready dossier / plan board / settings editor の専用 UI。 + +一方で、GUI を理由に runtime authority を分散させたり、Ticket/Pod state を独自 DB として二重管理したり、prompt/workflow 文字列を GUI code に直書きしたりしてはいけない。 + +## Strategy / design direction + +- GUI は Yoi core の上に乗る client として作る。 + - Pod lifecycle、session/history、Ticket storage、Profile resolution、workflow/prompt authority は既存 core を正とする。 + - GUI 固有 state は selection、layout、local UI preference などに限定する。 +- 最初に toolkit / architecture の小さな spike を置く。 + - 評価軸は Rust code reuse、async/runtime 統合、native packaging、Linux dogfooding しやすさ、testability、accessibility、long-running log/output 表示、将来の cross-platform 余地。 + - toolkit 選定は Objective では固定しない。候補比較と採用理由を Ticket に残す。 +- 実装は段階的に進める。 + 1. read-only workspace dashboard: Pod / Ticket / Orchestrator 状態を既存 backend から表示する。 + 2. attach / restore / open など、既存 protocol に乗る低リスク操作を追加する。 + 3. composer と role action: Companion / Intake / Orchestrator / coder / reviewer launch を既存 launcher 経由で扱う。 + 4. Ticket body/thread/artifacts、Pod output、validation evidence、review report を閲覧しやすくする。 + 5. 必要に応じて settings/profile/config editor や merge-ready dossier UI を追加する。 +- TUI は廃止前提にしない。 + - GUI 導入後も CLI/TUI は fallback / automation / terminal-first workflow として維持する。 + - GUI で見つかった state model の改善は、TUI と共有できる pure data model / client API に寄せる。 +- Prompt / workflow / role guidance は GUI code に直書きしない。 + - LLM-facing prompt は `resources/prompts` または `.yoi/workflow` / configured resources を正とする。 + - GUI は prompt 文言を所有せず、選択・起動・runtime context の入力面を担当する。 +- Security / privacy / authority boundary を保つ。 + - secret-like data は UI diagnostics / logs / model context に漏らさない。 + - permission / scope / profile の authority は既存 resolver/policy に従う。 + - GUI convenience action は durable Ticket/Pod state transition と対応付け、暗黙の side effect を避ける。 + +## Success criteria / exit conditions + +- 明示コマンドまたは binary で native GUI を起動できる。 +- GUI は既存 workspace config、Profile、Ticket backend、Pod registry/protocol を使い、独自の authority store を持たない。 +- 最小 dashboard で live/stored Pod、Ticket lane/state、Orchestrator/role session の概況を確認できる。 +- GUI から少なくとも attach/restore/open 相当の安全な Pod 操作ができる。 +- GUI から Ticket Intake または既存 role launcher を使った role action を実行でき、既存の prompt/workflow/resource 境界を壊さない。 +- Pod output / Ticket body/thread/artifacts を、TUI より見通しよく閲覧できる最小 UI がある。 +- GUI 固有 state と core durable state の境界が文書化されている。 +- toolkit / architecture 選定理由、採用しなかった選択肢、packaging 方針が Ticket artifact または design note として残っている。 +- GUI で使う state transformation / action eligibility は pure model として test 可能で、主要な selection/action state の unit test がある。 +- GUI 実装は CLI/TUI の既存 workflow を破壊せず、必要な targeted validation が定義されている。 + +## Decision context + +- この Objective は中長期の方向性・判断軸を保持する。具体的な toolkit 選定、crate 構成、初期 dashboard 実装、role action 実装、packaging は個別 Ticket に分ける。 +- GUI は TUI の単純な置換ではなく、複数 Pod / Ticket / Orchestrator を扱う workspace cockpit として設計する。 +- authority は既存 core に残す。GUI は client/view/controller surface であり、Pod/Ticket/workflow/prompt の正本を所有しない。 +- Prompt 直書き禁止方針を守る。GUI 実装中に LLM-facing 文言が必要になった場合は、`resources/prompts` または workflow/resource 側に置く。 +- 初期 target は dogfooding しやすい desktop GUI とし、public release / cross-platform polish / installer は後続段階で扱う。 diff --git a/.yoi/objectives/00001KTR80WMN/item.md b/.yoi/objectives/00001KTR80WMN/item.md new file mode 100644 index 00000000..f227f594 --- /dev/null +++ b/.yoi/objectives/00001KTR80WMN/item.md @@ -0,0 +1,63 @@ +--- +title: "MCP integration as external capability provider" +state: "active" +created_at: "2026-06-10T07:47:48Z" +updated_at: "2026-06-10T07:47:48Z" +linked_tickets: ["00001KST8H4M0", "00001KTR81P9X", "00001KTR82RB7"] +--- + +## Goal + +Yoi が MCP (Model Context Protocol) server を external capability provider として安全に扱えるようにする。 + +到達点は、MCP server が提供する tools / resources / prompts を、Yoi の既存の Pod / Feature / ToolRegistry / permission / scope / history / bounded result 境界に乗せて利用できる状態にすること。MCP は Yoi の plugin model そのものではなく、protocol-bound bridge / external provider runtime として扱う。 + +## Motivation / background + +MCP は AI application と外部 system を接続する標準 protocol になりつつあり、server は tools、resources、prompts などを提供する。Yoi にとって MCP support は有用だが、外部 server が返す schema、description、annotation、resource content、prompt template はすべて untrusted data であり、Yoi の instruction hierarchy、scope、permission、history persistence、prompt-context 加工原則を弱めてはいけない。 + +現行の `pod::feature` API は static descriptor / static tool contribution を中心にしており、MCP のように startup 時の initialize / capability negotiation / discovery によって surface が決まる provider には不足がある。そのため、MCP 実装だけを先に ad-hoc に入れるのではなく、まず外部 protocol-backed provider を扱える Feature API boundary を整え、その上に MCP implementation を載せる。 + +## Strategy / design direction + +- Broad MCP integration Ticket は progress-container として使わず、この Objective に中期方針を移す。 +- 実装 work item は concrete Ticket に分ける。 + - `00001KTR81P9X`: `pod::feature` / Worker / ToolRegistry API を external protocol-backed provider に耐える形へ拡張する。 + - `00001KTR82RB7`: MCP `2025-11-25` local stdio server-feature bridge を実装する。 +- MCP 実装は local stdio transport から始める。 + - Streamable HTTP、remote auth/OAuth、MCP Registry distribution、workspace-provided package auto-start は後続判断とする。 +- tools / resources / prompts は無理に分けず、MCP server features として扱う。 + - ただし resources/prompts は direct context injection ではなく、明示 tool operation の結果として history に残す。 + - `resources/read` / `prompts/get` の結果を history に残らない形で context に注入しない。 +- MCP server は untrusted external capability provider として扱う。 + - server-provided schema/description/annotation/content/error は instruction ではなく data。 + - ToolRegistry / PreToolCall permission / history / bounded result path を迂回しない。 +- local process execution は explicit authority として扱う。 + - filesystem/network authority から暗黙に subprocess 起動権限を派生させない。 + - secrets は explicit secret/env references で扱い、diagnostics / logs / model context / project records に plaintext として残さない。 +- dynamic discovery / list_changed は prompt/tool schema consistency を壊さない範囲で扱う。 + - live refresh が危険なら next-turn refresh または restart/reinitialize-required diagnostic を選ぶ。 + - silent stale state は避ける。 +- Sampling / elicitation は external server が Yoi 側の LLM/user interaction を要求する強い authority なので、初期段階では fail-closed とし、必要なら別 Ticket で approval/resume/UI path を設計する。 + +## Success criteria / exit conditions + +- `pod::feature` が external protocol-backed capability provider を表現できる。 +- local subprocess execution authority が明示的に型・config・grant として扱われる。 +- Feature-provided long-running service / connection manager を Pod lifetime に安全に接続できる。 +- discovery 後の dynamic tool contribution が通常 ToolRegistry と permission path に統合される。 +- MCP spec baseline `2025-11-25` に基づく local stdio server integration がある。 +- MCP tools が namespaced stable Yoi tool として使える。 +- MCP resources/prompts が明示 tool operation として使え、取得結果は通常 tool result として history に残る。 +- server-provided data が system/developer instruction、scope、permission、prompt-context、history persistence rules を弱めない。 +- secrets / env values / command args containing secrets が diagnostics、logs、model context に plaintext で出ない。 +- Streamable HTTP、remote auth、distribution、sampling、elicitation の扱いが out-of-scope / fail-closed / follow-up として明示されている。 +- local mock MCP server による focused tests と、関連 crate tests、`nix build .#yoi` による packaging validation が定義されている。 + +## Decision context + +- `00001KST8H4M0` は broad MCP integration Ticket として作られていたが、今後はこの Objective の背景 context として扱い、実装 authority は concrete Tickets に置く。 +- `00001KTR81P9X` は API/architecture prerequisite。MCP 実装が ToolRegistry / permission / history path を迂回しないための土台を作る。 +- `00001KTR82RB7` は MCP implementation Ticket。API 拡張の結果に乗って local stdio MCP server features を実装する。 +- Objective-to-Ticket links は context であり、dependency/scheduling authority ではない。実際の routing / readiness / blockers は各 Ticket の body/thread/artifacts と Orchestrator 判断に置く。 +- `resources/prompts` は scope 外に固定しない。安全条件は「direct hidden context injection をしない」ことであり、明示 tool result として扱うなら MCP integration の対象に含める。 diff --git a/.yoi/tickets/00001KST8H4M0/item.md b/.yoi/tickets/00001KST8H4M0/item.md index 6696b1e8..d1e39590 100644 --- a/.yoi/tickets/00001KST8H4M0/item.md +++ b/.yoi/tickets/00001KST8H4M0/item.md @@ -1,8 +1,8 @@ --- title: "MCP integration as external tool/resource/prompt provider" -state: "planning" +state: 'closed' created_at: "2026-05-29T16:19:28Z" -updated_at: "2026-05-29T16:19:28Z" +updated_at: '2026-06-10T07:50:19Z' --- ## Background diff --git a/.yoi/tickets/00001KST8H4M0/resolution.md b/.yoi/tickets/00001KST8H4M0/resolution.md new file mode 100644 index 00000000..38c35f25 --- /dev/null +++ b/.yoi/tickets/00001KST8H4M0/resolution.md @@ -0,0 +1,14 @@ +この broad MCP integration Ticket は concrete work item としては退役し、Objective `00001KTR80WMN` に格上げした。 + +今後の実装 authority は以下の concrete Tickets に置く。 + +- `00001KTR81P9X`: `pod::feature` / Worker / ToolRegistry API を external protocol-backed capability providers に耐える形へ拡張する。 +- `00001KTR82RB7`: MCP `2025-11-25` local stdio server-feature bridge を実装する。 + +重要な判断: + +- API 拡張と MCP 実装は分離する。 +- `resources/prompts` は固定で scope 外にせず、direct hidden context injection を禁止したうえで明示 tool operation の result として扱う方向にする。 +- Streamable HTTP、remote auth/OAuth、MCP Registry distribution、sampling、elicitation は後続判断または fail-closed とする。 + +この Ticket 自体は progress-container として残さない。Objective-to-Ticket links は context であり、dependency/scheduling authority ではない。 \ No newline at end of file diff --git a/.yoi/tickets/00001KST8H4M0/thread.md b/.yoi/tickets/00001KST8H4M0/thread.md index d3a4150a..2bd48ac8 100644 --- a/.yoi/tickets/00001KST8H4M0/thread.md +++ b/.yoi/tickets/00001KST8H4M0/thread.md @@ -5,3 +5,159 @@ Created by tickets.sh create. --- + + + +## Decision + +# Intake refinement: concrete MVP scope for MCP integration + +既存の Ticket は `mcp-integration` の広い構想として作られていたが、現在の work item 運用では umbrella/progress-container として残さず、単独で実装・レビュー・検証できる concrete slice として扱う。 + +この Ticket の実装対象を **Yoi に local stdio MCP server を設定し、MCP tools を通常の ToolRegistry / PreToolCall permission / bounded tool-result path に橋渡しする MVP** に絞る。既存 body 内の古い `Insomnia` 表記は現在の `Yoi` を指すものとして読む。 + +## Binding decisions / invariants + +- MCP server は untrusted external capability provider として扱う。 +- MCP tool は Yoi の通常の `ToolRegistry` に feature/plugin contribution として登録され、既存の tool permission、scope、history/tool-result recording、bounded output の経路を迂回しない。 +- MCP の tool descriptions / schemas / annotations / result content は外部由来の data であり、system/developer instruction、scope、permission、prompt-context、history-persistence rules を弱めない。 +- local stdio transport を最初の対象にする。server command / args / cwd / env / secret refs は明示設定に限る。 +- secrets は explicit secret/env references で扱い、diagnostics / session logs / model context / Ticket records に plaintext として出さない。 +- model-visible な resource/prompt content を history に残らない形で context に注入しない。`resources/read` / `prompts/get` はこの Ticket では実装を defer してよいが、将来も explicit operation + permission/policy gate + durable/model-visible path が必要。 +- client-side sampling / elicitation はこの Ticket では disabled / fail-closed とする。実装するなら別途 approval/resume / UI path の設計が必要。 +- Streamable HTTP transport、remote auth/TLS/redirect/private-network policy、MCP server packaging/distribution はこの Ticket の非対象。 +- Plugin/Feature surface の現在の決定に従い、MCP は plugin model そのものではなく protocol-bound bridge/runtime kind として扱う。 + +## Requirements for this slice + +- Profile/config から named local stdio MCP server を有効化できる。 +- Pod startup または feature installation 時に configured server を initialize し、MCP lifecycle (`initialize` / capability negotiation / `notifications/initialized`) を処理する。 +- `tools/list` により discovered tools を stable namespaced tool names として登録する。 +- registered MCP tool call は `tools/call` に変換され、成功/失敗とも bounded structured output として通常の tool-result path に記録される。 +- startup failure、protocol failure、server disconnect、tool discovery/call failure は server 名と phase が分かる diagnostic として出す。secret values は出さない。 +- `notifications/tools/list_changed` は安全に扱う。live refresh が既存 ToolRegistry/request lifecycle と衝突する場合は、restart/reinitialize-required diagnostic でもよいが、silent stale state にしない。 +- Filesystem roots を MCP に公開する場合は Yoi の authorized scope 由来のみにする。初期実装で roots を公開しない選択も可。 +- local mock/test server を使った focused tests を追加する。 +- docs に local stdio MCP server の最小例と trust/permission/secret guidance を追加する。 + +## Acceptance criteria + +- 少なくとも1つの local stdio MCP server を Profile/config で有効化できる。 +- configured server の initialize 成功/失敗が観測可能で、失敗時に server 名と phase が分かる。 +- `tools/list` の結果が Yoi の通常 tool として namespaced stable name で model-visible schema に現れる。 +- registered MCP tool を呼ぶと `tools/call` が実行され、bounded structured output が通常の tool result として返る。 +- 既存の PreToolCall permission / tool permission policy が MCP tool にも適用され、denial が通常の tool denial として扱われる。 +- MCP server 由来 metadata/content は untrusted data として扱われ、prompt-context / history-persistence rules を迂回しない。 +- secret refs / env values が diagnostics、logs、model context に plaintext で出ないことを focused test または review で確認できる。 +- sampling / elicitation / Streamable HTTP / resources-prompts direct context injection は disabled, fail-closed, or explicitly out-of-scope として実装・docs に反映されている。 +- Validation: focused MCP protocol/tool bridge tests、関連 crate tests、`cargo fmt --check`、`cargo check --workspace --all-targets`、`nix build .#yoi`。 + +## Implementation latitude + +- crate placement、internal module names、exact Profile/config syntax、FeatureRegistry integration details、ToolRegistry registration timingは、上の invariants を満たす範囲で実装側に委ねる。 +- `resources/read` / `prompts/get` support、Streamable HTTP、packaged MCP server distribution、sampling/elicitation approval flow は follow-up Ticket に分けてよい。 +- 初期 TUI 表示は詳細 UI でなく bounded diagnostics/actionbar/log surface でもよい。 + +## Escalation conditions + +- MCP tool registration のために通常の ToolRegistry / permission / history path を迂回する必要が出た場合。 +- Profile/config enablement と plugin/feature contribution boundary のどちらが authority を持つか判断が必要になった場合。 +- server-provided resource/prompt content を model context に入れる UX/API を決める必要が出た場合。 +- secrets、network/remote transport、sampling/elicitation、workspace-provided executable/package auto-start に踏み込む必要が出た場合。 +- live `tools/list_changed` refresh が current run の tool schema consistency を壊す場合。 + +## Related tickets / context + +- `00001KSXRQ4G8` Plugin extension surface: MCP は protocol-bound backend/bridge であり plugin model 全体ではない。 +- `00001KT6Q08R9` Plugin feature contribution registry: built-in/future external capability は既存 Tool / Hook / Notify paths に contribution する。 +- `00001KT0Z4BK8` Plugin distribution package format: package presence is discovery only; workspace-provided executable/MCP process startup requires explicit enablement and capability approval. + +--- + + + +## Intake summary + +既存の broad MCP integration Ticket を、local stdio MCP server の設定・初期化・`tools/list`/`tools/call` bridge・通常 ToolRegistry/permission/bounded-result 経路への統合に絞った concrete MVP として refinement した。resources/prompts、Streamable HTTP、sampling/elicitation、distribution は非対象または follow-up とし、untrusted metadata、secret handling、prompt-context/history persistence、scope/permission boundary を binding invariants として明記した。blocking open questions はなく、Orchestrator が implementation routing できる。 + +--- + + + +## State changed + +Intake refinement が完了し、Ticket は implementation routing 可能な ready 状態です。 + +--- + + + +## Comment + +# Intake correction: prior refinement is not user-approved + +直前の Intake では、ユーザーとの明示的な要件同期・draft 承認を挟まずに scope refinement と `ready` 化まで進めており、Intake workflow の「作成/更新前に draft を提示し、ユーザー合意を取る」手順に対して過剰だった。 + +直前に記録した MCP MVP scope は **提案 draft** として扱い、合意済み binding decision ではない。特に以下はユーザー確認が必要: + +- この Ticket を local stdio MCP tools bridge MVP に絞ってよいか。 +- resources/prompts、Streamable HTTP、sampling/elicitation、distribution を follow-up / out-of-scope にしてよいか。 +- permission/scope/secret/prompt-context boundary の書き方が過不足ないか。 +- 既存 body の広い MCP 要件をこの Ticket 上で置き換えるのか、別 Ticket に split するのか。 + +--- + + + +## State changed + +ユーザーとの明示的な draft 確認なしに ready 化していたため、要件同期に戻す。直前の refinement は未承認の提案として扱い、scope / non-goals / split 方針を確認してから再度 ready 判定する。 + +--- + + + +## Decision + +# Decomposition decision: promote broad MCP work to Objective + +ユーザー判断により、広い MCP integration work は concrete implementation Ticket としては扱わず、Objective `00001KTR80WMN` に格上げして中期 context として保持する。 + +Concrete work item は以下に分離した。 + +- `00001KTR81P9X`: `pod::feature` / Worker / ToolRegistry API を external protocol-backed capability providers に耐える形へ拡張する。 +- `00001KTR82RB7`: MCP `2025-11-25` local stdio server-feature bridge を実装する。 + +`resources/prompts` は固定で scope 外にしない。安全条件は direct hidden context injection をしないことであり、明示 tool operation の result として history に残す形なら MCP implementation の対象に含める。 + +--- + + + +## State changed + +Ticket を closed にしました。 + + +--- + + + +## 完了 + +この broad MCP integration Ticket は concrete work item としては退役し、Objective `00001KTR80WMN` に格上げした。 + +今後の実装 authority は以下の concrete Tickets に置く。 + +- `00001KTR81P9X`: `pod::feature` / Worker / ToolRegistry API を external protocol-backed capability providers に耐える形へ拡張する。 +- `00001KTR82RB7`: MCP `2025-11-25` local stdio server-feature bridge を実装する。 + +重要な判断: + +- API 拡張と MCP 実装は分離する。 +- `resources/prompts` は固定で scope 外にせず、direct hidden context injection を禁止したうえで明示 tool operation の result として扱う方向にする。 +- Streamable HTTP、remote auth/OAuth、MCP Registry distribution、sampling、elicitation は後続判断または fail-closed とする。 + +この Ticket 自体は progress-container として残さない。Objective-to-Ticket links は context であり、dependency/scheduling authority ではない。 + +--- diff --git a/.yoi/tickets/00001KTR6D3C5/artifacts/.gitkeep b/.yoi/tickets/00001KTR6D3C5/artifacts/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/.yoi/tickets/00001KTR6D3C5/item.md b/.yoi/tickets/00001KTR6D3C5/item.md new file mode 100644 index 00000000..d68c4810 --- /dev/null +++ b/.yoi/tickets/00001KTR6D3C5/item.md @@ -0,0 +1,56 @@ +--- +title: 'Lua Profileに組み込みyoi APIとimport/extendを追加する' +state: 'ready' +created_at: '2026-06-10T07:19:31Z' +updated_at: '2026-06-10T07:41:26Z' +assignee: null +--- + +## 背景 + +Lua Profile では現在、標準 API を使うたびに `require("yoi.profile")` / `require("yoi.scope")` / `require("yoi.compact")` などを明示している。標準 API は sandbox 内で host が与える組み込み surface なので、Profile 実行時に最初から `yoi` object を global として注入し、すべて `yoi.*` 経由でアクセスできる形に整理したい。 + +また、builtin Profile は registry selector としては `builtin:default` を選べるが、Lua Profile 内から import して上書き・再 export する標準経路がない。project-local の `.yoi/profiles/_base.lua` に function を置いて各 Profile から `require("_base")` する運用はできるが、builtin base Profile を再利用する API ではない。 + +## 要件 + +- Lua Profile 実行環境に global `yoi` object を注入する。 +- 標準 API は `yoi.profile` / `yoi.scope` / `yoi.compact` / `yoi.models` のように、単一の `yoi` object 配下から利用できる。 +- `yoi.profile` は `yoi.profile { ... }` と呼べる callable な表現にしつつ、Profile 操作用 helper を持てる形にする。 +- builtin / registry Profile を Lua Profile 内から reusable Profile artifact として import できる API を追加する。 + - 例: `yoi.profile.import("builtin:default")` + - import 対象は resolved Manifest ではなく、workspace/runtime 解決前の raw Profile artifact とする。 +- import した Profile artifact に対して override を適用し、Profile として再 export できる API を追加する。 + - 例: `return yoi.profile.extend("builtin:default", { slug = "coder", worker = { language = "Japanese" } })` + - 例: `local base = yoi.profile.import("builtin:default"); return yoi.profile.extend(base, { ... })` +- merge semantics を明示して実装する。 + - object/table は再帰的に merge する。 + - scalar は override する。 + - array/list は replace する。 + - `nil` による削除 semantics はこのチケットでは導入しない。 +- import/extend 後の最終 artifact に対して、既存の Profile validation を維持する。 + - `pod`、complete Manifest 形状、concrete `scope.allow` / `scope.deny`、resolved absolute path などは禁止のまま。 +- bundled `resources/profiles/default.lua` は `require("yoi.*")` ではなく global `yoi` style に更新する。 +- project-local module composition のための local `require("...")` は維持する。 +- `require("yoi")` / `require("yoi.*")` の扱いを整理する。 + - 互換 alias として当面残すか、明示的に非推奨化するかを実装時に判断し、テストで固定する。 + +## 受け入れ条件 + +- `resources/profiles/default.lua` が `local profile = require("yoi.profile")` などを使わず、global `yoi` だけで評価できる。 +- filesystem Profile でも embedded builtin Profile でも、global `yoi` API が利用できる。 +- Lua Profile で `yoi.profile.import("builtin:default")` または同等の API により builtin default の raw Profile artifact を取得できる。 +- Lua Profile で `yoi.profile.extend("builtin:default", overrides)` または同等の API により builtin default を上書きした Profile を返せる。 +- override は nested table を意図通り deep merge し、scalar と list は置換される。 +- import/extend で runtime-bound field や concrete authority を混入させた場合、既存 Profile 境界に沿って reject される。 +- project-local `require("_base")` などは引き続き動作する。 +- 新 API と既存 default Profile の評価に対する manifest crate のテストが追加・更新されている。 +- `cargo test -p manifest profile` または該当する targeted test が通る。 +- `target/debug/yoi ticket doctor` が通る。 + +## 非目標 + +- resolved Manifest を Lua Profile へ import 可能にすること。 +- runtime-bound な `pod.name` や concrete `scope.allow` / `scope.deny` を Profile に許可すること。 +- local filesystem require を builtin embedded profile の module search path と混ぜること。 +- `nil` / tombstone による field deletion API の導入。 diff --git a/.yoi/tickets/00001KTR6D3C5/thread.md b/.yoi/tickets/00001KTR6D3C5/thread.md new file mode 100644 index 00000000..84cc2f27 --- /dev/null +++ b/.yoi/tickets/00001KTR6D3C5/thread.md @@ -0,0 +1,41 @@ + + +## 作成 + +LocalTicketBackend によって作成されました。 + +--- + + + +## Plan + +## Intake refinement + +Readiness: `implementation_ready`。 + +重複確認: `.yoi/tickets` 内で `profile.import` / `import/extend` / global `yoi` に関する未完了の重複 Ticket は見つからなかった。 + +Open questions: blocking な未決定点はない。`require("yoi")` / `require("yoi.*")` を互換 alias として残すか非推奨にするかは、Ticket 本文どおり実装時に整理し、テストで固定する implementation latitude として扱う。 + +Risk flags / reviewer focus: `profile-api`, `authority-boundary`, `sandbox-module-loading`, `backward-compat`, `packaging-resource`。 + +Orchestrator routing: queued 後は implementation に進めてよい。実装では Lua Profile sandbox の global 注入、builtin/raw Profile artifact import、extend merge semantics、validation boundary、bundled `resources/profiles/default.lua` 更新、manifest crate テストを一体で確認すること。 + +--- + + + +## Intake summary + +既存 Ticket 00001KTR6D3C5 を確認し、Lua Profile の global `yoi` API 注入、`yoi.profile.import/extend`、deep merge semantics、Profile validation boundary、default.lua 移行、local require 維持、manifest crate tests まで受け入れ条件が揃っていると判断した。blocking open question はない。`require("yoi")` / `require("yoi.*")` の扱いは実装時に固定する implementation latitude。主な risk flags は profile-api / authority-boundary / sandbox-module-loading / backward-compat / packaging-resource。 + +--- + + + +## State changed + +Intake により implementation_ready と判断したため、state を ready にする。実装開始は panel による ready -> queued と Orchestrator routing に委ねる。 + +--- diff --git a/.yoi/tickets/00001KTR6YVDB/artifacts/.gitkeep b/.yoi/tickets/00001KTR6YVDB/artifacts/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/.yoi/tickets/00001KTR6YVDB/item.md b/.yoi/tickets/00001KTR6YVDB/item.md new file mode 100644 index 00000000..4e416ecb --- /dev/null +++ b/.yoi/tickets/00001KTR6YVDB/item.md @@ -0,0 +1,56 @@ +--- +title: 'LLM向けプロンプト直書きを廃止してresources/promptsへ集約する' +state: 'queued' +created_at: '2026-06-10T07:29:13Z' +updated_at: '2026-06-10T07:49:23Z' +assignee: null +queued_by: 'workspace-panel' +queued_at: '2026-06-10T07:49:23Z' +--- + +## 背景 + +この repository の設計要旨では、プロンプトはすべて `resources/prompts` に集約することになっている。管理効率・override 可能性・レビュー容易性のため、Rust code や workflow 起動処理に LLM-facing prompt 文言を直書きしてはいけない。 + +現在、少なくとも Ticket role launch / Intake handoff 周辺では、LLM に渡る generated launch prompt が `crates/client/src/ticket_role.rs` に直書きされている。例として `build_launch_prompt`、`TicketIntakeHandoff::append_prompt_lines`、role-specific execution guidance などが該当する。これらは UI label / notice ではなく model context に入る prompt なので、`resources/prompts` 管理へ移す必要がある。 + +この Ticket は Intake 文言だけでなく、LLM に渡る hardcoded prompt prose 全体を audit し、`resources/prompts` 経由に移すためのものとする。 + +## 要件 + +- LLM-facing prompt 文言を Rust code に直書きしない。 +- Ticket role launch prompt の固定文言を `resources/prompts` 配下へ移す。 + - `# Ticket role launch` から始まる launch context guidance。 + - Ticket id / language / user instruction / handoff / intent packet / worktree / validation / report expectation の説明文。 + - Intake handoff guidance。 + - Orchestrator / coder / reviewer 向け role execution guidance。 +- Intake workflow の本体文言は引き続き `.yoi/workflow/ticket-intake-workflow.md` を正とし、launch prompt 側には必要最小限の runtime context と参照関係だけを載せる。 +- `resources/prompts` に追加する prompt resource は、用途・入力変数・出力境界が分かる単位に分割する。 +- Rust 側は prompt resource を読み込み、必要な runtime 値を安全に埋め込むだけにする。 +- prompt resource の読み込みは既存の prompt/resource 管理方針に合わせる。 + - bundled resource として扱うべきものは compile-time embedded resource に含める。 + - user override 可能性を壊さない。 +- repository 内の hardcoded LLM-facing prompt prose を audit し、少なくとも既知の Ticket role launch 系はこの Ticket で解消する。 +- 残す文言がある場合は、UI 表示文言・diagnostic・protocol literal など、LLM prompt ではない理由を明確にする。 +- 将来の再発を防ぐため、可能なら grep しやすい境界・テスト・lint 的な確認を追加する。 + +## 受け入れ条件 + +- `crates/client/src/ticket_role.rs` から LLM-facing prompt prose の大きな直書きがなくなっている。 +- Ticket role launch で LLM に渡る固定 guidance は `resources/prompts` の prompt resource から組み立てられる。 +- Intake handoff の LLM-facing guidance が Rust 直書きではなく prompt resource 管理になっている。 +- Orchestrator / coder / reviewer role execution guidance が Rust 直書きではなく prompt resource 管理になっている。 +- runtime 値の埋め込みは prompt injection を広げない形で bounded / escaped / sectioned に維持される。 +- 既存の Ticket role launch behavior は semantic に維持される。 +- `resources/prompts` 側の resource 名・責務が明確で、後続の文言修正を code edit なしで行える。 +- targeted tests が追加・更新され、launch prompt が resource 経由で生成されることを確認している。 +- repository audit の結果が Ticket thread または implementation report に記録され、残存する hardcoded LLM-facing prose がない、または非対象理由が明示されている。 +- `cargo test -p client ticket_role` または該当する targeted test が通る。 +- `target/debug/yoi ticket doctor` が通る。 + +## 非目標 + +- TUI の表示ラベル、status line、notice、error diagnostic など、LLM に渡らない UI 文言を `resources/prompts` に移すこと。 +- workflow markdown 本体を `resources/prompts` に移すこと。project-authored workflow は `.yoi/workflow` が正である。 +- protocol literal、tool name、field name、file path、command name を翻訳・抽象化すること。 +- prompt resource system 全体の大規模再設計。 diff --git a/.yoi/tickets/00001KTR6YVDB/thread.md b/.yoi/tickets/00001KTR6YVDB/thread.md new file mode 100644 index 00000000..9f11e30e --- /dev/null +++ b/.yoi/tickets/00001KTR6YVDB/thread.md @@ -0,0 +1,32 @@ + + +## 作成 + +LocalTicketBackend によって作成されました。 + +--- + + + +## Intake summary + +既存 Ticket を確認し、`crates/client/src/ticket_role.rs` の `build_launch_prompt` / `TicketIntakeHandoff::append_prompt_lines` / Orchestrator・Coder・Reviewer execution guidance に LLM-facing prompt prose の直書きがあること、および `resources/prompts` 側に既存 prompt catalog があることを確認した。要件・受け入れ条件・非目標は実装判断に十分で、未決定の blocking question はない。readiness: implementation_ready。risk_flags: [prompt-context, runtime-resource, role-launch, override-semantics, workflow-boundary]。実装時は Ticket role launch の semantic を維持し、runtime 値の bounded/sectioned 埋め込みと user override 可能性を壊さず、残す hardcoded 文言が LLM prompt ではない理由を thread/implementation report に記録すること。関連参考: closed `00001KTCDHFPG`(Ticket role config), closed `00001KSTRAW70`(prompt catalog を使った tool description), planning `00001KSKBPAXR`(内部 Worker/Pod prompt の将来 Workflow 化)。 + +--- + + + +## State changed + +Intake により要件同期済み。blocking open question はなく、Orchestrator が routing 可能な concrete work item として ready にする。 + +--- + + + +## State changed + +Ticket を `workspace-panel` が queued にしました。 + + +--- diff --git a/.yoi/tickets/00001KTR81P9X/artifacts/.gitkeep b/.yoi/tickets/00001KTR81P9X/artifacts/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/.yoi/tickets/00001KTR81P9X/item.md b/.yoi/tickets/00001KTR81P9X/item.md new file mode 100644 index 00000000..57e7570f --- /dev/null +++ b/.yoi/tickets/00001KTR81P9X/item.md @@ -0,0 +1,76 @@ +--- +title: 'Extend pod::feature API for external protocol-backed capability providers' +state: 'planning' +created_at: '2026-06-10T07:48:14Z' +updated_at: '2026-06-10T07:48:14Z' +assignee: null +readiness: 'requirements_sync_needed' +risk_flags: ['authority-boundary', 'feature-api', 'tool-registry', 'permission-scope', 'process-exec', 'prompt-context'] +--- + +## Background + +MCP integration を concrete work item として実装する前に、Yoi の `pod::feature` / Worker / ToolRegistry 境界が外部 protocol-backed capability provider を自然に扱える必要がある。 + +現行の `pod::feature` API は static descriptor / static tool contribution / host authority grant を中心にしており、MCP のように startup 時の protocol negotiation と discovery によって tools/resources/prompts surface が決まる provider には不足がある。MCP 実装側でこれを ad-hoc に迂回すると、permission、history、bounded result、service lifecycle、feature/plugin boundary が歪む。 + +Objective context: `00001KTR80WMN`。 + +## Requirements + +- `pod::feature` が external protocol-backed capability provider を表現できるようにする。 +- local subprocess を起動する authority を明示的に表現する。 + - 既存の filesystem/network/service authority に押し込まない。 + - command / args / cwd / env / secret refs は explicit config/grant に基づく。 +- Pod lifetime に紐づく feature-provided service / connection manager の lifecycle を表現できるようにする。 +- startup / initialize / discovery 後に tool contribution を登録または更新できる host-mediated API を設計する。 +- dynamic contribution は通常の ToolRegistry / PreToolCall permission / history / bounded tool-result path を迂回しない。 +- tool metadata に、MCP など外部 provider が持つ追加 metadata を安全に保持・変換できる余地を作る。 + - title + - output schema + - annotations + - icons or display metadata + - execution/task-support metadata +- rich / structured tool result を bounded serialization できる共通 path を用意する。 +- capability metadata / schemas / descriptions / results は untrusted data として扱う。 +- live list-changed / registry refresh が current run の tool schema consistency を壊さない方針を決める。 +- API 拡張は MCP 固有名に寄せすぎず、将来の external plugin / bridge provider にも使える feature boundary として設計する。 + +## Acceptance criteria + +- external protocol-backed provider を built-in feature として表現できる API がある。 +- subprocess execution authority が `HostAuthority` または同等の明示 grant として型で表現されている。 +- feature-owned long-running service lifecycle を Pod lifetime に接続できる。 +- discovery 後の dynamic tool contribution が通常 ToolRegistry と permission path に統合される。 +- external metadata / schema / result content が untrusted data として扱われる設計になっている。 +- `list_changed` 相当の dynamic registry change について、safe refresh / next-turn refresh / restart-required diagnostic のいずれかが明示され、silent stale にならない。 +- MCP 実装 Ticket が private/ad-hoc API ではなく、この拡張 API に乗って実装できる見通しがある。 +- focused tests で authority grant、dynamic registration、permission denial、bounded result、service diagnostics を確認できる。 +- Validation: relevant crate tests、`cargo fmt --check`、`cargo check --workspace --all-targets`、`nix build .#yoi`。 + +## Binding decisions / invariants + +- ToolRegistry / permission / history / bounded result の既存経路を迂回する API は作らない。 +- external provider 由来の schema / description / annotation / content は instruction ではなく untrusted data として扱う。 +- process execution は explicit authority として分離し、filesystem/network authority から暗黙に派生させない。 +- dynamic registry update は prompt/tool schema consistency と cache behavior を壊さないよう、turn boundary または restart/reinitialize diagnostic を持つ。 +- MCP specific shortcut ではなく、`pod::feature` の長期的な extension surface として成立させる。 + +## Implementation latitude + +- exact type names、crate placement、service handle の形、dynamic registration timing は実装側に委ねる。 +- 初期実装では rich content を provider-native multimodal block として渡さず、bounded structured text/JSON serialization に寄せてもよい。 +- live registry refresh が大きい場合は、まず restart/reinitialize-required diagnostic でもよい。ただし silent stale は避ける。 + +## Escalation conditions + +- current Worker / ToolRegistry architecture では dynamic contribution を安全に扱えない場合。 +- process execution authority と profile/config authority の責務境界が曖昧になる場合。 +- rich content を model-provider native content block に渡す必要が出た場合。 +- hook / feature / plugin contribution boundary の既存設計と矛盾する場合。 + +## Related work + +- Objective: `00001KTR80WMN` +- Decomposed from broad Ticket: `00001KST8H4M0` +- Follow-up implementation Ticket: MCP local stdio implementation Ticket created by this intake split. diff --git a/.yoi/tickets/00001KTR81P9X/thread.md b/.yoi/tickets/00001KTR81P9X/thread.md new file mode 100644 index 00000000..ca24dea6 --- /dev/null +++ b/.yoi/tickets/00001KTR81P9X/thread.md @@ -0,0 +1,7 @@ + + +## 作成 + +LocalTicketBackend によって作成されました。 + +--- diff --git a/.yoi/tickets/00001KTR82RB7/artifacts/.gitkeep b/.yoi/tickets/00001KTR82RB7/artifacts/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/.yoi/tickets/00001KTR82RB7/item.md b/.yoi/tickets/00001KTR82RB7/item.md new file mode 100644 index 00000000..f7b73d32 --- /dev/null +++ b/.yoi/tickets/00001KTR82RB7/item.md @@ -0,0 +1,100 @@ +--- +title: 'Implement MCP 2025-11-25 local stdio server-feature bridge' +state: 'planning' +created_at: '2026-06-10T07:48:49Z' +updated_at: '2026-06-10T07:48:49Z' +assignee: null +readiness: 'blocked' +risk_flags: ['mcp', 'authority-boundary', 'prompt-context', 'permission-scope', 'secrets', 'process-exec', 'feature-api'] +--- + +## Background + +Yoi に MCP integration を追加する。対象は現時点の latest MCP specification `2025-11-25` を基準にした local stdio MCP server integration。 + +この Ticket は MCP 実装を担当し、`pod::feature` / Worker / ToolRegistry の拡張そのものは別 Ticket `00001KTR81P9X` に分離する。MCP 実装は、その拡張 API に乗り、Yoi の通常 ToolRegistry / permission / history / bounded result path を迂回しない。 + +Objective context: `00001KTR80WMN`。 + +## Requirements + +- MCP specification `2025-11-25` を基準にする。 +- local stdio transport の MCP server を explicit Profile/config から有効化できる。 +- stdio subprocess lifecycle を実装する。 + - stdin/stdout newline-delimited JSON-RPC。 + - stdout は MCP messages として扱う。 + - stderr は bounded diagnostics/logging として扱い、即 protocol failure にはしない。 + - shutdown は graceful close / terminate / kill を安全に扱う。 +- MCP lifecycle を実装する。 + - `initialize` + - capability negotiation + - `notifications/initialized` + - protocol/startup/disconnect diagnostics +- server features を Yoi の明示 tool operations として expose する。 + - `tools/list` + - `tools/call` + - `resources/list` + - `resources/read` + - `prompts/list` + - `prompts/get` +- `resources` / `prompts` は direct context injection ではなく、通常の tool call result として history に記録される model-visible operation として扱う。 +- MCP tools は discovered tool を namespaced stable Yoi tool として expose する。 +- tool/resource/prompt metadata、schemas、annotations、content は untrusted data として扱う。 +- `tools/list` / `resources/list` / `prompts/list` pagination と list-changed notification を扱う。 +- result content を bounded serialization する。 + - `content[]` + - `structuredContent` + - `isError` + - `_meta` + - text / image / audio / resource_link / embedded resource +- roots を実装する場合は Yoi authorized scope 由来の root のみに限定する。 +- sampling / elicitation は初期実装では client capability として宣言せず、要求された場合は fail-closed diagnostic とする。 +- Streamable HTTP transport / OAuth / remote auth / MCP Registry distribution / automatic package execution はこの Ticket の対象外。 +- secret refs / env values / command args containing secrets を diagnostics / logs / model context に plaintext で出さない。 +- local mock MCP server を使った focused tests を追加する。 +- docs に local stdio MCP server の設定例、trust model、permission/scope/secret guidance を追加する。 + +## Acceptance criteria + +- docs/tests/config で MCP spec baseline `2025-11-25` が明記されている。 +- 少なくとも1つの local stdio MCP server を Profile/config で有効化できる。 +- configured server の initialize 成功/失敗が観測可能で、失敗時に server 名と phase が分かる。 +- discovered MCP tools が namespaced stable name で Yoi の model-visible tool schema に現れる。 +- registered MCP tool を呼ぶと `tools/call` が実行され、normal result / `isError: true` / JSON-RPC protocol error が区別される。 +- `resources/list` / `resources/read` と `prompts/list` / `prompts/get` が明示 tool operations として使え、結果が通常 tool result として history に残る。 +- resource/prompt content は history に残らない形で context に注入されない。 +- `structuredContent` / output schema / rich content blocks が bounded serialization される。 +- list-changed notification が silent stale にならず、safe refresh または restart/reinitialize-required diagnostic として扱われる。 +- PreToolCall permission denial が通常 Yoi tool denial と同じ経路で動く。 +- server-provided metadata/content が system/developer instruction や Yoi scope/permission を弱めない。 +- secrets が diagnostics/logs/model context に plaintext で出ないことを focused test または review で確認できる。 +- sampling / elicitation / Streamable HTTP / remote auth / distribution は disabled, fail-closed, or explicitly out-of-scope として実装・docs に反映されている。 +- Validation: focused MCP mock server tests、related crate tests、`cargo fmt --check`、`cargo check --workspace --all-targets`、`nix build .#yoi`。 + +## Binding decisions / invariants + +- MCP server は untrusted external capability provider として扱う。 +- MCP integration は `pod::feature` / Worker / ToolRegistry の通常 authority path に乗せ、private/ad-hoc bypass を作らない。 +- `resources/read` / `prompts/get` の結果を hidden context injection しない。明示 tool result としてのみ model-visible にする。 +- local process 起動は explicit config と explicit process authority に限る。 +- filesystem roots を公開する場合は Yoi authorized scope 由来に限定する。 +- unsupported client features, including sampling and elicitation, are fail-closed。 + +## Implementation latitude + +- exact Profile/config syntax、crate/module placement、namespacing format、diagnostic surface は invariants を満たす範囲で実装側に委ねる。 +- `notifications/*/list_changed` の live refresh が current run の tool schema consistency を壊す場合は、next-turn refresh または restart/reinitialize-required diagnostic でよい。 +- MCP `2025-11-25` の experimental tasks / `execution.taskSupport` は、実装時に API 拡張 Ticket の結果を踏まえて ordinary call fallback / unsupported diagnostic / focused support の範囲を決める。`required` task-only tool を silent mis-expose しない。 + +## Escalation conditions + +- API extension Ticket `00001KTR81P9X` の完了前に private bypass が必要になりそうな場合。 +- MCP tasks / task-augmented tool calls を full support するために Yoi Task / approval / resume model との統合判断が必要になる場合。 +- server-provided resource/prompt content を tool result 以外の context path に入れる必要が出た場合。 +- Streamable HTTP、remote auth、sampling、elicitation、workspace-provided executable/package auto-start に踏み込む必要が出た場合。 + +## Related work + +- Objective: `00001KTR80WMN` +- API prerequisite: `00001KTR81P9X` +- Decomposed from broad Ticket: `00001KST8H4M0` diff --git a/.yoi/tickets/00001KTR82RB7/thread.md b/.yoi/tickets/00001KTR82RB7/thread.md new file mode 100644 index 00000000..e834da3a --- /dev/null +++ b/.yoi/tickets/00001KTR82RB7/thread.md @@ -0,0 +1,7 @@ + + +## 作成 + +LocalTicketBackend によって作成されました。 + +--- diff --git a/.yoi/tickets/00001KTR83D6E/artifacts/.gitkeep b/.yoi/tickets/00001KTR83D6E/artifacts/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/.yoi/tickets/00001KTR83D6E/item.md b/.yoi/tickets/00001KTR83D6E/item.md new file mode 100644 index 00000000..330cec19 --- /dev/null +++ b/.yoi/tickets/00001KTR83D6E/item.md @@ -0,0 +1,64 @@ +--- +title: 'Edit/Writeの同一ファイル変更をToolExecutionContextで直列化する' +state: 'planning' +created_at: '2026-06-10T07:49:10Z' +updated_at: '2026-06-10T07:49:10Z' +assignee: null +--- + +## 背景 + +LLM-Worker は approved tool calls を並列実行する。これは維持したい一方で、同じ assistant response 内で同一ファイルに対する複数の `Edit` / `Write` / それに準ずる mutation tool が発行された場合、実行順序が nondeterministic になると、LLM が意図した順序と異なる変更・失敗・部分適用が起き得る。 + +`ToolExecutionContext` は既に導入済みで、各 tool call に `call_id` / `batch_id` / `call_index` が渡る。これにより、tool 実装側で response-local order と batch identity を参照できるようになった。この Ticket はその基盤を使い、Worker 自体を scheduler にせず、ファイル mutation tool 側で同一ファイル変更の直列化を行う。 + +## ゴール + +`Edit` / `Write` など同一ファイルを変更する built-in tool について、同じ target file への mutation が競合しないように tool 側で直列化し、同一 batch 内では LLM が返した `call_index` 順に処理されるようにする。 + +## 要件 + +- Worker の approved tool call 並列実行は維持する。 +- Worker に resource scheduling policy / per-file scheduler を持たせない。 +- `Edit` / `Write` など file mutation tool 側で、canonical target file path 単位の mutation guard / queue / mutex を持つ。 +- 同一 `batch_id` かつ同一 target file の複数 mutation は、`ToolExecutionContext.call_index` の昇順で実行される。 +- 異なる file への mutation は不要に直列化しない。 +- 異なる `batch_id` の同一 file mutation については、破綻しない排他を維持する。 + - 厳密な global ordering が必要か、単純な per-file mutex で十分かを実装時に判断し、理由を記録する。 +- `Edit` と `Write` が同じ file を対象にする場合も、同じ per-file mutation boundary に乗せる。 +- path normalization / canonicalization を慎重に扱う。 + - 同じ実ファイルを指す相対/絶対 path、`..`、symlink の扱いを明示する。 + - 既存 scope/permission/path validation と矛盾させない。 +- queue 待ち・timeout・panic/drop 時に lock が残り続けないようにする。 +- 失敗時は対象 tool call だけが明確な error result を返し、他 file の mutation や Worker 全体を不要に止めない。 +- `call_id` / `batch_id` / `call_index` は diagnostics に有用な範囲で使うが、secret/private path 露出や過剰 log を避ける。 + +## 非目標 + +- Worker に一般 resource scheduler を実装すること。 +- `parallel_tool_calls=false` を導入すること。 +- Hook / Interceptor に lock lifecycle を持たせること。 +- すべての tool を直列化すること。 +- LLM response 全体を sequential execution に戻すこと。 +- 複数 process / 複数 Pod 間の完全な distributed file lock をこの Ticket で解くこと。 + +## 受け入れ条件 + +- 同一 response / 同一 `batch_id` 内で同じ file に対する複数 `Edit` が発行された場合、`call_index` 昇順に実行される。 +- 同一 response / 同一 `batch_id` 内で同じ file に対する `Write` と `Edit` が混在しても、同じ file mutation boundary で直列化される。 +- 異なる file に対する `Edit` / `Write` は並列実行可能なままである。 +- Worker の tool execution path は引き続き approved calls を並列に起動し、Worker が file scheduling policy を所有しない。 +- path equivalence の扱いがテストまたは実装コメントで固定されている。 +- mutation 中に tool が error になっても guard が解放され、後続 mutation が永久待ちしない。 +- focused tests が追加されている。 + - same-batch same-file multiple `Edit` order; + - same-batch same-file `Write` + `Edit` order; + - different-file mutations remain concurrent; + - failed mutation releases the per-file guard; + - path normalization/equivalence case。 +- `cargo test` の targeted command、`cargo fmt --check`、`git diff --check`、`target/debug/yoi ticket doctor` が通る。 + +## 実装メモ + +- `ToolExecutionContext` 導入 Ticket `00001KTNVGT8G` では、この same-file mutation queue / Edit-Write serialization は明示的に非目標だった。本 Ticket はその follow-up。 +- Analytics Ticket `00001KTNS9B50` は same-file multiple Edit の検出であり、実行制御ではない。 diff --git a/.yoi/tickets/00001KTR83D6E/thread.md b/.yoi/tickets/00001KTR83D6E/thread.md new file mode 100644 index 00000000..d0e2f2b0 --- /dev/null +++ b/.yoi/tickets/00001KTR83D6E/thread.md @@ -0,0 +1,7 @@ + + +## 作成 + +LocalTicketBackend によって作成されました。 + +---