252 lines
16 KiB
Markdown
252 lines
16 KiB
Markdown
<!-- event: create author: "yoi ticket" at: 2026-07-08T19:18:25Z -->
|
||
|
||
## 作成
|
||
|
||
LocalTicketBackend によって作成されました。
|
||
|
||
---
|
||
|
||
<!-- event: intake_summary author: hare at: 2026-07-09T07:18:33Z -->
|
||
|
||
## Intake summary
|
||
|
||
Marked ready by `yoi ticket state`.
|
||
|
||
---
|
||
|
||
<!-- event: state_changed author: "yoi ticket" at: 2026-07-09T07:18:33Z 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-09T07:56:07Z from: ready to: queued reason: queued field: state -->
|
||
|
||
## State changed
|
||
|
||
Ticket を `workspace-panel` が queued にしました。
|
||
|
||
|
||
---
|
||
|
||
<!-- event: decision author: orchestrator at: 2026-07-09T07:57:36Z -->
|
||
|
||
## Decision
|
||
|
||
Routing decision: implementation_ready
|
||
|
||
Reason:
|
||
- Declared dependency `00001KWZ5KERY` is closed, so Decodal ProfileSourceArchive / archive verify / Runtime FSなし resolution の基礎は available。
|
||
- Related follow-up `00001KX0DSMPT` Workspace/Profile settings API/pages is also closed, so settings/profile editing surface exists and this Ticket can refine it to ProfileSourceTree virtual filesystem + Decodal editor。
|
||
- Ticket body gives concrete model/API/UI/editor/dependency/validation requirements and clear non-goals。
|
||
- typed relation blocker is resolved; OrchestrationPlan record は 0 件。inprogress Ticket も 0 件。
|
||
- queued notification is human authorized routing/start。
|
||
|
||
Evidence checked:
|
||
- Ticket body / thread / artifacts。
|
||
- `TicketRelationQuery(00001KX1JNJ2Y)`: outgoing `depends_on 00001KWZ5KERY`; target is closed。
|
||
- `TicketOrchestrationPlanQuery(00001KX1JNJ2Y)`: 0 件。
|
||
- `TicketList`: queued はこの Ticket 1件、inprogress は 0 件。
|
||
- Orchestrator worktree git status: clean on `orchestration`。
|
||
- Relevant prior work: Decodal/ProfileSourceArchive closed, Workspace/Profile settings closed。
|
||
|
||
IntentPacket:
|
||
|
||
Intent:
|
||
- Add Backend-owned `ProfileSourceTree` virtual filesystem for Decodal profile sources, connect ProfileSourceArchive import closure building to that tree, strengthen Runtime archive import validation, and add Workspace settings Profile source tree editor using `decodal-codemirror@0.1.2` / CodeMirror 6。
|
||
|
||
Binding decisions / invariants:
|
||
- Browser/editor works with virtual relative paths and safe source tree/file ids, never host absolute paths or raw filesystem authority。
|
||
- Backend validation is authority; Browser editor diagnostics are only assistance。
|
||
- Runtime reads only ProfileSourceArchive manifest / virtual paths, not Workspace filesystem。
|
||
- `ProfileSourceArchive` is a snapshot of source tree revision + selected root + import closure。
|
||
- Browser-facing API must not expose host absolute path, symlink target path, Runtime endpoint/socket/session path, secret values, WorkingDirectory root path, raw resource handles, archive digest/content, or backend-private paths。
|
||
- `decodal-codemirror@0.1.2` / CodeMirror 6 dependency is in scope; formatter and Browser-side Decodal materialization as authority are out of scope。
|
||
|
||
Requirements / acceptance criteria:
|
||
- Implement typed `ProfileSourceTree` model with tree id, revision/generation, virtual root metadata, files, provenance, diagnostics, and safe summaries。
|
||
- Implement virtual import resolver for relative imports and adopted namespace imports, with normalization and typed diagnostics for root escape, absolute path, URL/unsupported scheme, extension/content-type, depth/count/bytes limits。
|
||
- Build `ProfileSourceArchive` from selected root virtual path and source tree import closure, including virtual path / source key / digest / size / content type / import map in manifest。
|
||
- Runtime `ArchiveSourceLoader` validates manifest-contained virtual paths only and rejects manifest-outside import, absolute path, `..`, unsupported namespace。
|
||
- Add scoped Profile settings file-tree API: list trees, list files, read/write/create/delete file, validate tree/file; rename/move optional。
|
||
- Add Settings UI profile source tree list and file tree editor routes/pages using Decodal CodeMirror extension and Backend save/create/delete/validate APIs。
|
||
- Focused backend/runtime/web tests cover path normalization, import closure, archive manifest validation, Runtime import resolution, Browser redaction, file tree API, and editor route smoke。
|
||
|
||
Implementation latitude:
|
||
- Exact endpoint names, source tree storage format, namespace enum details, UI route/component split, and editor model can follow existing workspace-server/Svelte style。
|
||
- v0 may keep source tree storage minimal and project/workspace-backed, provided Browser contract remains virtual-path based and Backend validation remains authority。
|
||
|
||
Escalate if:
|
||
- Browser-facing raw host path authority, Runtime workspace filesystem discovery, Browser-side Decodal materialization as authority, formatter integration, plugin/MCP/sandbox artifact sync, or Profile source RDB-normalized editor becomes required。
|
||
|
||
Validation:
|
||
- `cargo test -p yoi-workspace-server`
|
||
- `cargo test -p worker-runtime --features ws-server,fs-store`
|
||
- `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:
|
||
- Backend profile settings/source model: `crates/workspace-server/src/profile_settings.rs`, `server.rs`, `hosts.rs`。
|
||
- Decodal/Profile archive: `crates/worker-runtime/src/profile_archive.rs`, `config_bundle.rs`。
|
||
- Frontend settings/profile editor: `web/workspace/src/routes/w/[workspaceId]/settings/**`, `web/workspace/src/lib/workspace-settings/**`。
|
||
|
||
Critical risks / reviewer focus:
|
||
- virtual paths and tar paths must not allow absolute path / `..` / symlink/path escape。
|
||
- Browser must never receive host absolute path, secret, runtime endpoint, archive digest/content, or raw handle。
|
||
- Runtime SourceLoader must be archive-manifest/import-map only, no FS/backend fallback。
|
||
- source tree validation/write must be revision-aware and fail closed with typed diagnostics。
|
||
- new editor dependency and Nix/lock updates must be correct。
|
||
|
||
---
|
||
|
||
<!-- event: state_changed author: orchestrator at: 2026-07-09T07:57:59Z 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(00001KX1JNJ2Y)`: depends_on `00001KWZ5KERY`; target is closed。
|
||
- `TicketOrchestrationPlanQuery(00001KX1JNJ2Y)`: prior record 0 件。今回 accepted_plan を記録済み。
|
||
- Orchestrator worktree git status: clean on `orchestration`。
|
||
- queued Ticket はこの Ticket 1件のみ。inprogress は 0 件。
|
||
|
||
Acceptance basis:
|
||
- concrete missing decision / information は残っていない。
|
||
- Ticket scope is ProfileSourceTree virtual filesystem + Decodal editor follow-up on top of closed Decodal/ProfileSourceArchive and Workspace/Profile settings work。
|
||
- side effect はこの `queued -> inprogress` acceptance 後に、worktree-workflow に沿って implementation worktree を作成してから開始する。
|
||
|
||
---
|
||
|
||
<!-- event: implementation_report author: orchestrator at: 2026-07-09T07:58:54Z -->
|
||
|
||
## Implementation report
|
||
|
||
Implementation routing update:
|
||
|
||
- Worktree-workflow に従い implementation worktree を作成した。
|
||
- Worktree: `/home/hare/Projects/yoi/.worktree/00001KX1JNJ2Y-profile-source-tree`
|
||
- Branch: `work/00001KX1JNJ2Y-profile-source-tree`
|
||
- Worktree には tracked `.yoi` project records が見えている。
|
||
- `.yoi/memory` / `.yoi/runtime` / `.yoi/log` / `.yoi/logs` / `.yoi/local` / `.yoi/*.lock` / `.yoi/*secret*` は作成直後に存在しないことを確認した。
|
||
- Sibling Coder Pod `yoi-coder-00001KX1JNJ2Y-source-tree` を起動した。
|
||
- Scope policy: runtime workspace root は read-only、implementation worktree は write 可。Coder task では root/original workspace での read/write/validation/git operation を禁止し、この implementation worktree だけを作業対象に指定した。
|
||
- 初回プロンプト肥大化を避けるため、Coder には短い task と Ticket record 読み取り指示を渡した。
|
||
- 完了後は diff / validation evidence を Orchestrator が確認し、別 sibling Reviewer Pod に read-only review を依頼する。`StopPod` は既知の不具合があるため使用しない。
|
||
|
||
---
|
||
|
||
<!-- event: implementation_report author: orchestrator at: 2026-07-09T08:28:11Z -->
|
||
|
||
## Implementation report
|
||
|
||
Implementation progress report:
|
||
|
||
- Coder Pod completed implementation and committed `81abfa63 feat: add profile source tree editor` on branch `work/00001KX1JNJ2Y-profile-source-tree`.
|
||
- Worktree status was clean after commit。
|
||
- Changed files include:
|
||
- `crates/worker-runtime/src/profile_archive.rs`
|
||
- `crates/workspace-server/src/profile_settings.rs`
|
||
- `crates/workspace-server/src/server.rs`
|
||
- `web/workspace/deno.json`, `web/workspace/deno.lock`
|
||
- `web/workspace/src/lib/workspace-settings/DecodalSourceEditor.svelte`
|
||
- `web/workspace/src/lib/workspace-settings/{profile-api.ts,profile-types.ts}`
|
||
- `web/workspace/src/routes/w/[workspaceId]/settings/profiles/+page.svelte`
|
||
- child implementation also committed `.yoi/tickets/00001KX1JNJ2Y/{item.md,thread.md}` changes; Orchestrator will preserve authoritative Ticket records during merge if conflicts occur。
|
||
- Implementation summary:
|
||
- Added Runtime archive validation for virtual source metadata, duplicate/undeclared entries, scoped import maps, namespace/path safety, and relative virtual import resolution。
|
||
- Added Backend-owned project `ProfileSourceTree` support with virtual `profiles/...` paths, tree scanning, revision-aware file read/write/delete API, and tree-based archive/config-bundle generation。
|
||
- Added workspace server routes and Browser API/types for scoped source-tree access without host paths or backend-private/archive internals。
|
||
- Added Profiles settings Decodal CodeMirror editor using virtual paths and revision tokens。
|
||
- Added worker-runtime tests for scoped virtual import resolution and import-map mismatch rejection。
|
||
- Orchestrator reran validation in the implementation worktree:
|
||
- `git diff --check`: pass
|
||
- `cargo test -p yoi-workspace-server`: pass(91 lib tests + 2 main tests)
|
||
- `cargo test -p worker-runtime --features ws-server,fs-store`: pass(47 lib tests + 5 main tests + doc tests)
|
||
- `cargo check -p yoi`: pass
|
||
- `cd web/workspace && deno task check`: pass(0 errors / 0 warnings)
|
||
- `cd web/workspace && deno task test`: pass(17 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-09T08:32:35Z status: request_changes -->
|
||
|
||
## Review: request changes
|
||
|
||
External review result: request_changes
|
||
|
||
Blockers:
|
||
|
||
1. Decodal CodeMirror integration is missing。
|
||
- Ticket requires `decodal-codemirror@0.1.2` and the `decodal()` CodeMirror 6 extension。
|
||
- Implementation only adds `@codemirror/state` / `@codemirror/view` (`web/workspace/deno.json`) and `deno.lock` has no `decodal-codemirror` specifier。
|
||
- `DecodalSourceEditor.svelte` builds a plain CodeMirror editor with line numbers/selection/theme only, so there is no Decodal highlighting/indent/folding extension。
|
||
|
||
2. Settings UI does not implement the required tree route or create/delete editor operations。
|
||
- Ticket requires `/w/<workspace-id>/settings/profiles/trees/<source-tree-id>` plus save/create/delete via Backend APIs。
|
||
- Route tree only contains `web/workspace/src/routes/w/[workspaceId]/settings/profiles/+page.svelte`; no `trees/[sourceTreeId]` route。
|
||
- Page imports/uses only `writeProfileTreeFile` and renders only Save; no create/delete UI is wired despite `deleteProfileTreeFile` existing in API wrapper。
|
||
|
||
3. Archive construction is not a selected-root import-closure snapshot。
|
||
- `build_workspace_profile_archive(workspace_root, selector)` reads whole tree and calls `build_profile_archive_from_tree_sources`; selector is used only for post-build validation。
|
||
- Builder adds entrypoints for every project registry entry, scans every source for imports, and passes entire `sources` map into `ProfileSourceArchive::build`。
|
||
- This violates requirement that archive is generated from `ProfileSourceTree revision + selected root + import closure`, with closure-only contents。
|
||
|
||
4. `ProfileSourceTree` typed model is incomplete against Ticket contract。
|
||
- Browser/backend structs expose tree id/root/revision/file count and file path/kind/revision/size, but no content digest, content type, or provenance field/typed provenance enum。
|
||
- These are explicit Ticket requirements for the typed model。
|
||
|
||
5. Symlink/path-escape write safety has a side-effect before containment validation。
|
||
- `write_profile_tree_file` calls `fs::create_dir_all(parent)` on unresolved workspace path before `checked_source_path` canonical root containment checks。
|
||
- With a symlinked intermediate directory under `.yoi/profiles`, this can create directories outside source root before later rejection。
|
||
- Path/symlink escape should fail closed without outside filesystem mutation。
|
||
|
||
Validation performed:
|
||
- Read Ticket item, routing IntentPacket, and implementation report。
|
||
- Inspected implementation commit metadata and relevant backend/runtime/frontend files in the implementation worktree only。
|
||
- Did not rerun reported cargo/deno/nix validations; Orchestrator-reported validation was passing, but blockers are functional/design acceptance gaps。
|
||
|
||
Non-blocking follow-ups:
|
||
- After blockers are fixed, add focused regression coverage for selected-root closure behavior, tree route smoke, Decodal editor extension wiring, UI create/delete flows, and symlinked-directory tree-write rejection-before-side-effect。
|
||
|
||
---
|
||
|
||
<!-- event: implementation_report author: orchestrator at: 2026-07-09T08:52:14Z -->
|
||
|
||
## Implementation report
|
||
|
||
Review-fix implementation report:
|
||
|
||
- Coder Pod completed requested changes and committed follow-up `941b9126 fix: complete profile source tree review fixes` on branch `work/00001KX1JNJ2Y-profile-source-tree`.
|
||
- Worktree status was clean after commit。
|
||
- Fix summary:
|
||
- Added `decodal-codemirror@0.1.2` and wired `decodal()` into the CodeMirror 6 editor。
|
||
- Added source tree settings route `/w/<workspace-id>/settings/profiles/trees/<source-tree-id>`。
|
||
- Wired UI create/save/delete operations through Backend virtual-path source tree APIs。
|
||
- Changed archive construction to selected selector/root + import closure only, avoiding unrelated project tree sources。
|
||
- Added safe typed source/tree metadata including content type, content digest, and typed provenance。
|
||
- Hardened tree writes against symlinked intermediate directories before any outside filesystem mutation。
|
||
- Added focused regression coverage for selected-root closure-only archive contents, symlink write rejection before side effects, and web model smoke tests for tree routes / virtual create paths。
|
||
- Orchestrator reran validation in the implementation worktree:
|
||
- `git diff --check`: pass
|
||
- `cargo test -p yoi-workspace-server`: pass(93 lib tests + 2 main tests)
|
||
- `cargo test -p worker-runtime --features ws-server,fs-store`: pass(47 lib tests + 5 main tests + doc tests)
|
||
- `cargo check -p yoi`: pass
|
||
- `cd web/workspace && deno task check`: pass(0 errors / 0 warnings)
|
||
- `cd web/workspace && deno task test`: pass(19 tests)
|
||
- `yoi ticket doctor`: ok
|
||
- `nix build .#yoi --no-link`: pass
|
||
- Requesting follow-up external review against `81abfa63..941b9126` and full combined implementation。
|
||
|
||
---
|