yoi/.yoi/tickets/00001KWY8EHEJ/thread.md

355 lines
22 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!-- event: create author: "yoi ticket" at: 2026-07-07T12:22:06Z -->
## 作成
LocalTicketBackend によって作成されました。
---
<!-- event: intake_summary author: hare at: 2026-07-07T12:26:36Z -->
## Intake summary
Marked ready by `yoi ticket state`.
---
<!-- event: state_changed author: "yoi ticket" at: 2026-07-07T12:26:36Z from: planning to: ready reason: cli_state field: state -->
## State changed
Marked ready by `yoi ticket state`.
---
<!-- event: state_changed author: workspace-panel at: 2026-07-07T13:40:23Z from: ready to: queued reason: queued field: state -->
## State changed
Ticket を `workspace-panel` が queued にしました。
---
<!-- event: decision author: orchestrator at: 2026-07-07T13:41:22Z -->
## Decision
Routing decision: implementation_ready
Reason:
- Ticket は Browser-managed working directory の pre-allocate 方式、API/UI/spawn 接続、`relative_cwd` validation、path leak invariant、cleanup policy の v0 方針を具体化している。
- 先行 Runtime-side materializer / Repository registry / workspace-id scoped API が orchestration branch に統合済みで、Browser-facing API を `/api/w/<workspace-id>/...` に追加する実装基盤がある。
- raw host path / internal materialization request を Browser payload に露出しない binding invariant が明確で、Worker spawn は allocation id + safe `relative_cwd` で接続する要求になっている。
- typed relation blocker は 0 件、OrchestrationPlan record は 0 件。
- queued notification は human authorized routing であり、今回の routing acceptance 後にのみ implementation side effect へ進める。
Evidence checked:
- Ticket body / thread / artifacts。
- `TicketRelationQuery(00001KWY8EHEJ)`: 0 件。
- `TicketOrchestrationPlanQuery(00001KWY8EHEJ)`: 0 件。
- Orchestrator worktree git status: clean on `orchestration`
- queued Ticket 一覧: この Ticket 1件のみ。inprogress は 0 件。
- visible Pods: previous child Pods が idle で残っているが、`StopPod` 不使用方針のため停止せず、新規 unique Pod を使う。capacity blocker ではない。
- `TicketDoctor`: 0 errors / 既存 diagnostics のみ。
- Bounded code map: `crates/worker-runtime/src/{catalog.rs,working_directory.rs,runtime.rs,worker_backend.rs,http_server.rs}`, `crates/workspace-server/src/{server.rs,hosts.rs,repositories.rs,config.rs}`, `web/workspace/src/lib/workspace-sidebar/**`, scoped routes/API under `web/workspace/src/routes/w/[workspaceId]/**`
IntentPacket:
Intent:
- Browser-facing API から configured repository + selector + policy により working directory を事前作成し、Browser には allocation id と safe summary だけを返す。
- Worker launch UI/API で作成済み working directory を選択し、Worker spawn 時に allocation id と safe `relative_cwd` を Runtime materializer / Worker spawn boundary に接続する。
- Worker detail/list に working directory の safe summary を表示し、cleanup policy と手動 cleanup 操作の v0 方針を実装/明示する。
Binding decisions / invariants:
- Browser から raw host path、backend-private absolute path、raw `WorkingDirectoryRequest`、internal runtime path を送らせない/返さない。
- pre-allocate 方式を優先する。単発 spawn request だけで暗黙 materialize する経路は後回し。
- v0 materializer は existing local Git detached worktree 方針を使う。remote clone/cache、dirty source inclusion は扱わない。
- Worker spawn は作成済み allocation id と任意の `relative_cwd` を選ぶ。
- `relative_cwd` は materialized workspace root からの相対 path とし、absolute path、`..` escape、symlink escape、存在しない/不正 directory を拒否する。
- Browser-facing status/detail/list は safe summary のみ。内部 path / cleanup target raw path は露出しない。
- cleanup policy と manual cleanup operation は v0 の範囲で明示し、cleanup diagnostics は typed/sanitized にする。
- Workspace-scoped Browser API は `/api/w/<workspace-id>/...` を使い、Runtime `/v1/...` API を Browser contract として広げない。
Requirements / acceptance criteria:
- `POST /api/w/<workspace-id>/working-directories` 相当で configured repository + selector から working directory を作成できる。
- `GET /api/w/<workspace-id>/working-directories` 相当で safe summary list を取得できる。
- 必要なら detail / cleanup endpoint を scoped API に追加し、safe summary / typed diagnostic を返す。
- Worker launch UI で working directory を選択でき、raw path ではなく safe id/selector 情報を送る。
- Worker spawn 時に選択 allocation が Runtime の materialized workspace に接続され、Worker cwd/scope は materialized worktree 配下になる。
- invalid repository / dirty unsupported / remote unsupported / invalid `relative_cwd` は typed diagnostic。
- Worker detail/list に working directory safe summary を表示する。
- frontend check/test、workspace-server tests、`yoi ticket doctor`、`nix build .#yoi` を通す。
Implementation latitude:
- Allocation store の所在/形式、API endpoint 名、UI placement、cleanup status 名、test helper は既存 workspace-server / worker-runtime / web style に合わせてよい。
- v0 では Runtime materializer の既存 allocation evidence を再利用し、Browser-managed allocation registry は必要最小限でよい。
- Worker launch UI は既存 New Worker form に working directory select / create link / refresh を追加する形でよい。
- `relative_cwd` は empty/`.` を workspace root と扱ってよい。
Escalate if:
- raw host path や internal runtime path を Browser contract に出さないと満たせない場合。
- remote clone/cache, dirty snapshot/apply, credential resolution, multi-repository mount, strong sandbox policy, or cross-Runtime allocation migration が必要になる場合。
- pre-allocate 方式でなく implicit one-shot materialization を主経路にする必要が出た場合。
Validation:
- `cd web/workspace && deno task check && deno task test`
- `cargo test -p yoi-workspace-server`
- `cargo test -p worker-runtime --features ws-server,fs-store`
- `cargo check -p yoi`
- `git diff --check`
- `yoi ticket doctor`
- `nix build .#yoi --no-link`Ticket acceptance に含まれるため実行する。実行不能なら理由を implementation report に明記する)
Current code map:
- Runtime working directory: `crates/worker-runtime/src/catalog.rs`, `working_directory.rs`, `runtime.rs`, `worker_backend.rs`, `http_server.rs`
- Workspace Backend host/API: `crates/workspace-server/src/server.rs`, `hosts.rs`, `repositories.rs`, `config.rs`
- Worker launch UI and API helpers: `web/workspace/src/lib/workspace-sidebar/WorkersNavSection.svelte`, worker launch model/tests, workspace API helper, scoped route layout。
- Worker detail/console: scoped worker console route and runtime worker detail/list projections。
Critical risks / reviewer focus:
- Browser payload/response must not expose raw path or raw internal materialization request。
- `allocation_id` must not become ambient authority across mismatched workspace/runtime/repository contexts。
- `relative_cwd` validation must handle absolute paths, `..`, symlink escape, missing/non-directory paths。
- cleanup operation must not delete outside materialized allocation root。
- Worker spawn should use existing materialized allocation rather than creating hidden implicit workspaces as the primary flow。
- Runtime `/v1` remains internal/trusted; Browser uses scoped workspace API。
---
<!-- event: state_changed author: orchestrator at: 2026-07-07T13:41:43Z from: queued to: inprogress reason: routing_acceptance_implementation_ready field: state -->
## State changed
Queued acceptance recorded after Workspace Dashboard Queue notification authorized Orchestrator routing.
Checked context:
- Ticket body / thread / artifacts。
- `TicketRelationQuery(00001KWY8EHEJ)`: blocking relation 0 件。
- `TicketOrchestrationPlanQuery(00001KWY8EHEJ)`: prior record 0 件。今回 accepted_plan を記録済み。
- Orchestrator worktree git status: clean on `orchestration`
- queued Ticket はこの Ticket 1件のみ。inprogress は 0 件。
- visible Pods / TicketDoctor / bounded code map を確認。
Acceptance basis:
- concrete missing decision / information は残っていない。
- Ticket の scope は Browser-managed pre-allocated working directory と Worker spawn 接続に閉じており、remote clone/cache, dirty source inclusion, raw path Browser contract, implicit one-shot materialization は非目標/後回しとして明確。
- side effect はこの `queued -> inprogress` acceptance 後に、worktree-workflow に沿って implementation worktree を作成してから開始する。
---
<!-- event: implementation_report author: orchestrator at: 2026-07-07T13:42:50Z -->
## Implementation report
Implementation routing update:
- Worktree-workflow に従い implementation worktree を作成した。
- Worktree: `/home/hare/Projects/yoi/.worktree/00001KWY8EHEJ-browser-working-directories`
- Branch: `work/00001KWY8EHEJ-browser-working-directories`
- Worktree には tracked `.yoi` project records が見えている。
- `.yoi/memory` / `.yoi/runtime` / `.yoi/log` / `.yoi/logs` / `.yoi/local` / `.yoi/*.lock` / `.yoi/*secret*` は作成直後に存在しないことを確認した。
- Sibling Coder Pod `yoi-coder-00001KWY8EHEJ-browser-execws` を起動した。
- Scope policy: runtime workspace root は read-only、implementation worktree は write 可。Coder task では root/original workspace での read/write/validation/git operation を禁止し、この implementation worktree だけを作業対象に指定した。
- 完了後は diff / validation evidence を Orchestrator が確認し、別 sibling Reviewer Pod に read-only review を依頼する。`StopPod` は既知の不具合があるため使用しない。
---
<!-- event: implementation_report author: orchestrator at: 2026-07-07T14:23:27Z -->
## Implementation report
Implementation progress report:
- Coder Pod completed implementation and committed `684b19e8 feat: add browser working directories` on branch `work/00001KWY8EHEJ-browser-working-directories`.
- Worktree status was clean after commit.
- Changed files include:
- `crates/worker-runtime/src/{catalog.rs,working_directory.rs,http_server.rs,runtime.rs,worker_backend.rs}`
- `crates/workspace-server/src/{companion.rs,hosts.rs,server.rs}`
- `web/workspace/src/lib/workspace-sidebar/{WorkersNavSection.svelte,types.ts,worker-launch.ts,worker-launch.test.ts}`
- Implementation summary:
- Runtime-side preallocated working directory create/list/detail/cleanup and allocation binding at Worker spawn。
- `relative_cwd` validation rejects absolute paths, `..`, missing paths, files, and symlink escapes。
- scoped Browser API: `POST/GET /api/w/<workspace-id>/working-directories`, detail, and cleanup。
- Browser API uses configured `repository_id` + selector + policy, not raw paths/internal `WorkingDirectoryRequest`
- Browser responses expose safe summaries only。
- Worker spawn uses selected allocation id plus optional safe `relative_cwd`
- Worker list/detail projections include working directory safe summary。
- Workspace UI Worker launch flow can select existing allocations or create a new allocation before launch。
- Orchestrator reran validation in the implementation worktree:
- `git diff --check`: pass
- `cd web/workspace && deno task check`: pass0 errors / 0 warnings
- `cd web/workspace && deno task test`: pass17 tests
- `cargo test -p yoi-workspace-server`: pass66 lib tests + 2 main tests
- `cargo test -p worker-runtime --features ws-server,fs-store`: pass36 lib tests + 5 main tests + doc tests
- `cargo check -p yoi`: pass
- `yoi ticket doctor`: ok
- `nix build .#yoi --no-link`: pass
- External review will be requested via a read-only sibling Reviewer Pod. `StopPod` は使わない。
---
<!-- event: review author: reviewer at: 2026-07-07T14:36:39Z status: request_changes -->
## Review: request changes
External review result: request_changes
Blocker:
1. Invalid `relative_cwd` is rejected internally, but the Browser-facing Worker spawn API does not return the required typed working directory diagnostic。
- Ticket acceptance requires invalid `relative_cwd` to be rejected as a typed diagnostic。
- Materializer has specific typed codes:
- `working_directory_relative_cwd_invalid`
- `working_directory_relative_cwd_unavailable`
- `working_directory_relative_cwd_escape_rejected`
- `crates/worker-runtime/src/worker_backend.rs` converts `WorkingDirectoryDiagnostic` to a plain string in `WorkerExecutionResult::rejected(...)`
- Workspace host/API then maps this to generic diagnostics/error codes, including generic embedded execution rejection and generic `workspace_worker_create_failed`
- Result: Browser caller submitting invalid `relative_cwd` gets a generic worker-create/runtime rejection rather than a typed `working_directory_relative_cwd_*` diagnostic。
- Browser/scoped API-level tests cover materializer bind validation but not the API rejection shape。
Required fix:
- Preserve/propagate `WorkingDirectoryDiagnostic.code` through Worker spawn, or prevalidate allocation + `relative_cwd` in the Workspace API and return that typed diagnostic directly。
- Add a scoped Browser API test for at least one invalid `relative_cwd` that asserts the typed `working_directory_relative_cwd_*` diagnostic is returned。
Non-blocking follow-ups:
- The implementation otherwise appears aligned with the pre-allocation design: scoped `/api/w/<workspace-id>/working-directories` routes exist, Browser create payload uses configured `repository_id`/selector/policy rather than raw `WorkingDirectoryRequest`, summaries avoid raw paths, UI explicitly creates/selects allocations, and cleanup is bounded to the allocation root。
Validation reviewed:
- Reviewer read Ticket item/thread, inspected `git show --stat --check 684b19e8` / `git show --name-only 684b19e8`, and reviewed Runtime, Workspace API/host, and frontend launch files。
- Reviewer did not rerun full validation; Orchestrator-provided validation was used as passing evidence。
---
<!-- event: implementation_report author: orchestrator at: 2026-07-07T14:51:28Z -->
## Implementation report
Review-fix implementation report:
- Coder Pod completed requested changes and committed follow-up `9adb0fae fix: preserve working directory cwd diagnostics` on branch `work/00001KWY8EHEJ-browser-working-directories`.
- Worktree status was clean after commit.
- Fix summary:
- Browser Worker spawn now prevalidates selected working directory allocation + `relative_cwd` through the materializer before spawn。
- `WorkingDirectoryDiagnostic` is mapped directly into Browser API error diagnostics, preserving typed codes such as `working_directory_relative_cwd_invalid`, `working_directory_relative_cwd_unavailable`, and `working_directory_relative_cwd_escape_rejected`
- Added a scoped Browser API regression test asserting invalid `relative_cwd: "../escape"` returns typed `working_directory_relative_cwd_invalid` diagnostic。
- Existing scoped working directory routes, safe summaries, explicit UI allocation flow, and bounded cleanup behavior remain unchanged。
- Orchestrator reran validation in the implementation worktree:
- `git diff --check`: pass
- `cd web/workspace && deno task check`: pass0 errors / 0 warnings
- `cd web/workspace && deno task test`: pass17 tests
- `cargo test -p yoi-workspace-server`: pass67 lib tests + 2 main tests
- `cargo test -p worker-runtime --features ws-server,fs-store`: pass36 lib tests + 5 main tests + doc tests
- `cargo check -p yoi`: pass
- `yoi ticket doctor`: ok
- `nix build .#yoi --no-link`: pass
- Requesting follow-up external review against `684b19e8..9adb0fae` and full combined implementation。
---
<!-- event: review author: reviewer at: 2026-07-07T14:56:52Z status: approve -->
## Review: approve
External follow-up review result: approve
Blockers: none.
Evidence reviewed in implementation worktree only:
- Ticket records: `.yoi/tickets/00001KWY8EHEJ/item.md`, `thread.md`, and orchestration artifact。
- Fix diff: `9adb0fae` stat/check and `684b19e8..9adb0fae` focused diff for `crates/workspace-server/src/server.rs`
- Relevant files: `workspace-server/src/server.rs`, `worker-runtime/src/working_directory.rs`, `worker_backend.rs`, scoped host/runtime API pieces, and worker launch UI/model/tests。
Findings:
- Prior blocker is resolved. Browser Worker spawn now pre-validates `working_directory.relative_cwd` through the working directory materializer before calling the runtime spawn path, and maps `WorkingDirectoryError` into API diagnostics via `working_directory_api_error`
- Invalid Browser spawn `relative_cwd` now returns typed diagnostics with the expected codes, covered by the added test asserting `working_directory_relative_cwd_invalid` appears both in diagnostics and message。
- Browser-facing spawn payload remains allocation-based (`allocation_id` + optional `relative_cwd`) rather than exposing raw `WorkingDirectoryRequest` or host paths. UI request construction sends allocation id and relative cwd only。
- Scoped create/list/detail/cleanup routes remain under `/api/w/:workspace_id/working-directories`; worker creation uses the scoped workspace API path from the Browser UI。
- Cleanup remains bounded to the allocation root: cleanup re-derives allocation root from the allocation id/root, canonicalizes workspace root, rejects escape, and removes only the recorded workspace root。
- Runtime/internal trusted path still performs canonical materialization/bind at Worker launch, while Browser gets a safer scoped allocation API。
- Reported validation was comprehensive and green; reviewer did not rerun tests as this was a read-only follow-up review。
Non-blocking follow-ups: none identified。
No merge-blocking issues found.
---
<!-- event: state_changed author: orchestrator at: 2026-07-07T14:58:18Z from: inprogress to: done reason: merged_validated_review_approved field: state -->
## State changed
Merge/validation acceptance:
- Follow-up external review approved the implementation after blocker fix。
- Implementation branch `work/00001KWY8EHEJ-browser-working-directories` was merged into the orchestration branch with merge commit `b52986e5 merge: browser working directories`
- Final validation in Orchestrator worktree passed:
- `git diff --check`: pass
- `cd web/workspace && deno task check`: pass0 errors / 0 warnings
- `cd web/workspace && deno task test`: pass17 tests
- `cargo test -p yoi-workspace-server`: pass67 lib tests + 2 main tests
- `cargo test -p worker-runtime --features ws-server,fs-store`: pass36 lib tests + 5 main tests + doc tests
- `cargo check -p yoi`: pass
- `yoi ticket doctor`: ok
- `nix build .#yoi --no-link`: pass
Implementation commits:
- `684b19e8 feat: add browser working directories`
- `9adb0fae fix: preserve working directory cwd diagnostics`
No merge-blocking issues remain.
---
<!-- event: state_changed author: hare at: 2026-07-07T14:58:35Z from: done to: closed reason: closed field: state -->
## State changed
Ticket を closed にしました。
---
<!-- event: close author: hare at: 2026-07-07T14:58:35Z status: closed -->
## 完了
完了。
実装内容:
- Browser-managed working directory API を scoped Workspace API に追加した。
- `POST /api/w/<workspace-id>/working-directories`
- `GET /api/w/<workspace-id>/working-directories`
- detail / cleanup endpoint
- Browser create payload は configured `repository_id` / selector / policy を使い、raw host path / raw internal `WorkingDirectoryRequest` / internal runtime path を受け取らないようにした。
- Browser response は allocation id、repository id、selector/commit evidence、status、cleanup policy など safe summary のみを返すようにした。
- Worker launch UI で working directory を create/select できるようにした。
- Worker spawn は selected allocation id + optional `relative_cwd` を使い、Runtime materialized workspace に接続するようにした。
- `relative_cwd` は materialized root 相対として検証し、absolute path、`..` escape、symlink escape、nonexistent / non-directory を拒否するようにした。
- invalid `relative_cwd` は Browser-facing API で typed `working_directory_relative_cwd_*` diagnostic として返るようにした。
- Worker list/detail に working directory safe summary を含めた。
- cleanup は allocation root に bounded され、typed/sanitized diagnostic を返すようにした。
- Focused backend/runtime/web tests を追加した。
主な commit / merge:
- implementation: `684b19e8 feat: add browser working directories`
- review fix: `9adb0fae fix: preserve working directory cwd diagnostics`
- merge into orchestration: `b52986e5 merge: browser working directories`
Review:
- 初回 external review は request_changes。
- follow-up external review は approve。merge-blocking issue なし。
Final validation in Orchestrator worktree:
- `git diff --check`: pass
- `cd web/workspace && deno task check`: pass0 errors / 0 warnings
- `cd web/workspace && deno task test`: pass17 tests
- `cargo test -p yoi-workspace-server`: pass67 lib tests + 2 main tests
- `cargo test -p worker-runtime --features ws-server,fs-store`: pass36 lib tests + 5 main tests + doc tests
- `cargo check -p yoi`: pass
- `yoi ticket doctor`: ok
- `nix build .#yoi --no-link`: pass
---