diff --git a/.yoi/tickets/00001KW7726H9/artifacts/.gitkeep b/.yoi/tickets/00001KW7726H9/artifacts/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/.yoi/tickets/00001KW7726H9/artifacts/api-field-audit.md b/.yoi/tickets/00001KW7726H9/artifacts/api-field-audit.md new file mode 100644 index 00000000..672efa85 --- /dev/null +++ b/.yoi/tickets/00001KW7726H9/artifacts/api-field-audit.md @@ -0,0 +1,225 @@ +# Runtime Worker creation API field audit + +調査日: 2026-06-28 +対象 Ticket: `00001KW7726H9` + +## 方針 + +未検証の field を API 案として固定しない。以下は現在の実装に存在する型と field を確認し、canonical Runtime Worker creation に残せるかを判定したもの。 + +参照した主な実装: + +- `crates/worker-runtime/src/catalog.rs` +- `crates/worker-runtime/src/runtime.rs` +- `crates/worker-runtime/src/config_bundle.rs` +- `crates/worker-runtime/src/execution.rs` +- `crates/worker-runtime/src/fs_store.rs` +- `crates/workspace-server/src/hosts.rs` +- `crates/workspace-server/src/server.rs` +- `crates/worker/src/runtime_adapter.rs` +- `crates/protocol/src/lib.rs` + +## 現在の Runtime `CreateWorkerRequest` + +現在の型は `worker_runtime::catalog::CreateWorkerRequest`。 + +```rust +pub struct CreateWorkerRequest { + pub intent: WorkerIntent, + pub profile: ProfileSelector, + pub config_bundle: Option, + pub requested_capabilities: Vec, + pub workspace_refs: Vec, + pub mount_refs: Vec, +} +``` + +### `intent: WorkerIntent` + +- source: Workspace Backend / direct Runtime HTTP caller。 +- current use: Worker summary/detail projection、worker snapshot persistence、diagnostic label。`Task.objective` は non-empty validation のみ。 +- scope/access: なし。execution backend の実行条件ではない。 +- visibility: Runtime metadata と Browser-facing projection に出る。 +- persistence/projection: `PersistedWorkerRecord.request` と `WorkerSnapshot.request` に保存される。 +- retry: idempotency には使われていない。 +- validation: `Task.objective` の空文字のみ。 +- verdict: canonical Runtime create request からは外す。Workspace Companion / Ticket role / Objective などは Backend launch context と initial input / tools 側で扱う。Runtime projection に必要な表示情報があれば、別途検証した display/projection field として定義する。 + +### `profile: ProfileSelector` + +- source: Workspace Backend。現状は Browser-facing `WorkerSpawnRequest.profile` からも来得る。 +- current use: ConfigBundle compatibility check、`worker::runtime_adapter::ProfileRuntimeWorkerFactory::runtime_profile` が実 Worker profile resolution に使う。 +- scope/access: なし。ただし実 Worker の Profile 選択に直結する。 +- visibility: Runtime metadata と Browser-facing projection に出る。 +- persistence/projection: `CreateWorkerRequest` ごと worker snapshot に保存される。 +- retry: 同じ selector なら同じ意味になり得るが、Profile 内容の時点依存は ConfigBundle identity で固定する必要がある。 +- validation: `ConfigBundle` がある場合は bundle 内に profile があるか確認。`Named` は synced bundle がないと拒否。 +- verdict: Runtime create request に残す候補。ただし Browser が自由入力する field ではなく、Backend が launch context から決定する。ConfigBundle identity と組み合わせて Profile 内容を固定すること。 + +### `config_bundle: Option` + +- source: 現状は caller が `ConfigBundleRef { id, digest }` を渡す。Workspace Backend の `WorkerSpawnRequest` にも露出している。 +- current use: Runtime が `config_bundles` store から id で lookup し、digest 一致と profile compatibility を検証する。 +- scope/access: なし。secret 値や raw path は含まない。 +- visibility: Runtime metadata と Browser-facing projection に出る。 +- persistence/projection: request として worker snapshot に保存される。ConfigBundle 本体は runtime snapshot の `config_bundles` に保存される。 +- retry: id+digest は stable。`LatestForProfile` のような時点依存 selector は存在しないし入れない。 +- validation: id / digest の形式、store presence、digest mismatch、profile containment。 +- verdict: Runtime create request に残すなら、Backend が直前に `SyncConfigBundle` / availability check で得た id+digest だけを渡す形に限定する。Browser-facing launch request からは外す。`Option` のまま runtime default に落ちる経路は canonical path として再検証が必要。 + +### `requested_capabilities: Vec` + +- source: 現状は Browser-facing `WorkerSpawnRequest.requested_capabilities` からも来得る。embedded spawn は空の場合に `read` を補う。 +- current use: Runtime summary/detail の count/projection、request persistence。execution backend / Worker factory はこの field を実行制限として使っていない。 +- scope/access: 現時点では access control ではない。validation は capability name non-empty のみ。 +- visibility: Runtime detail に出る。 +- persistence/projection: request として worker snapshot に保存される。 +- retry: idempotency には使われていない。 +- validation: name non-empty のみ。 +- verdict: canonical Runtime create request からは外す。必要な declaration は ConfigBundle、実際の制限は既存 execution backend / tool host / scope 設定側で扱う。未システム化の requested capability を API field として残さない。 + +### `workspace_refs: Vec` + +- source: caller supplied opaque refs。 +- current use: Runtime detail projection と persistence。execution backend / Worker factory は使っていない。 +- scope/access: 現時点では access control ではない。 +- visibility: Runtime detail に出る。 +- persistence/projection: request として worker snapshot に保存される。 +- retry: 意味は caller convention 依存。 +- validation: 実質なし。 +- verdict: canonical Runtime create request から削除する。working directory / cwd / workspace root を Runtime metadata にしない。 + +### `mount_refs: Vec` + +- source: caller supplied opaque refs。 +- current use: Runtime detail projection と persistence。execution backend / Worker factory は使っていない。 +- scope/access: 現時点では access control ではない。 +- visibility: Runtime detail に出る。 +- persistence/projection: request として worker snapshot に保存される。 +- retry: 意味は caller convention 依存。 +- validation: 実質なし。 +- verdict: canonical Runtime create request から削除する。mount/materialization を Runtime create payload にしない。 + +## 現在の Browser-facing `WorkerSpawnRequest` + +現在の型は `workspace-server::hosts::WorkerSpawnRequest`。 + +```rust +pub struct WorkerSpawnRequest { + pub intent: WorkerSpawnIntent, + pub requested_worker_name: Option, + pub acceptance: WorkerSpawnAcceptanceRequirement, + pub profile: Option, + pub config_bundle: Option, + pub requested_capabilities: Vec, +} +``` + +### `intent: WorkerSpawnIntent` + +- source: Browser / Workspace Backend caller。 +- current use: embedded adapter が Runtime `WorkerIntent` と default Profile に変換する。 +- verdict: Browser-facing launch context として残す。Runtime create request へはそのまま渡さない。 + +### `requested_worker_name: Option` + +- source: Browser-facing caller。 +- current use: embedded runtime v0 では ignored diagnostic。WorkerId は Runtime sequence で割り当て。 +- verdict: canonical flow で必要なら display/projection として再設計する。Worker identity authority にはしない。 + +### `acceptance: WorkerSpawnAcceptanceRequirement` + +- source: Browser-facing caller / Backend launch policy。 +- current use: embedded Runtime は `SocketReady` を拒否し、`RunAccepted` は diagnostic のみ。Runtime create API には存在しない。 +- verdict: Browser/Backend launch policy として残す候補。Runtime create request field にはしない。acceptance evidence は Backend が create/input/observe 結果から構成する。 + +### `profile: Option` + +- source: Browser-facing caller からも渡せる。 +- current use: Runtime create `profile` にそのまま渡る。 +- verdict: Browser-facing API で自由に渡す field としては再検証が必要。canonical flow では Backend が role/target から決定し、Runtime create には Backend-decided profile を渡す。 + +### `config_bundle: Option` + +- source: Browser-facing caller からも渡せる。 +- current use: Runtime create にそのまま渡る。 +- verdict: Browser-facing API から削除する。Backend が ConfigBundle を決定・sync/check し、その結果の stable identity を Runtime create に渡す。 + +### `requested_capabilities: Vec` + +- source: Browser-facing caller からも渡せる。 +- current use: Runtime create にそのまま渡る。実 execution 制限には使われていない。 +- verdict: Browser-facing API から削除するか Backend-only policy input に閉じる。Runtime create にそのまま流さない。 + +## ConfigBundle sync / store + +- `ConfigBundle` は `metadata.id` と `metadata.digest` を持つ。 +- `ConfigBundle::computed_digest()` が content digest を計算する。 +- `Runtime::store_config_bundle()` は validate 後、runtime state の `config_bundles: BTreeMap` に保存し、`ConfigBundleAvailability { reference: ConfigBundleRef { id, digest }, summary }` を返す。 +- fs-store では ConfigBundle 本体は runtime snapshot に保存される。 + +Verdict: + +- create caller が Runtime store を探索する必要はない。Backend が bundle を決めて sync/check し、返った id+digest を使う形なら妥当。 +- Browser-facing launch に ConfigBundleRef を出す必要はない。 +- `LatestForProfile` のような runtime-local latest selector は入れない。 + +## Initial input / Segment + +- protocol `Segment` の既存 variant は `Text` / `Paste` / `FileRef` / `KnowledgeRef` / `WorkflowInvoke` / `Unknown`。 +- `TicketRef` / `ObjectiveRef` variant は現在存在しない。 +- Runtime `WorkerInput` は `kind` + `content: String`。Runtime transcript も `TranscriptEntry.content: String`。 +- Runtime adapter は `WorkerInput.content` を `Segment::text(content)` にして `Method::Run` に渡している。 + +Verdict: + +- initial input を `Vec` に寄せる方針は protocol 慣例として妥当だが、現状の Runtime input/transcript は String なので、そのまま field を追加するだけでは不十分。 +- Ticket / Objective を Segment として渡すなら、既存 variant で text にするか、protocol に record ref variant を追加する必要がある。未実装の `TicketRef` / `ObjectiveRef` を API field として前提にしない。 +- `System` initial message は不要。role prompt / system-level instruction は Profile / ConfigBundle 側で解決する。 + +## Execution / workspace scope + +- `WorkerExecutionSpawnRequest` は `worker_ref`、`request: CreateWorkerRequest`、`context: WorkerExecutionContext` を持つ。 +- `WorkerExecutionContext` は observation publish と worker_ref を持つだけで、cwd / workspace root / scope を持たない。 +- `worker::runtime_adapter::ProfileRuntimeWorkerFactory` は `workspace_root` と `cwd` を factory に保持し、request field から per-worker cwd を受け取っていない。 +- Workspace Backend の embedded runtime 初期化は `WorkerRuntimeExecutionBackend::from_workspace(config.workspace_root.clone())`。 + +Verdict: + +- 現在は per-worker execution binding API は存在しない。 +- `ExecutionBindingRef` は最終型名ではなく、今の Ticket では「Runtime create payload に raw cwd/workspace/tool scope を入れない」という境界だけを確定する。 +- per-worker cwd / tool scope が必要なら、まず execution backend / factory boundary を設計・実装する必要がある。 + +## Worker creation persistence / transaction + +- worker-runtime fs-store は runtime snapshot、worker snapshot、event、transcript を保存する。 +- worker snapshot は現在 `CreateWorkerRequest` 全体を保存する。 +- `Runtime::create_worker()` は現在、Worker record を insert/persist してから execution backend spawn を呼ぶ。 +- spawn が rejected/errored になっても Worker は残り、execution status に失敗が記録される。 +- execution backend がない Runtime でも Worker は catalog-only として作れる。 + +Verdict: + +- canonical invariant として「input-capable Worker は execution backend 接続済み」を守るには、現在の create order / failure handling を変更する必要がある。 +- 永続化しない選択肢はない。検証すべきなのは、既存正規 store/projection のどこに何を保存し、spawn failure をどう診断表示するか。 +- catalog-only Worker を通常 Worker として公開する現経路は canonical path では禁止または explicit non-input-capable diagnostic に分類する。 + +## 現時点で API field として固定してよいもの / だめなもの + +固定してよい境界: + +- Runtime create は WorkerId を発行する唯一の経路にする。 +- Runtime create は Browser-facing launch とは別の内部境界にする。 +- Runtime create は synced ConfigBundle identity を検証する。 +- Runtime create は raw workspace path / cwd / socket / credential / session path を受け取らない。 +- Runtime create は initial input を Worker creation transaction と同じ単位で扱う。 +- Runtime create は execution backend に接続できない Worker を通常 input-capable Worker として公開しない。 + +まだ field として固定しないもの: + +- `launch_id`: existing idempotency key がないため、source/persistence/retry contract を設計してから。 +- `ConfigBundleRef` / digest field: Runtime-internal create では sync response 由来の id+digest が候補だが、Browser-facing には出さない。既存 store contract と migration を確認して確定。 +- `ExecutionBindingRef`: 現在の execution backend boundary に存在しないため、field として固定しない。 +- `Vec` initial input: direction は妥当だが Runtime input/transcript が String なので、protocol/store変更を伴う。field だけ先に固定しない。 +- `display`: 現在は intent/profile 由来の projection。必要なら projection設計として検証してから。 +- `acceptance`: Backend launch policy。Runtime create field として固定しない。 diff --git a/.yoi/tickets/00001KW7726H9/artifacts/relations.json b/.yoi/tickets/00001KW7726H9/artifacts/relations.json new file mode 100644 index 00000000..5cbba9b2 --- /dev/null +++ b/.yoi/tickets/00001KW7726H9/artifacts/relations.json @@ -0,0 +1,29 @@ +{ + "version": 1, + "relations": [ + { + "ticket_id": "00001KW7726H9", + "kind": "related", + "target": "00001KW55B32Y", + "note": "execution backend boundary is part of the canonical Worker creation contract", + "author": "yoi ticket", + "at": "2026-06-28T13:36:24Z" + }, + { + "ticket_id": "00001KW7726H9", + "kind": "related", + "target": "00001KW55B33B", + "note": "embedded worker crate adapter must be entered through the canonical creation path", + "author": "yoi ticket", + "at": "2026-06-28T13:36:24Z" + }, + { + "ticket_id": "00001KW7726H9", + "kind": "related", + "target": "00001KW55B33H", + "note": "Workspace Companion bootstrap must not bypass canonical Runtime Worker creation", + "author": "yoi ticket", + "at": "2026-06-28T13:36:24Z" + } + ] +} diff --git a/.yoi/tickets/00001KW7726H9/item.md b/.yoi/tickets/00001KW7726H9/item.md new file mode 100644 index 00000000..dfc61866 --- /dev/null +++ b/.yoi/tickets/00001KW7726H9/item.md @@ -0,0 +1,245 @@ +--- +title: 'Runtime Worker起動経路を正規のExecution/ConfigBundle経路に一本化する' +state: 'ready' +created_at: '2026-06-28T13:35:21Z' +updated_at: '2026-06-28T16:41:17Z' +assignee: null +--- + +## 背景 + +Runtime 上の Worker 起動経路が増え、一覧には出るが入力できない Worker、execution backend につながっていない Worker、再起動で消える Worker が作れてしまう状態になっている。 + +Worker を作る手順は、embedded、remote、Workspace Companion、Web Console のどれから呼ばれても同じであるべき。違いは配置や通信方式に閉じ込め、Worker 作成そのものは正規の API を通す。 + +この Ticket は、最終 API の field を疑似定義するものではない。`CreateWorkerRequest` などの具体 field は、既存型・永続化・retry・transport・scope 境界を確認したうえで実装時に確定する。ここでは API 境界、責務、検証すべき性質を定義する。 + +## 目的 + +- Runtime 上の Worker 作成手順を 1 本にする。 +- 作られた Worker は、入力・観測・実行・履歴保存がそろった状態にする。 +- Workspace Backend / Companion / Web Console が独自に Worker 風のものを作らないようにする。 +- Runtime に workspace filesystem access / tool execution scope を持たせない。 +- working directory や Ticket / Objective の意味は Backend 側で扱い、Runtime の Worker identity に混ぜない。 +- Worker creation を中間状態が残りにくい transactional API にする。 +- 未検証の request field を API 案として固定しない。 + +## やり取りの全体像 + +外部から見た Worker 起動は、Workspace Backend への 1 回の launch request にする。Browser / Web Console は Runtime の内部 config store、execution binding、cwd、tool scope、secret、Runtime endpoint を知らない。 + +```text +Browser / Web Console + -> Workspace Backend: launch worker + +Workspace Backend + -> Runtime: ensure/sync ConfigBundle if needed + -> execution host / tool host: create execution binding if needed + -> Runtime: create worker +``` + +Runtime の Worker creation は 1 request / 1 transaction として扱う。途中で必要な前提が欠けていた場合は typed error を返し、入力不能な Worker や fake response は作らない。 + +## 検証済み field audit + +現在の実装に存在する Worker creation / launch 関連 field は、`artifacts/api-field-audit.md` で調査済み。以後この Ticket で API field を追加・削除・改名する場合は、その artifact と同じ観点で検証してから行う。 + +主な結論: + +- 現行 Runtime `CreateWorkerRequest` の `intent` / `requested_capabilities` / `workspace_refs` / `mount_refs` は canonical Runtime create request には残さない。 +- 現行 Browser-facing `WorkerSpawnRequest.config_bundle` / `requested_capabilities` は Runtime create にそのまま流さない。 +- ConfigBundle は Browser-facing launch から選ばせず、Backend が決定・sync/check した stable identity だけを Runtime create 境界で扱う。 +- `ExecutionBindingRef` は現行実装に存在しないため、最終 field として固定しない。現時点で確定するのは、Runtime create payload に raw cwd / workspace / tool scope を入れない境界だけ。 +- initial input を `Vec` に寄せる方針は妥当だが、現行 Runtime input / transcript は String なので、field だけ先に固定しない。 + +## API 境界 + +### Browser-facing launch + +Browser-facing API は product semantics を受け取る。これは Runtime の Worker creation API ではない。 + +Browser-facing launch で扱ってよい情報: + +- Profile selector または role selector。 +- role / display name などの表示・選択情報。 +- 対象 Ticket / Objective など Backend launch context。 +- acceptance policy など、Backend が解釈して Runtime create に落とし込む方針。 + +Browser-facing launch に出してはいけない情報: + +- Runtime endpoint / credential / socket path / session path。 +- raw workspace path / cwd。 +- tool scope / tool access の具体設定。 +- Runtime 内部の config store 状態。 +- execution binding の中身。 + +### ConfigBundle sync + +`ConfigBundle` 本体は Worker creation payload に混ぜない。Backend が Profile などから ConfigBundle を決定し、必要なら Runtime に同期する。 + +ただし、Runtime create request が何を持つかは実装時に検証して決める。特に `ConfigBundleRef` のような参照を渡す案は、request を出す側が Runtime 内部の config store を把握する必要を生む可能性があるため、無条件に採用しない。 + +API 確定時に満たすべき条件: + +- create caller が Runtime 内部 store を探索・選択しなくてよい。 +- retry / duplicate launch で同じ ConfigBundle を指せる。 +- Runtime restart 後に、どの ConfigBundle で Worker を作ったか診断できる。 +- Runtime は create 時に ConfigBundle の存在、内容同一性、Profile compatibility、provider / secret / declaration の整合を検証できる。 +- `LatestForProfile` のような時点依存の選択を Worker creation の再現性に混ぜない。 + +候補としては、Backend が同期した bundle について Runtime から返る stable identity を Runtime create に渡す方式がある。ただしこれは Browser-facing API に出さず、既存の ConfigBundle store / digest 型 / sync API に従って実装時に確定する。 + +### Execution binding + +working directory、cwd、tool scope、Ticket backend access は Runtime に渡さない。embedded Runtime も例外ではなく、Runtime 自体は workspace filesystem access を持たない。 + +Workspace Backend は launch context をもとに execution host / tool host 側へ binding を作る。binding は execution backend が Worker を起動するときに使う opaque handle であり、Runtime が中身を解釈するものではない。 + +API 確定時に満たすべき条件: + +- binding 作成は Runtime API ではなく、Backend / execution host / tool host 側の内部 API として扱う。 +- Runtime は binding の cwd / raw workspace path / tool scope / Ticket backend path を metadata として保持しない。 +- Runtime は binding の中身を解釈して file operation を行わない。 +- file/tool access の制限は execution backend / tool host 側で行う。 +- remote Runtime が local workspace の binding を使えない場合は、binding の中身を Runtime create request に展開せず typed error にする。 +- 未使用 binding が残る場合に備え、execution host 側で lease / TTL / explicit cleanup のいずれかを持つ。 + +`ExecutionBindingRef` という名前は候補であり、最終型名ではない。現時点で専用システムが存在しない概念を API field として新設しない。既存の execution backend 接続型や tool host の scope 設定を確認してから決める。 + +### Initial input + +initial input は Worker creation と同じ transaction で transcript に入る。別 store に先置きする `InitialInputRef` / `PrepareInitialInput` は作らない方針とする。 + +initial input は独自 message 型ではなく、既存 protocol の `Segment` / user submission 表現に寄せる。`System` message は作らない。role prompt / system-level instruction は Profile / ConfigBundle 側で解決する。 + +API 確定時に満たすべき条件: + +- Ticket / Objective の要約文は通常の text segment として扱える。 +- Ticket / Objective など読み直し可能な record は、別 field ではなく Segment の既存または追加 variant で表せる。 +- Worker 側では通常の user submission と同じ解決経路で context 化される。 +- Backend claim、RuntimeRegistry の振り分け、raw workspace path、working directory の作成方針、execution binding は conversation context に入らない。 + +既存 `Segment` の variant と変換経路を確認し、不足があればこの Ticket の実装内で Segment 側を拡張するか、別 Ticket に分ける。 + +### Runtime worker creation + +Runtime worker creation は、同期済み ConfigBundle、execution binding、initial input を結びつけ、execution backend に接続した Worker を登録する唯一の経路にする。 + +ただし、最終的な `CreateWorkerRequest` の field はこの Ticket 本文では固定しない。実装前に各 field を次の観点で検証し、Ticket thread または実装 report に残す。Worker creation の永続化は必須であり、永続化しない worker creation path は作らない。 + +各 field の検証観点: + +- source: 誰がその値を作るか。 +- scope/access: その値は既存の access/scope 制限に関わるか、単なる識別子・表示情報か。 +- visibility: Browser-facing API / Runtime metadata / Worker conversation / execution backend のどこに見えてよいか。 +- persistence/projection: Runtime restart 後に、既存の正規 store のどの record / projection に何を保存し、どの情報を復元・診断に使うか。store を選ぶ項目ではない。`no` は選択肢にしない。raw handle などを保存できない場合でも、対応する durable identity / projection / diagnostic record を持つ。 +- retry: retry / duplicate launch で同じ意味になるか。 +- validation: Runtime create 時に何を検証できるか。 +- existing type: 既存型・既存 protocol に対応物があるか。 +- failure: 不足・不整合時にどの typed error になるか。 + +現時点で確定している制約: + +- WorkerId を発行するのは Runtime worker creation だけ。 +- Worker creation は 1 request / 1 transaction として扱う。 +- Worker creation の結果は worker-runtime fs-store / transcript store / catalog の既存正規 store に永続化される。永続化しない Worker は通常 Worker として作らない。 +- Runtime は workspace filesystem access / tool execution scope を持たない。 +- Runtime は fake / providerless assistant response を生成しない。 +- Runtime は execution backend 未接続の Worker を通常 Worker として公開しない。 + +## transaction と失敗処理 + +Runtime worker creation は概ね次を 1 transaction として行う。ただし具体的な保存順序は実装時に worker-runtime fs-store / execution backend / transcript store の既存 contract を確認して決める。永続化しない起動はこの Ticket の対象にしない。 + +```text +create worker: + 1. retry / duplicate launch を扱う。 + 2. ConfigBundle を検証する。 + 3. execution binding を execution backend に渡して接続可能か確認する。 + 4. WorkerId / TranscriptId を割り当てる。 + 5. initial input を user submission として transcript に保存する。 + 6. Runtime catalog に Worker を登録する。 + 7. execution backend に接続する。 + 8. response を返す。 +``` + +途中失敗した場合は、WorkerId を公開しないか、公開済みなら failed creation として明示的に診断できる状態にする。入力不能な Worker や fake response は作らない。 + +想定される typed error は実装時に既存 error 型と合わせて確定する。少なくとも次の分類は必要になる。 + +- duplicate / retry conflict。 +- ConfigBundle missing / mismatch / incompatible。 +- provider / secret / declaration 不足。 +- execution binding missing / unsupported。 +- execution backend unavailable。 +- persistence failure。 + +## 境界 + +- Runtime は workspace filesystem access / tool execution scope を持たない。 +- embedded Runtime でも Runtime 自体に workspace filesystem access を許可しない。 +- raw workspace path / cwd / socket path / credential / session path は Browser-facing API に出さない。 +- Ticket id / Objective id は Runtime の Worker identity にしない。 +- `ConfigBundle` 本体は Worker creation payload にしない。 +- `InitialInputRef` は作らず、initial input は Worker creation request に inline する。 +- `ExecutionEnvironmentRef` のように Runtime が working directory materialization を持つように見える型は避ける。 +- execution backend に接続できないものを通常 Worker として一覧に出さない。 + +## 既存経路の整理 + +- embedded Runtime は上記の作成手順を通る。ただし embedded Runtime に workspace filesystem access を付与しない。 +- remote Runtime も同じ worker creation contract を使う。execution binding を使えない段階では typed error で拒否する。 +- Companion 専用の作成・送信経路が残る場合も、内部ではこの worker creation API の薄い呼び出しにする。 +- Web Console は `runtime_id + worker_id` を対象に入力・観測するだけにし、Worker 作成の特別扱いを持たない。 + +## 保存と再起動 + +- Worker 作成時に Worker id、参照した ConfigBundle identity、execution binding identity、transcript id、initial input を保存する。保存しない選択肢は取らない。 +- 保存する identity が access/scope を与える値にならないようにする。たとえば execution binding identity は Runtime の filesystem access ではなく、stale execution mapping の診断と execution backend reconnect のための参照として扱う。 +- 再起動後に live execution handle を復元できない場合は、stale execution mapping として診断する。 +- ConfigBundle、execution binding、履歴のどれかが見つからない場合は typed diagnostic にし、黙って別 Worker を作らない。 + +## 対象外 + +- Web Console の見た目変更。 +- 複数利用者の auth / permission / redaction policy の完成。 +- provider / secret store UI の新設。 +- remote Runtime process supervisor の完成。 +- remote Runtime の execution provisioning の完成。 +- `pod_store` など旧内部 store 名の全面 rename。 + +## 実装前に必ず確認するもの + +初回調査結果は `artifacts/api-field-audit.md` に記録済み。実装時はその調査結果を更新し、コード変更に合わせて以下を再確認する。 + +- 現在の `worker-runtime` の create / catalog / fs-store / execution backend mapping 型。 +- 現在の Workspace Backend launch API と embedded Runtime 呼び出し箇所。 +- ConfigBundle store / digest / sync の既存型と責務。 +- existing `Segment` / user submission / transcript append の型と変換経路。 +- execution host / tool host / scope 設定の既存境界。 +- retry / duplicate launch に使える既存 idempotency key または request id。 + +## 受け入れ条件 + +- Browser-facing launch request と Runtime worker creation request の責務差が code/docs/tests 上で明確になっている。 +- Runtime が workspace filesystem access / tool execution scope を持たないことが code/docs/tests 上で明確になっている。 +- ConfigBundle sync と worker creation payload が分離されている。 +- worker creation caller が Runtime 内部 config store を探索・選択する必要がない。 +- ConfigBundle の識別方法が content identity / digest / 既存 store contract の観点で検証され、thread または実装 report に記録されている。 +- execution binding 作成経路が Backend / execution host 側に定義され、Runtime API として扱われていない。 +- initial input は Worker creation request に inline され、`InitialInputRef` / `PrepareInitialInput` のような中間 API を作らない。 +- initial input は既存 `Segment` / user submission 表現に寄せられ、Ticket / Objective record 参照も Segment 経路で扱われる。 +- Runtime worker creation request の各 field について、source / scope-access / visibility / persistence-projection / retry / validation / existing type / failure が検証されている。persistence-projection は保存有無や store 選択ではなく、既存の正規 store のどの record / projection に何を保存・復元・診断するかを確認する項目である。 +- Runtime worker creation が 1 request / 1 transaction として扱われ、WorkerId を発行する唯一の API になっている。 +- embedded Worker / Workspace Companion / remote-facing Worker creation が同じ作成手順を使う。 +- input-capable Worker が execution backend 未接続になる経路がない。 +- fake / providerless assistant response を生成する Worker 起動 bypass がない。 +- ConfigBundle / Profile / provider / secret / execution binding 不足が typed diagnostic になる。 +- Runtime catalog / transcript / observation / persistence initialization が Worker creation と一貫しており、永続化しない通常 Worker 作成経路がない。 +- Browser-facing API に Runtime endpoint / credential / socket path / session path / raw execution handle / raw workspace path が漏れない。 +- Focused tests が Worker 作成成功、duplicate launch retry、missing ConfigBundle rejection、missing execution binding rejection、execution backend connected Worker、stale execution mapping diagnostic、Companion bootstrap path を確認する。 +- `cargo test -p worker-runtime --features ws-server` が通る。 +- `cargo test -p yoi-workspace-server` が通る。 +- `cargo check -p yoi` が通る。 +- `git diff --check` が通る。 +- `nix build .#yoi --no-link` が通る。 diff --git a/.yoi/tickets/00001KW7726H9/thread.md b/.yoi/tickets/00001KW7726H9/thread.md new file mode 100644 index 00000000..33fd3e51 --- /dev/null +++ b/.yoi/tickets/00001KW7726H9/thread.md @@ -0,0 +1,206 @@ + + +## 作成 + +LocalTicketBackend によって作成されました。 + +--- + + + +## Decision + +Runtime Worker creation API から Backend/Orchestrator intent と raw workspace context を外す。 + +決定: +- `intent` は Runtime の authority ではなく Backend-side launch context とする。Workspace Companion / Ticket role / Orchestrator routing / Objective は Backend が Profile 選択、ConfigBundle 選択、ExecutionEnvironment 準備、initial context/tool authority 付与に使う。 +- ConfigBundle 本体は create payload で送らない。Runtime は事前同期済み ConfigBundle store を ref/digest で参照し、create 時に availability / digest / profile compatibility / provider / secret / authority を検証する。 +- working directory / workspace root / tool scope は Runtime create request の raw field にしない。Backend が worktree/cwd/tool authority/project record access/ticket backend access を準備し、Runtime には opaque `ExecutionEnvironmentRef` を渡す。 +- Ticket / Objective は Runtime Worker identity metadata ではなく、initial context と tool-readable records として Worker に与える。Worker が知るべきなのは対象 Ticket/Objective の内容と使える tools/scope であり、Backend claim id や RuntimeRegistry routing ではない。 + +Runtime create request の中心は Profile selector、ConfigBundle ref、ExecutionEnvironmentRef、labels/role、execution/acceptance requirement に絞る。 + + +--- + + + +## Decision + +前回の記述は「API に入れないもの」の列挙に寄りすぎていたため、Ticket 本体を API 設計中心に書き直した。 + +修正内容: +- 横文字中心の見出しと説明を減らし、起動手順と作る API の形を前面に出した。 +- ConfigBundle 同期、ExecutionEnvironment 準備、InitialInput 準備、Worker 作成を別 API として整理した。 +- `CreateWorkerRequest` の具体的なフィールド案を明記した。 +- `WorkerWorkspaceRef` は Worker 作成 API に入れず、working directory は `ExecutionEnvironmentRef` として execution backend だけが解決する内部参照にした。 +- Ticket / Objective は Worker identity ではなく、initial input と tool-readable records で渡す形にした。後続 decision で initial input は `CreateWorkerRequest` に inline する方針へ更新した。 + + +--- + + + +## Decision + +前回の修正で domain term まで不自然に和訳していたため、Ticket 本体の用語を修正した。 + +修正方針: +- ConfigBundle / ExecutionEnvironment / InitialInput / execution backend / tool authority / provider / secret / Browser-facing API などの domain term はそのまま使う。 +- 説明文は日本語にするが、API 名・crate/domain 用語は訳語を作らない。 +- 独自訳は作らず、`tool authority` に統一する。 + + +--- + + + +## Decision + +Worker 起動 protocol の整理を更新した。 + +決定: +- Browser-facing launch は Workspace Backend への 1 request とする。Browser / Web Console は ConfigBundleRef、ExecutionEnvironmentRef、cwd、tool authority、secret、Runtime endpoint を知らない。 +- Runtime の Worker creation は `CreateWorker` 1 request / 1 transaction とする。WorkerId を発行するのは `CreateWorker` だけ。 +- ConfigBundle sync は create 前の冪等な前提準備であり、Worker を作らない。 +- ExecutionEnvironment 準備は Backend / Runtime 内部の前提準備であり、Worker に見せる protocol ではない。未使用参照には lease / TTL / cleanup を持たせる。 +- initial input は `CreateWorkerRequest` に inline する。`PrepareInitialInput` / `InitialInputRef` は作らない。 +- `launch_id` を `CreateWorkerRequest` に入れ、retry / duplicate request を安定して扱えるようにする。 + + +--- + + + +## Decision + +embedded Runtime の authority 境界を踏まえて、ExecutionEnvironmentRef 方針を撤回し、ExecutionBindingRef 方針に更新した。 + +決定: +- Runtime は file operation authority / tool authority を持たない。embedded Runtime でも例外にしない。 +- working directory / cwd / tool scope / Ticket backend authority は Runtime create request に入れない。 +- Backend は execution host / tool host 側に execution binding を作る。これは Runtime API ではなく、Browser-facing API にも Worker の conversation context にも出さない。 +- `CreateWorkerRequest` は `ExecutionEnvironmentRef` ではなく opaque な `ExecutionBindingRef` を受け取る。 +- `ExecutionBindingRef` は Runtime に file access を許可する ref ではなく、Runtime が execution backend に接続するときに渡す handle とする。 +- binding の cwd / tool authority / Ticket backend access の enforcement は execution backend / tool host 側で行う。 +- remote Runtime が binding を使えない場合は、binding の中身を Runtime create request に展開せず、typed error で拒否する。 + + +--- + + + +## Decision + +InitialInput の表現を protocol Segment に寄せる。 + +決定: +- initial input 用の独自 message 型は作らず、`CreateWorkerRequest.initial_input` は `Vec` とする。 +- `System` message は作らない。role prompt / system-level instruction は Profile / ConfigBundle 側で解決する。 +- readable record 用の別 field は作らない。Ticket / Objective などの読み直し可能な参照は Segment variant として表す。 +- Ticket / Objective の要約文は `Segment::Text`、参照は `Segment::TicketRef` / `Segment::ObjectiveRef` 相当で表し、通常の user submission と同じ解決経路で扱う。 + + +--- + + + +## Decision + +未検証の pseudo API field を Ticket 本体から外し、API 確定を実装時の検証事項として委譲する方針に更新した。 + +決定: +- この Ticket 本文では `CreateWorkerRequest` の最終 field を固定しない。 +- API field を定義する場合は、各 field ごとに source / authority / visibility / persistence / retry / validation / existing type / failure を検証する。 +- `ConfigBundleRef` のような参照を create request に渡す案は、caller が Runtime 内部 config store を把握する必要を生む可能性があるため未採用とする。 +- ConfigBundle の識別方法は、content identity / digest / 既存 store contract を確認して実装時に確定する。 +- initial input は既存 Segment / user submission 表現に寄せる方針だけを残し、独自 pseudo type は置かない。 +- ExecutionBinding も最終型名ではなく、Runtime が file authority を持たず execution backend へ渡す opaque handle が必要、という境界だけを残す。 + + +--- + + + +## Decision + +`authority` を未実装の API 概念として扱っていた箇所を修正した。 + +決定: +- 現段階で専用システム化されていない authority / capability を Runtime Worker creation API の field として新設しない。 +- Ticket 本体では `authority` 検証ではなく、既存の source / scope-access / visibility / persistence / retry / validation / existing type / failure を検証する方針にする。 +- Runtime が持たないものは `file operation authority` ではなく、より具体的に workspace filesystem access / tool execution scope と表現する。 +- file/tool access の制限は、既存の execution backend / tool host / scope 設定の境界を確認して実装時に接続する。 + + +--- + + + +## Decision + +Worker creation field の検証観点にある persistence の意味を修正した。 + +決定: +- 通常 Worker creation で「永続化しない」は選択肢にしない。 +- field 検証の persistence は yes/no ではなく、既存の正規 store の record / projection に何を保存し、restart 後に何を復元・診断するかを確認する `persistence/projection` とする。 +- raw handle などを保存できない場合でも、対応する durable identity / projection / diagnostic record を持つ。 +- Runtime catalog / transcript / observation / persistence initialization が Worker creation と一貫していることを受け入れ条件に残し、永続化しない通常 Worker 作成経路を禁止する。 + + +--- + + + +## Decision + +`persistence/projection` の意味を再修正した。 + +決定: +- store は任意選択の対象ではない。 +- Worker creation の保存先は既存の正規 store / projection に従う。主対象は worker-runtime fs-store、transcript store、Runtime catalog など既存 contract で決まるもの。 +- field 検証では store を選ぶのではなく、既存の正規 store のどの record / projection に何を保存し、restart 後に何を復元・診断するかを確認する。 + + +--- + + + +## Decision + +現在実装に存在する Worker creation / launch 関連 field を調査し、`artifacts/api-field-audit.md` に記録した。 + +検証した主な対象: +- Runtime `CreateWorkerRequest` の `intent` / `profile` / `config_bundle` / `requested_capabilities` / `workspace_refs` / `mount_refs`。 +- Browser-facing `WorkerSpawnRequest` の `intent` / `requested_worker_name` / `acceptance` / `profile` / `config_bundle` / `requested_capabilities`。 +- ConfigBundle sync/store/digest の現行 contract。 +- protocol `Segment` と Runtime `WorkerInput` / transcript の現行差分。 +- execution backend spawn request と per-worker cwd/scope boundary の不在。 +- worker-runtime fs-store / worker snapshot / transcript persistence と現在の create/spawn 順序。 + +主な結論: +- 未検証 field を API 案として固定しない。 +- 現行 Runtime `CreateWorkerRequest` の `intent` / `requested_capabilities` / `workspace_refs` / `mount_refs` は canonical Runtime create request には残さない。 +- Browser-facing `config_bundle` / `requested_capabilities` は Runtime create にそのまま流さない。 +- `ExecutionBindingRef` は現行実装に存在しないため、最終 field として固定しない。 +- initial input を `Vec` に寄せる方針は妥当だが、現行 Runtime input/transcript は String なので field だけ先に固定しない。 + + +--- + + + +## Intake summary + +Marked ready by `yoi ticket state`. + +--- + + + +## State changed + +Marked ready by `yoi ticket state`. + + +---