merge: backend resource and profile settings

This commit is contained in:
2026-07-08 23:11:54 +09:00
29 changed files with 4403 additions and 74 deletions
@@ -0,0 +1,3 @@
{"id":"orch-plan-20260708-104512-1","ticket_id":"00001KX0DSMPT","kind":"after","related_ticket":"00001KX0G06VA","note":"This Ticket is queued while `00001KX0G06VA` is inprogress because both touch Workspace/Backend profile/resource launch surfaces (`workspace-server` settings/API/hosts/server and profile archive/resource fetch integration). Sequence after the active resource-fetch implementation to avoid conflicting public API and ProfileSourceArchive authority-boundary changes.","author":"orchestrator","at":"2026-07-08T10:45:12Z"}
{"id":"orch-plan-20260708-104530-2","ticket_id":"00001KX0DSMPT","kind":"waiting_capacity_note","note":"Queue review after Dashboard authorization. The declared dependency `00001KWZ5KERY` is closed, so that blocker is resolved. However `00001KX0G06VA` is currently inprogress on branch `work/00001KX0G06VA-resource-fetch-api` and changes the same ProfileSourceArchive/resource/workspace-server launch API surfaces this Ticket needs to build on. Leave this Ticket queued until the active resource-fetch branch is reviewed/merged or its API shape is otherwise decided; then re-route/start from the updated orchestration branch.","author":"orchestrator","at":"2026-07-08T10:45:30Z"}
{"id":"orch-plan-20260708-115622-3","ticket_id":"00001KX0DSMPT","kind":"accepted_plan","accepted_plan":{"summary":"`00001KWZ5KERY` と `00001KX0G06VA` が closed/merged になり、previous waiting reason は解除された。Workspace/Profile editing API/pages を updated orchestration branch から実装開始する。","branch":"work/00001KX0DSMPT-workspace-profile-settings","worktree":"/home/hare/Projects/yoi/.worktree/00001KX0DSMPT-workspace-profile-settings","role_plan":"単一 sibling Coder Pod に implementation worktree を委譲し、Workspace/Profile settings scoped APIs、safe Profile registry/source read-write model、settings UI pages、Backend discovery invalidation、launch candidate integration、diagnostic/redaction tests を実装する。完了後、別 sibling Reviewer Pod で Ticket IntentPacket / ProfileSourceArchive/resource-fetch authority boundary / acceptance criteria に照らして read-only review する。"},"author":"orchestrator","at":"2026-07-08T11:56:22Z"}
+2 -2
View File
@@ -1,8 +1,8 @@
---
title: 'Add Workspace settings API and pages for Workspace/Profile editing'
state: 'queued'
state: 'closed'
created_at: '2026-07-08T08:34:01Z'
updated_at: '2026-07-08T10:44:13Z'
updated_at: '2026-07-08T13:20:27Z'
assignee: null
queued_by: 'workspace-panel'
queued_at: '2026-07-08T10:44:13Z'
+33
View File
@@ -0,0 +1,33 @@
完了。
実装内容:
- Workspace/Profile settings scoped API を追加した。
- Workspace metadata read/update と safe identity/source summaries を扱う Settings API を追加した。
- Profile registry/source read/update API を追加し、create/update/delete と revision/etag-style optimistic checks を実装した。
- Backend profile settings model に safe source ids/display paths、Decodal/ProfileSourceArchive validation、selector uniqueness、path/symlink escape protection、source size checks、typed diagnostics を追加した。
- Profile updates 後に Backend profile discovery / validation / launch options を再構築し、Worker launch profile candidates と Settings profile list が同じ discovery result を使うようにした。
- invalid project profile は relevant profile summary に diagnostics を付与し、Worker launch candidates から除外し、candidate validation でも reject するようにした。
- Browser-facing responses/UI から host absolute paths、secret values、Runtime endpoints/tokens、socket/session paths、runtime-local store paths、archive content/digest、raw resource handles、backend-private paths を出さないようにした。
- Settings UI に Workspace overview と Profile list/source editor surface を追加した。
- Focused backend/web tests を追加/強化した。
主な commit / merge:
- implementation: `3eefd333 feat: add workspace profile settings`
- review fix: `0c2ca1ea fix: harden profile settings validation`
- merge into orchestration: `0bf3638c merge: workspace profile settings`
Review:
- 初回 external review は request_changes。
- follow-up external review は approve。merge-blocking issue なし。
Final validation in Orchestrator worktree:
- `git diff --check`: pass
- `cargo test -p yoi-workspace-server`: pass91 lib tests + 2 main tests
- `cargo check -p yoi`: pass
- `cd web/workspace && deno task check`: pass0 errors / 0 warnings
- `cd web/workspace && deno task test`: pass17 tests
- `yoi ticket doctor`: ok
- `nix build .#yoi --no-link`: pass
補足:
- implementation branch merge 時に Ticket record conflict が発生したため、Orchestrator 側の Ticket item/thread を保持して解決した。product/code changes は merge 済み。
+348
View File
@@ -30,4 +30,352 @@ Marked ready by `yoi ticket state`.
Ticket を `workspace-panel` が queued にしました。
---
<!-- event: decision author: orchestrator at: 2026-07-08T10:45:48Z -->
## Decision
Routing decision: blocked_by_dependency_or_missing_authority
Reason:
- Declared dependency `00001KWZ5KERY` is now closed, so the original Decodal/ProfileSourceArchive prerequisite is satisfied。
- However `00001KX0G06VA` is currently `inprogress` on branch `work/00001KX0G06VA-resource-fetch-api`
- This Tickets Workspace/Profile editing API and pages need to build on the same profile/resource/workspace-server launch surfaces that `00001KX0G06VA` is actively changingProfileSourceArchive resource handling, workspace-server settings/API/hosts/server, Browser-facing profile launch configuration)。
- Starting this Ticket now would create a high-conflict parallel branch and risks designing Profile editing against the wrong resource-fetch/public API boundary。
- Therefore this routing pass leaves the Ticket queued and does not record `queued -> inprogress`, create a worktree, or spawn role Pods。
Evidence checked:
- Ticket body / thread / artifacts。
- `TicketRelationQuery(00001KX0DSMPT)`: depends_on `00001KWZ5KERY`; target is closed。
- `TicketOrchestrationPlanQuery(00001KX0DSMPT)`: prior record 0 件だったため、今回 `after 00001KX0G06VA` と waiting-capacity note を記録。
- `TicketList`: queued はこの Ticket 1件、inprogress は `00001KX0G06VA` 1件。
- Orchestrator worktree git status: clean on `orchestration`
Next action:
- `00001KX0G06VA` の implementation/review/merge outcome を待つ。
- resource-fetch API shape が merge されたら、この Ticket を再 routing し、updated orchestration branch から start する。
Escalate if:
- 人間が `00001KX0G06VA` を中断してこの Ticket を先に実装する、または両者を同一 combined worktree で統合実装する方針に切り替えたい場合。
---
<!-- event: decision author: orchestrator at: 2026-07-08T11:56:03Z -->
## Decision
Routing decision: implementation_ready
Reason:
- Previous waiting reason is resolved: `00001KX0G06VA` is now merged/validated/closed, so the ProfileSourceArchive resource-fetch API shape this Ticket depends on is stable enough to build against。
- Declared dependency `00001KWZ5KERY` is also closed, so Decodal Profile source model / ProfileSourceArchive boundary is available。
- Ticket body gives concrete Workspace/Profile settings API, read/write source model, UI routes, diagnostics, redaction invariants, and validation criteria。
- typed relation blocker is resolved (`depends_on 00001KWZ5KERY` target closed); no active inprogress Ticket remains。
- The user requested sequential consumption once no blocker remains, and the Dashboard queue authorization is already present。
Evidence checked:
- Ticket body / thread / artifacts。
- `TicketRelationQuery(00001KX0DSMPT)`: outgoing `depends_on 00001KWZ5KERY`; target is closed。
- `TicketOrchestrationPlanQuery(00001KX0DSMPT)`: prior `after 00001KX0G06VA` / waiting note; `00001KX0G06VA` is now closed with merge commit `01f94b75` and close commit `a645ee5b`
- Orchestrator worktree git status: clean on `orchestration`
- queued Ticket 一覧: this Ticket 1件。inprogress は 0 件。
IntentPacket:
Intent:
- Workspace-scoped Browser API and pages for Workspace metadata and Profile registry/source editing, using Backend as the authority and the Decodal/ProfileSourceArchive model already merged。
- Frontend should edit Profiles through safe Backend APIs, not filesystem paths, and Worker launch profile candidates should reflect updated Backend discovery/validation state。
Binding decisions / invariants:
- Workspace/Profile editing APIs live under `/api/w/<workspace-id>/settings...` or consistent scoped Workspace API paths。
- Browser-facing API/UI must not expose host absolute paths, secret values, Runtime endpoints/tokens, socket/session paths, runtime-local store paths, archive content/digest, or raw resource handles。
- Profile source references use safe ids/artifact ids/display paths rather than raw absolute paths。
- Writes must validate syntax/schema/selector uniqueness/path safety before commit and return typed diagnostics。
- Decodal/ProfileSourceArchive source model from `00001KWZ5KERY` and resource-fetch boundary from `00001KX0G06VA` are authority inputs; do not reintroduce Runtime filesystem discovery。
- Runtime direct sync is out of scope; Backend discovery/launch options invalidation is in scope。
Requirements / acceptance criteria:
- Workspace metadata read/update API works for display name and safe identity/source summaries。
- Profile registry/source read/update APIs support create/update/delete with revision/etag-style optimistic check。
- Settings UI has Workspace overview and Profile list/source editor routes under `/w/<workspace-id>/settings...`
- Profile updates re-run Backend discovery/validation and update Worker launch profile candidates。
- Duplicate selector, invalid registry schema, invalid Decodal syntax, path/symlink escape, artifact too large, and concurrent update conflict return typed diagnostics。
- Browser WorkingDirectory / Worker launch profile candidates and settings Profile list share the same Backend discovery result。
Implementation latitude:
- Endpoint naming, module boundaries, revision token shape, source/artifact id representation, UI component split, and editor implementation can follow existing workspace-server / Svelte style。
- v0 plain textarea/editor is acceptable; no heavyweight editor required。
- Imported source write support can be limited to bounded module root or deferred with typed diagnostics if not needed for core v0。
Escalate if:
- Secret value editor, multi-user auth/RBAC, Runtime direct sync, Plugin/MCP/sandbox artifact sync, Ticket/Objective/Memory editor integration, or a new Profile source semantic model beyond Decodal/ProfileSourceArchive is required。
Validation:
- `cargo test -p yoi-workspace-server`
- `cargo check -p yoi`
- `cd web/workspace && deno task check && deno task test`
- `git diff --check`
- `yoi ticket doctor`
- `nix build .#yoi --no-link`
Current code map:
- Workspace/profile settings backend: `crates/workspace-server/src/server.rs`, `hosts.rs`, `config.rs`, `resource_broker.rs`, Decodal/archive helpers。
- Profile archive/config: `crates/worker-runtime/src/profile_archive.rs`, `config_bundle.rs` for source model reference。
- Frontend settings: `web/workspace/src/routes/w/[workspaceId]/settings/**`, `web/workspace/src/lib/workspace-settings/**`, worker launch profile candidate helpers。
Critical risks / reviewer focus:
- No raw paths/secrets/runtime internals or resource handles leak to Browser。
- Profile editing updates the same Backend discovery/launch options used by Worker launch。
- Optimistic concurrency and path/symlink escape checks fail closed。
- Decodal validation is real and not only superficial string checks。
- Existing Runtime resource fetch / ProfileSourceArchive authority boundaries remain intact。
---
<!-- event: state_changed author: orchestrator at: 2026-07-08T11:56:36Z from: queued to: inprogress reason: routing_acceptance_implementation_ready field: state -->
## State changed
Queued acceptance recorded after previous waiting reason was resolved.
Checked context:
- Ticket body / thread / artifacts。
- `TicketRelationQuery(00001KX0DSMPT)`: depends_on `00001KWZ5KERY`; target is closed。
- `TicketOrchestrationPlanQuery(00001KX0DSMPT)`: prior `after 00001KX0G06VA` / waiting note を確認。`00001KX0G06VA` is now closed / merged。
- Orchestrator worktree git status: clean on `orchestration`
- queued Ticket はこの Ticket 1件のみ。inprogress は 0 件。
Acceptance basis:
- Previous blocker/waiting reason is resolved。
- concrete missing decision / information は残っていない。
- Ticket scope is Workspace/Profile settings API and pages using already-merged Decodal/ProfileSourceArchive and resource-fetch boundaries。
- side effect はこの `queued -> inprogress` acceptance 後に、worktree-workflow に沿って implementation worktree を作成してから開始する。
---
<!-- event: implementation_report author: orchestrator at: 2026-07-08T11:58:14Z -->
## Implementation report
Implementation routing update:
- Worktree-workflow に従い implementation worktree を作成した。
- Worktree: `/home/hare/Projects/yoi/.worktree/00001KX0DSMPT-workspace-profile-settings`
- Branch: `work/00001KX0DSMPT-workspace-profile-settings`
- Worktree には tracked `.yoi` project records が見えている。
- `.yoi/memory` / `.yoi/runtime` / `.yoi/log` / `.yoi/logs` / `.yoi/local` / `.yoi/*.lock` / `.yoi/*secret*` は作成直後に存在しないことを確認した。
- Sibling Coder Pod `yoi-coder-00001KX0DSMPT-profile-settings` を起動した。
- 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-08T12:03:23Z -->
## Implementation report
Implementation routing recovery note:
- Initial Coder Pod `yoi-coder-00001KX0DSMPT-profile-settings` failed its first turn with provider `context_length_exceeded` before producing implementation output。
- Ticket remains `inprogress`; worktree/branch already exist and are clean at creation baseline。
- Recovery plan: avoid `StopPod` and retry with a fresh minimal Coder task that reads the Ticket records from the worktree instead of embedding the full IntentPacket in the prompt. If scope registry prevents a fresh Pod, fallback is to use the existing Pod with a much smaller instruction or ask for human cleanup/authority。
---
<!-- event: implementation_report author: orchestrator at: 2026-07-08T12:40:07Z -->
## Implementation report
Implementation progress report:
- Recovery Coder Pod `yoi-coder2-00001KX0DSMPT-profile-settings` completed implementation and committed `3eefd333 feat: add workspace profile settings` on branch `work/00001KX0DSMPT-workspace-profile-settings`.
- Worktree status was clean after commit。
- Changed files include:
- `crates/workspace-server/src/profile_settings.rs` (new)
- `crates/workspace-server/src/{server.rs,hosts.rs,companion.rs,lib.rs}`
- `web/workspace/src/lib/workspace-settings/{profile-api.ts,profile-types.ts,model.ts}`
- `web/workspace/src/lib/workspace-api/http.ts`
- `web/workspace/src/routes/w/[workspaceId]/settings/+page.svelte`
- child implementation also committed `.yoi/tickets/00001KX0DSMPT/{item.md,thread.md}` changes; Orchestrator will preserve authoritative Ticket thread/item records during integration if conflicts occur。
- Implementation summary:
- Added scoped Workspace/Profile settings API for workspace metadata and profile registry/source read/write。
- Added Backend profile settings model with safe source ids/display paths, revision checks, Decodal validation, selector uniqueness checks, path/symlink escape protection, and typed diagnostics。
- Profile updates rebuild Backend profile discovery/launch options so Worker launch profile candidates and settings profile list use the same discovery result。
- Extended settings UI with Workspace overview and Profiles list/editor surface using scoped APIs and safe summaries。
- Browser-facing responses avoid raw host paths, runtime internals, archive digests/content, and resource handles。
- Orchestrator reran validation in the implementation worktree:
- `git diff --check`: pass
- `cargo test -p yoi-workspace-server`: pass80 lib tests + 2 main tests
- `cargo check -p yoi`: pass
- `cd web/workspace && deno task check`: pass0 errors / 0 warnings
- `cd web/workspace && deno task test`: pass17 tests
- `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-08T12:49:09Z status: request_changes -->
## Review: request changes
External review result: request_changes
Blockers:
1. Profile mutation validation failures are not returned as typed diagnostics。
- scoped settings handlers call `profile_settings::*` with `?` directly (`server.rs:881-945`).
- `ApiError::from(Error)` initializes `diagnostics: Vec::new()` (`server.rs:3355-3360`).
- profile errors such as `profile_selector_duplicate`, `profile_source_syntax_invalid`, `profile_source_path_escape`, `profile_registry_revision_conflict` fall through to `BAD_GATEWAY` (`server.rs:3403-3414`) with an empty diagnostics array (`server.rs:3420-3423`).
- Recorded requirement says duplicate selector, invalid registry/schema/Decodal, path/symlink escape, artifact too large, and concurrency conflicts must return typed diagnostics.
2. Worker launch profile candidates can include invalid project profiles。
- `load_profile_settings` attaches Decodal/source validation errors from `validate_project_profiles` only to top-level `diagnostics` (`profile_settings.rs:327`, `663-707`).
- each project `WorkspaceProfileSummary` only gets `source_summary` diagnostics (`profile_settings.rs:304-323`).
- `worker_profile_candidates_for_root` includes project profiles when `profile.diagnostics.is_empty()` (`server.rs:2989-2992`).
- `is_profile_candidate` accepts any discovered project profile id (`profile_settings.rs:629-635`).
- Result: registry entry with invalid Decodal source can still appear in launch options and be accepted as a candidate until spawn-time archive resolution fails.
- This violates the intent that profile updates re-run Backend discovery/validation and Worker launch candidates share the same effective validated discovery result.
3. Registry/default updates can commit references that are not actually Backend-published/valid。
- `validate_default_profile` accepts any string beginning with `project:` without checking that the project selector exists in submitted registry or discovery result (`profile_settings.rs:946-955`).
- `update_profile_registry` only validates source content if the expected source file already exists (`profile_settings.rs:463-468`) before writing the registry (`profile_settings.rs:470`).
- This permits API writes that persist nonexistent project defaults or missing project source references, contrary to the invariant that writes validate schema/selector/source references before commit and defaults/candidates are Backend-published.
Validation performed:
- Read Ticket `00001KX0DSMPT` item/thread, IntentPacket, binding invariants, acceptance criteria, implementation report, and reviewer focus。
- Read-only inspection in implementation worktree `/home/hare/Projects/yoi/.worktree/00001KX0DSMPT-workspace-profile-settings`
- Inspected implementation commit scope and relevant backend/frontend files。
- Relied on Orchestrator-provided validation results; did not modify files or run root/original workspace operations。
Non-blocking follow-ups:
- Negative-test coverage is thinner than reviewer focus: duplicate selector, invalid registry schema, symlink escape, artifact size, redaction, concurrent update API response shape, and launch-candidate invalidation need stronger coverage.
- UI implements profile list/editor on single `/settings` page with anchors/forms rather than separate `/settings/profiles/...` pages. This may be acceptable under implementation latitude, but confirm route granularity if it matters.
---
<!-- event: implementation_report author: orchestrator at: 2026-07-08T13:07:39Z -->
## Implementation report
Review-fix implementation report:
- Recovery Coder Pod completed requested changes and committed follow-up `0c2ca1ea fix: harden profile settings validation` on branch `work/00001KX0DSMPT-workspace-profile-settings`.
- Worktree status was clean after commit。
- Fix summary:
- Profile settings validation errors now map to typed Browser diagnostics with non-empty `diagnostics` arrays and appropriate HTTP statusesrevision conflict 409、invalid/duplicate/path/schema/source/profile errors 400、unknown source/selector 404)。
- Project profile discovery attaches source/Decodal validation failures to the relevant `WorkspaceProfileSummary`
- Invalid project profiles are excluded from Worker launch candidates and rejected by candidate validation。
- Registry/default writes validate default selector existence, selector/source consistency, missing source files, path/symlink escape, source size, Decodal/ProfileSourceArchive validity, and invalid registry schema before commit。
- Added/strengthened tests for duplicate selector, invalid Decodal/schema, stale revision conflict, too-large source, symlink escape redaction, invalid launch candidate rejection, and missing/default reference rejection。
- Orchestrator reran validation in the implementation worktree:
- `git diff --check`: pass
- `cargo test -p yoi-workspace-server`: pass91 lib tests + 2 main tests
- `cargo check -p yoi`: pass
- `cd web/workspace && deno task check`: pass0 errors / 0 warnings
- `cd web/workspace && deno task test`: pass17 tests
- `yoi ticket doctor`: ok
- `nix build .#yoi --no-link`: pass
- Requesting follow-up external review against `3eefd333..0c2ca1ea` and full combined implementation。
---
<!-- event: review author: reviewer at: 2026-07-08T13:18:55Z status: approve -->
## Review: approve
External follow-up review result: approve
Blockers: none.
Validation performed read-only in implementation worktree. Reviewer inspected Ticket records, `0c2ca1ea`, fix diff `3eefd333..0c2ca1ea`, and relevant server/profile/UI code. Reviewer did not rerun heavy validation and relied on Orchestrator-reported passing validation.
Findings:
- Prior blocker 1 resolved: profile mutation failures now return typed Browser diagnostics with populated diagnostics rather than generic empty diagnostics. Server-side handlers/tests cover invalid source mutations and missing-source registry mutations with non-empty diagnostic arrays and bad-request status。
- Prior blocker 2 resolved: invalid/missing/Decodal-invalid project profile sources are surfaced on relevant profile summaries, invalid project profiles are excluded from Worker launch candidates, and candidate validation rejects invalid project profile ids with regression coverage。
- Prior blocker 3 resolved: registry/default update paths validate selector/default existence, selector/source-id correspondence, missing source files, source path safety including symlink escape rejection, source size, Decodal/ProfileSourceArchive validity, and invalid registry schema before accepting mutations。
- Browser-facing profile/settings summaries expose bounded ids, labels, relative display paths, revision/configured booleans, and diagnostics; no host absolute paths, socket/session paths, runtime-local store paths, runtime endpoints/tokens, backend-private paths, archive digests, raw resource handles, or secret values were found in inspected API/UI surfaces。
- Profile detail exposes editable source content as intended settings-editor payload, not resolved archive/resource bundle。
- Decodal/ProfileSourceArchive validation remains behind server-side checked source path/archive boundary; Runtime filesystem discovery was not reintroduced for profile validation or launch。
- Single-page settings UI route structure is acceptable under implementation latitude and not a blocker。
Non-blocking follow-up:
- If merge target accumulated additional `.yoi/tickets/00001KX0DSMPT/thread.md` edits, resolve Ticket-record conflicts normally during merge; this does not affect product/code correctness.
---
<!-- event: state_changed author: orchestrator at: 2026-07-08T13:20:09Z 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 fixes。
- Implementation branch `work/00001KX0DSMPT-workspace-profile-settings` was merged into the orchestration branch with merge commit `0bf3638c merge: workspace profile settings`
- Ticket-record conflicts during merge were resolved by preserving Orchestrator-side Ticket item/thread records; product/code changes were merged。
- Final validation in Orchestrator worktree passed:
- `git diff --check`: pass
- `cargo test -p yoi-workspace-server`: pass91 lib tests + 2 main tests
- `cargo check -p yoi`: pass
- `cd web/workspace && deno task check`: pass0 errors / 0 warnings
- `cd web/workspace && deno task test`: pass17 tests
- `yoi ticket doctor`: ok
- `nix build .#yoi --no-link`: pass
Implementation commits:
- `3eefd333 feat: add workspace profile settings`
- `0c2ca1ea fix: harden profile settings validation`
No merge-blocking issues remain.
---
<!-- event: state_changed author: hare at: 2026-07-08T13:20:27Z from: done to: closed reason: closed field: state -->
## State changed
Ticket を closed にしました。
---
<!-- event: close author: hare at: 2026-07-08T13:20:27Z status: closed -->
## 完了
完了。
実装内容:
- Workspace/Profile settings scoped API を追加した。
- Workspace metadata read/update と safe identity/source summaries を扱う Settings API を追加した。
- Profile registry/source read/update API を追加し、create/update/delete と revision/etag-style optimistic checks を実装した。
- Backend profile settings model に safe source ids/display paths、Decodal/ProfileSourceArchive validation、selector uniqueness、path/symlink escape protection、source size checks、typed diagnostics を追加した。
- Profile updates 後に Backend profile discovery / validation / launch options を再構築し、Worker launch profile candidates と Settings profile list が同じ discovery result を使うようにした。
- invalid project profile は relevant profile summary に diagnostics を付与し、Worker launch candidates から除外し、candidate validation でも reject するようにした。
- Browser-facing responses/UI から host absolute paths、secret values、Runtime endpoints/tokens、socket/session paths、runtime-local store paths、archive content/digest、raw resource handles、backend-private paths を出さないようにした。
- Settings UI に Workspace overview と Profile list/source editor surface を追加した。
- Focused backend/web tests を追加/強化した。
主な commit / merge:
- implementation: `3eefd333 feat: add workspace profile settings`
- review fix: `0c2ca1ea fix: harden profile settings validation`
- merge into orchestration: `0bf3638c merge: workspace profile settings`
Review:
- 初回 external review は request_changes。
- follow-up external review は approve。merge-blocking issue なし。
Final validation in Orchestrator worktree:
- `git diff --check`: pass
- `cargo test -p yoi-workspace-server`: pass91 lib tests + 2 main tests
- `cargo check -p yoi`: pass
- `cd web/workspace && deno task check`: pass0 errors / 0 warnings
- `cd web/workspace && deno task test`: pass17 tests
- `yoi ticket doctor`: ok
- `nix build .#yoi --no-link`: pass
補足:
- implementation branch merge 時に Ticket record conflict が発生したため、Orchestrator 側の Ticket item/thread を保持して解決した。product/code changes は merge 済み。
---
+2 -2
View File
@@ -1,8 +1,8 @@
---
title: 'Add Runtime-to-Backend resource fetch REST API'
state: 'inprogress'
state: 'closed'
created_at: '2026-07-08T09:12:33Z'
updated_at: '2026-07-08T10:40:25Z'
updated_at: '2026-07-08T11:54:55Z'
assignee: null
queued_by: 'workspace-panel'
queued_at: '2026-07-08T10:04:10Z'
+36
View File
@@ -0,0 +1,36 @@
完了。
実装内容:
- Runtime-to-Backend resource fetch contract を追加した。
- Backend-issued typed resource handle と `BackendResourceBroker` を実装した。
- v0 resource kind `profile_source_archive` を fetch / verify / cache できるようにした。
- embedded direct Runtime path と remote Runtime HTTP path が同じ typed resource contract を使うようにした。
- Runtime は handle に基づき archive を fetch し、digest / max bytes / content type / expiry / binding を検証してから cache/reuse するようにした。
- Backend broker は stored issued handle を authority として扱い、Runtime-provided mutable handle fields による expiry / max_bytes / policy tampering を fail closed するようにした。
- Runtime cache は Backend authorization / expiry / binding を bypass しないようにした。
- Decodal ProfileSourceArchive / config bundle path を resource fetch boundary に接続し、Runtime filesystem discovery を再導入しない形にした。
- Browser-facing summaries は internal resource handle / endpoint / raw path / archive content/digest/store path / token 等を出さないようにした。
- Focused worker-runtime / workspace-server tests を追加した。
主な commit / merge:
- implementation: `57e96d3b feat: add backend resource fetch api`
- review fix: `e716ae44 fix: harden backend resource handles`
- merge into orchestration: `01f94b75 merge: backend resource fetch api`
Review:
- 初回 external review は request_changes。
- follow-up external review は approve。merge-blocking issue なし。
Final validation in Orchestrator worktree:
- `git diff --check`: pass
- `cargo test -p worker-runtime --features ws-server,fs-store`: pass45 lib tests + 5 main tests + doc tests
- `cargo test -p yoi-workspace-server`: pass77 lib tests + 2 main tests
- `cargo check -p yoi`: pass
- `cd web/workspace && deno task check`: pass0 errors / 0 warnings
- `cd web/workspace && deno task test`: pass17 tests
- `yoi ticket doctor`: ok
- `nix build .#yoi --no-link`: pass
補足:
- Reviewer の non-blocking follow-up: stored `audit_correlation_id` echo と Runtime-side response `resource_id` check、remote HTTP response-size limiting のさらなる強化余地。
- queued `00001KX0DSMPT` については、resource-fetch API shape が確定したため再 routing 可能。
+219
View File
@@ -176,3 +176,222 @@ Implementation routing update:
- 完了後は diff / validation evidence を Orchestrator が確認し、別 sibling Reviewer Pod に read-only review を依頼する。`StopPod` は既知の不具合があるため使用しない。
---
<!-- event: implementation_report author: orchestrator at: 2026-07-08T11:20:23Z -->
## Implementation report
Implementation progress report:
- Coder Pod completed implementation and committed `57e96d3b feat: add backend resource fetch api` on branch `work/00001KX0G06VA-resource-fetch-api`.
- Worktree status was clean after commit.
- Changed files include:
- `crates/worker-runtime/src/resource.rs` (new)
- `crates/workspace-server/src/resource_broker.rs` (new)
- `crates/worker-runtime/src/{config_bundle.rs,http_server.rs,main.rs,profile_archive.rs,worker_backend.rs}`
- `crates/workspace-server/src/{hosts.rs,server.rs,companion.rs}`
- `Cargo.lock`, `package.nix`
- Implementation summary:
- Added typed resource handle/request/response model and Runtime resource client/cache path。
- Added Backend resource broker for v0 `profile_source_archive` resources。
- Embedded direct path and remote Runtime HTTP path share the resource contract。
- Runtime verifies digest, max bytes/content type, expiry/binding, and cache reuse before using fetched profile archives。
- Config bundle/profile archive path can use resource handle without Runtime filesystem discovery。
- Browser-facing summaries redact internal resource handles/endpoints/raw paths/archive details。
- Added focused tests for handle issue/verify, runtime mismatch, digest mismatch, oversized response, direct/remote resource fetch, Browser redaction, and config-bundle/resource archive integration。
- Orchestrator reran validation in the implementation worktree:
- `git diff --check`: pass
- `cargo test -p worker-runtime --features ws-server,fs-store`: pass42 lib tests + 5 main tests + doc tests
- `cargo test -p yoi-workspace-server`: pass71 lib tests + 2 main tests
- `cargo check -p yoi`: pass
- `cd web/workspace && deno task check`: pass0 errors / 0 warnings
- `cd web/workspace && deno task test`: pass17 tests
- `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-08T11:27:23Z status: request_changes -->
## Review: request changes
External review result: request_changes
Blockers:
1. Backend handle verification が Runtime から送られた mutable handle fields を信頼している。
- `crates/workspace-server/src/resource_broker.rs` の fetch validation は expiry / max-bytes を `request.handle` から確認しており、broker-stored issued handle の authority fields と照合していない。
- 有効な nonce/resource/digest を持つ Runtime が以下を改変できる可能性がある。
- `expires_at_unix_seconds` を延長して expiry を bypass。
- `max_bytes` を増やして oversized rejection を bypass。
- redaction/scope/generation など他 policy fields も stored issued handle に bind されていない。
- Backend-issued handle を Backend が検証し、expired/oversized handles が fail closed typed diagnostics になるという Ticket requirement に反する。
2. Runtime cache が Backend authorization / expiry / binding を bypass している。
- `ProfileRuntimeWorkerFactory::resolve_profile_source_archive` は fetch 前に digest keyed `profile_archive_cache` を見る。
- 一度 archive が cache されると、同一 digest の後続 config bundle は Backend verification なしで reuse でき、expired handle / runtime-worker-workspace mismatch でも成功し得る。
- 「Runtime cannot fetch/use Workspace-derived resources without Backend-issued handle」「Runtime verifies expiry/binding」「expired/unauthorized/mismatch cases produce diagnostics」に反する。
3. security contract の acceptance-level tests が不足している。
- happy-path broker issue/fetch、runtime mismatch、browser projection redaction はあるが、以下の meaningful coverage が不足している。
- tampered expired handle / expiry extension。
- worker mismatch。
- REST 経由 missing resource。
- Runtime response verification の digest mismatch。
- tampered `max_bytes` による oversized response。
- remote HTTP resource-fetch path が同じ contract を使うこと。
- 上記 defect が存在しているため、単なる coverage gap ではなく core Ticket intent の boundary regression を許している。
Validation / inspection performed:
- implementation worktree `/home/hare/Projects/yoi/.worktree/00001KX0G06VA-resource-fetch-api` のみを使用。
- Ticket item/thread/orchestration plan を確認。
- `git show --stat --check 57e96d3b`, `git show --name-only 57e96d3b`, relevant implementation files を inspection。
- Orchestrator-reported validation pass を参照し、Reviewer は heavy tests を再実行していない。
Non-blocking follow-ups:
- New `reqwest` dependency and `package.nix` cargo hash update は HTTP Runtime resource client と `nix build` pass により妥当。
- broader resource kind 追加前に、stored issued handle policy fields の完全比較、または signed/opaque handle representation を検討するとよい。
---
<!-- event: implementation_report author: orchestrator at: 2026-07-08T11:45:42Z -->
## Implementation report
Review-fix implementation report:
- Coder Pod completed requested changes and committed follow-up `e716ae44 fix: harden backend resource handles` on branch `work/00001KX0G06VA-resource-fetch-api`.
- Worktree status was clean after commit.
- Fix summary:
- Backend broker now treats broker-stored issued handle as authority。
- Request handle must match stored issued handle; expiry and `max_bytes` validation use stored policy fields, not mutable Runtime-provided fields。
- Tampered scope/policy fields fail closed。
- Runtime archive cache no longer bypasses Backend authorization: Runtime calls `BackendResourceClient` and verifies response before reusing digest-cached archive。
- Expired/unauthorized handles now block cached reuse。
- Added focused security-contract tests for expiry extension/expired handle rejection, worker mismatch, policy tampering, REST missing-resource diagnostic, Runtime digest mismatch, oversized response despite `max_bytes` tampering, and remote HTTP path using the same Backend contract as direct broker path。
- Orchestrator reran validation in the implementation worktree:
- `git diff --check`: pass
- `cargo test -p worker-runtime --features ws-server,fs-store`: pass45 lib tests + 5 main tests + doc tests
- `cargo test -p yoi-workspace-server`: pass77 lib tests + 2 main tests
- `cargo check -p yoi`: pass
- `cd web/workspace && deno task check`: pass0 errors / 0 warnings
- `cd web/workspace && deno task test`: pass17 tests
- `yoi ticket doctor`: ok
- `nix build .#yoi --no-link`: pass
- Requesting follow-up external review against `57e96d3b..e716ae44` and full combined implementation。
---
<!-- event: review author: reviewer at: 2026-07-08T11:53:02Z status: approve -->
## Review: approve
External follow-up review result: approve
Blockers: none.
Validation performed:
- Read-only review in implementation worktree `/home/hare/Projects/yoi/.worktree/00001KX0G06VA-resource-fetch-api`
- Ticket item/thread, branch/log/status, `57e96d3b..e716ae44` fix diff, and relevant implementation files を確認。
- Reviewer は validation suite を再実行せず、Orchestrator-reported passing validation を evidence として確認。
Findings:
- Prior blocker 1 fixed: Backend は mutable request handle policy fields を信頼しない。`BackendResourceBroker` は issued `BackendResourceHandle` を resource と共に保存し、stored expiry/max_bytes を検証してから request handle と stored issued handle を比較する。tampering は `Expired` / `Oversized` / `Unauthorized` diagnostics で fail closed。expiry extension、policy tampering、worker/runtime mismatch、max_bytes tampering tests あり。
- Prior blocker 2 fixed: Runtime cache は Backend authorization を bypass しない。`resolve_profile_source_archive` は先に Backend fetch を行い、handle に対して response verify してから digest cache を reuse/insert する。cache test は second-use backend `Expired` rejection と backend call count を確認している。
- Prior blocker 3 fixed: security contract tests が meaningful に追加されている。
- `resource_broker.rs`: expired/expiry extension、worker mismatch、runtime mismatch、policy tampering、stored max_bytes oversized。
- `resource.rs`: Runtime digest mismatch と oversized response verification。
- `server.rs`: REST missing-resource diagnostic と remote HTTP contract/tampering path。
- `worker_backend.rs`: cache authorization。
- Browser redaction: `ConfigBundleSummary` redaction test。
- Typed/direct/remote contract: `BackendResourceFetchRequest/Response/Error` は shared typed structs。embedded direct path は `BackendResourceBroker``BackendResourceClient` として使い、remote HTTP は同じ request shape を `/internal/runtime/resources/fetch` に POST する。
- Browser-facing redaction remains strong: browser-safe summaries は profile source graph summary のみを出し、handle nonce/resource id/archive digest/runtime-worker binding/token/internal endpoint/raw path を出さない。
- ProfileSourceArchive integration は normal Backend/Browser launch で Backend-owned resource boundary を使う。generated bundles は resource handle を持ち inline archive を持たず、Runtime は fetched archive bytes から resolve する。filesystem profile discovery は explicit no-config-bundle compatibility/debug fallback のみ。
Non-blocking follow-ups:
- stored `audit_correlation_id` の echo と Runtime-side response `resource_id` check を追加すると diagnostic integrity がさらに強くなる。
- remote HTTP resource fetch が trusted Backend/Runtime links を越えて露出する場合は、JSON body materialization 前の explicit client-side timeout/response-size limiting を検討する。
Effect on queued `00001KX0DSMPT`:
- blocking concern なし。profile/archive details は redacted summaries behind boundary に留まっており、future settings UI/API が profile metadata を consume しても handles を露出しない設計と互換。
---
<!-- event: state_changed author: orchestrator at: 2026-07-08T11:54:39Z 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/00001KX0G06VA-resource-fetch-api` was merged into the orchestration branch with merge commit `01f94b75 merge: backend resource fetch api`
- Final validation in Orchestrator worktree passed:
- `git diff --check`: pass
- `cargo test -p worker-runtime --features ws-server,fs-store`: pass45 lib tests + 5 main tests + doc tests
- `cargo test -p yoi-workspace-server`: pass77 lib tests + 2 main tests
- `cargo check -p yoi`: pass
- `cd web/workspace && deno task check`: pass0 errors / 0 warnings
- `cd web/workspace && deno task test`: pass17 tests
- `yoi ticket doctor`: ok
- `nix build .#yoi --no-link`: pass
Implementation commits:
- `57e96d3b feat: add backend resource fetch api`
- `e716ae44 fix: harden backend resource handles`
No merge-blocking issues remain. Reviewer noted no blocking concern for queued `00001KX0DSMPT`; the resource-fetch API shape is now stable enough for that follow-up to be re-routed.
---
<!-- event: state_changed author: hare at: 2026-07-08T11:54:54Z from: done to: closed reason: closed field: state -->
## State changed
Ticket を closed にしました。
---
<!-- event: close author: hare at: 2026-07-08T11:54:55Z status: closed -->
## 完了
完了。
実装内容:
- Runtime-to-Backend resource fetch contract を追加した。
- Backend-issued typed resource handle と `BackendResourceBroker` を実装した。
- v0 resource kind `profile_source_archive` を fetch / verify / cache できるようにした。
- embedded direct Runtime path と remote Runtime HTTP path が同じ typed resource contract を使うようにした。
- Runtime は handle に基づき archive を fetch し、digest / max bytes / content type / expiry / binding を検証してから cache/reuse するようにした。
- Backend broker は stored issued handle を authority として扱い、Runtime-provided mutable handle fields による expiry / max_bytes / policy tampering を fail closed するようにした。
- Runtime cache は Backend authorization / expiry / binding を bypass しないようにした。
- Decodal ProfileSourceArchive / config bundle path を resource fetch boundary に接続し、Runtime filesystem discovery を再導入しない形にした。
- Browser-facing summaries は internal resource handle / endpoint / raw path / archive content/digest/store path / token 等を出さないようにした。
- Focused worker-runtime / workspace-server tests を追加した。
主な commit / merge:
- implementation: `57e96d3b feat: add backend resource fetch api`
- review fix: `e716ae44 fix: harden backend resource handles`
- merge into orchestration: `01f94b75 merge: backend resource fetch api`
Review:
- 初回 external review は request_changes。
- follow-up external review は approve。merge-blocking issue なし。
Final validation in Orchestrator worktree:
- `git diff --check`: pass
- `cargo test -p worker-runtime --features ws-server,fs-store`: pass45 lib tests + 5 main tests + doc tests
- `cargo test -p yoi-workspace-server`: pass77 lib tests + 2 main tests
- `cargo check -p yoi`: pass
- `cd web/workspace && deno task check`: pass0 errors / 0 warnings
- `cd web/workspace && deno task test`: pass17 tests
- `yoi ticket doctor`: ok
- `nix build .#yoi --no-link`: pass
補足:
- Reviewer の non-blocking follow-up: stored `audit_correlation_id` echo と Runtime-side response `resource_id` check、remote HTTP response-size limiting のさらなる強化余地。
- queued `00001KX0DSMPT` については、resource-fetch API shape が確定したため再 routing 可能。
---