10 KiB
| title | state | created_at | updated_at | assignee | queued_by | queued_at |
|---|---|---|---|---|---|---|
| Workspace Backendのembedded Runtimeをfs-store永続化に切り替える | inprogress | 2026-06-28T13:34:29Z | 2026-06-28T19:05:47Z | null | workspace-panel | 2026-06-28T17:12:16Z |
背景
Workspace Backend の embedded Runtime は現在、EmbeddedWorkerRuntime::new_memory_with_execution_backend(...) で memory-backed Runtime として起動している。そのため Backend を再起動すると Runtime catalog、Worker snapshot、transcript、ConfigBundle store が失われる。
worker-runtime 側には既に fs-store backed Runtime が存在する。
Runtime::with_fs_store(...)Runtime::with_fs_store_and_execution_backend(...)FsRuntimeStoreOptions { root, runtime_id, display_name, limits }
一方で Workspace Backend 側の embedded wrapper には fs-store backed constructor が無く、WorkspaceApi::new_with_execution_backend(...) は memory-backed constructor を呼んでいる。
この Ticket では、Workspace Backend embedded Runtime を worker-runtime fs-store に接続し、Backend restart 後も Runtime record と transcript projection が残るようにする。
依存関係
00001KW7726H9 Runtime Worker起動経路を正規のExecution/ConfigBundle経路に一本化するの設計に従う。- この Ticket は fs-store 接続と restart persistence を扱う。canonical create request の field 設計や旧 Pod store 削除はこの Ticket の主対象にしない。
調査済みの現状
Workspace Backend 側
crates/workspace-server/src/hosts.rsWorkspaceApi::new_with_execution_backend(...)がEmbeddedWorkerRuntime::new_memory_with_execution_backend(...)を呼んでいる。- embedded spawn path は
WorkerSpawnRequestを RuntimeCreateWorkerRequestに変換している。
crates/workspace-server/src/server.rsServerConfigはworkspace_root、database_path、host URLs などを持つ。- Runtime fs-store root はまだ持っていない。
crates/workspace-server/src/main.rsWorkspaceIdentity::load_or_init(...)で workspace_id は取得済み。- 現状の
ServerConfig::local_dev(...)には Runtime store root が渡されていない。
crates/workspace-server/Cargo.tomlworker-runtimedependency はfeatures = ["ws-server"]。- fs-store を使うには
fs-storefeature も有効化する必要がある。
worker-runtime 側
crates/worker-runtime/src/runtime.rsRuntime::with_fs_store_and_execution_backend(options, backend)が存在する。- persisted state restore 時、Worker の live execution handle は復元せず
WorkerExecutionStatus::unconnected()/execution_handle: Noneになる。
crates/worker-runtime/src/fs_store.rs- store root 配下に runtime_id 別の directory を作る。
- runtime snapshot、worker snapshot、events、transcript entry を保存する。
crates/worker-runtime/src/config_bundle.rsConfigBundleはmetadata.idとmetadata.digestを持つ。- fs-store backed Runtime の persisted runtime state に ConfigBundle store も含まれる。
目的
- Workspace Backend embedded Runtime を memory-backed から fs-store backed に切り替える。
- Backend restart 後に Runtime catalog / Worker snapshot / transcript / ConfigBundle store が復元される。
- live execution handle は再起動で復元できないものとして扱い、connected Worker のように見せない。
- Runtime store root は Browser-facing API に出さない。
.yoi/ticketsなど project record と Runtime local state を混ぜない。
実装方針
1. workspace-server で worker-runtime fs-store feature を有効化する
crates/workspace-server/Cargo.toml の worker-runtime dependency に fs-store feature を追加する。
worker-runtime = { workspace = true, features = ["ws-server", "fs-store"] }
これにより Runtime::with_fs_store_and_execution_backend(...) と FsRuntimeStoreOptions を Workspace Backend から使えるようにする。
2. Runtime store root を ServerConfig に持たせる
ServerConfig に embedded Runtime 用の store root を追加する。
候補名:
pub embedded_runtime_store_root: PathBuf
決定事項:
- store root は Backend local state であり、Browser-facing API に出さない。
- store root は
.yoi/tickets配下に置かない。 - tests は temp dir を明示的に渡す。
- CLI/default path は
WorkspaceIdentity.workspace_idを使って workspace ごとに衝突しない path にする。
推奨 default:
<YOI_DATA_DIR or YOI_HOME or ~/.yoi>/workspace-server/<workspace_id>/worker-runtime
workspace-server crate が manifest::paths::data_dir() を使えない場合は、実装時に manifest dependency を追加するか、main.rs で default を解決して ServerConfig に注入する。workspace root 直下の git-tracked project record と混ぜないことを優先する。
3. EmbeddedWorkerRuntime に fs-store constructor を追加する
EmbeddedWorkerRuntime に fs-store backed constructor を追加する。
候補名:
EmbeddedWorkerRuntime::new_fs_store_with_execution_backend(...)
この constructor は内部で次を呼ぶ。
Runtime::with_fs_store_and_execution_backend(
FsRuntimeStoreOptions {
root: embedded_runtime_store_root,
runtime_id: embedded_runtime_id,
display_name,
limits,
},
execution_backend,
)
runtime_id は embedded Runtime として安定した値にする。
- 既存の
EmbeddedWorkerRuntime::runtime_id()/ embedded Runtime id 方針がある場合はそれに従う。 - workspace ごとの identity は store root 側で分けるため、runtime_id に raw workspace path を入れない。
- runtime_id が変わると既存 fs-store を復元できないため、restart 間で安定させる。
4. WorkspaceApi の constructor を fs-store backed に切り替える
WorkspaceApi::new_with_execution_backend(...) は memory constructor ではなく、fs-store constructor を呼ぶ。
変更前の趣旨:
EmbeddedWorkerRuntime::new_memory_with_execution_backend(...)
変更後の趣旨:
EmbeddedWorkerRuntime::new_fs_store_with_execution_backend(...)
この変更により、Workspace Backend 経由の embedded Runtime catalog / worker snapshot / transcript / ConfigBundle が fs-store に保存される。
5. restart 後の execution status を明示する
worker-runtime の restore は現状、Worker の live execution handle を復元せず WorkerExecutionStatus::unconnected() にする。これは正しい前提として扱う。
この Ticket では次を確認・必要に応じて補強する。
- Backend restart 後の Worker は catalog / transcript 上は復元される。
- live execution handle は復元済みのように見せない。
- input-capable として扱えない場合は
unconnected/ stale execution mapping / typed diagnostic として表示・API 応答される。 - restart 後に同じ WorkerId を使って fake response を生成しない。
6. ConfigBundle store の復元を確認する
fs-store backed Runtime は persisted runtime state に ConfigBundle store を持つ。Workspace Backend 側で embedded Runtime を fs-store に切り替えた後、Backend restart で ConfigBundle が失われないことを test で確認する。
この Ticket では ConfigBundle create API の再設計は行わない。00001KW7726H9 の canonical create 設計と矛盾しないよう、現行 store の復元だけを確認する。
Test plan
Focused tests を yoi-workspace-server 側に追加する。
embedded Runtime fs-store restore
- temp dir を store root として
WorkspaceApi/ embedded Runtime を起動する。 - Runtime に ConfigBundle を store する。
- Worker を作成し、transcript に entry を追加する。
- WorkspaceApi / Runtime を drop する。
- 同じ store root で WorkspaceApi / Runtime を再作成する。
- Runtime catalog に同じ Worker が復元されることを確認する。
- transcript entry が復元されることを確認する。
- ConfigBundle が復元されることを確認する。
- execution status が live connected として偽装されていないことを確認する。
memory-backed bypass absence
- Workspace Backend の production constructor が
new_memory_with_execution_backend(...)を呼ばないことを test または grep-resistant な unit test で確認する。 - memory-backed Runtime は test helper / explicit in-memory constructor に限定する。
store root isolation
- store root が
ServerConfigから注入されることを確認する。 - Browser-facing API response に store root が出ないことを確認する。
.yoi/tickets配下を Runtime fs-store root にしないことを確認する。
受け入れ条件
crates/workspace-serverがworker-runtimeのfs-storefeature を有効化している。ServerConfigが embedded Runtime store root を持ち、Workspace Backend 起動時に明示的に渡される。- CLI/default path が user data 配下の workspace_id 別 Runtime store root を使う。
EmbeddedWorkerRuntimeに fs-store backed constructor が追加されている。- Workspace Backend の通常 constructor が
EmbeddedWorkerRuntime::new_memory_with_execution_backend(...)を呼ばない。 - embedded Runtime が
Runtime::with_fs_store_and_execution_backend(...)を通って起動する。 - Backend restart 後に Runtime catalog / Worker snapshot / transcript / ConfigBundle store が復元される。
- restart 後の live execution handle は復元済みとして扱われず、unconnected / stale diagnostic として扱われる。
- Browser-facing API に Runtime store root / raw path / execution handle が漏れない。
- Focused tests が embedded fs-store restore、ConfigBundle restore、transcript restore、execution unconnected restore、memory-backed bypass absence を確認する。
cargo test -p yoi-workspace-serverが通る。cargo test -p worker-runtime --features ws-server,fs-storeが通る。cargo check -p yoiが通る。git diff --checkが通る。nix build .#yoi --no-linkが通る。
対象外
- canonical Runtime Worker create request の field 確定。
- per-worker cwd / tool scope の新 API。
- remote Runtime execution provisioning。
- live execution handle の restart 後自動再接続。
- 旧 Pod store / pod-registry の削除。