yoi/.yoi/tickets/00001KVFDX9AY/thread.md

871 lines
48 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-06-19T07:53:13Z -->
## 作成
LocalTicketBackend によって作成されました。
---
<!-- event: state_changed author: workspace-panel at: 2026-06-19T10:19:52Z from: ready to: queued reason: queued field: state -->
## State changed
Ticket を `workspace-panel` が queued にしました。
---
<!-- event: plan author: yoi-orchestrator at: 2026-06-19T10:22:26Z -->
## Plan
Routing hold / waiting-capacity note:
明示 queue review で Ticket body / relations / orchestration plan / workspace state を確認した。
Current decision:
- この Ticket は `queued` のまま待機。
- 依存 Ticket `00001KV5W3PHW` / `00001KV5W3PJ3` は closed で dependency blocker ではない。
- ただし同時 queued の `00001KVFD3YSV` CLI inspection を先に受理した。CLI inspection は Plugin discovery / enablement / grants / diagnostics の read-only public surface を作る作業で、host API implementation と同じ Plugin manifest/grant/runtime/diagnostic 周辺に触れる。
- `00001KVFDX9AF` https host API とは WASM Plugin Tool runtime host import boundary、Plugin grant model、diagnostics/tests/package behavior の変更面が重なるため `do_not_parallelize` plan record を残した。
Bounded reason for idle queued:
- conflict / reviewer-coder bottleneck。
Next action:
- `00001KVFD3YSV` の implementation/review/merge outcome を確認後、queued のまま再 routing する。
- その時点で `https` host API Ticket との ordering / conflict も再確認する。
---
<!-- event: decision author: yoi-orchestrator at: 2026-06-19T15:37:24Z -->
## Decision
Routing decision: implementation_ready
Reason:
- Panel Queue により、この Ticket は Orchestrator routing 対象として明示許可された。
- Ticket body には、`fs` host API intent、binding invariants、acceptance criteria、non-goals、validation、escalation-worthy risk domain が実装可能な粒度で揃っている。
- 依存 relation の `00001KV5W3PHW` minimal WASM runtime、`00001KV5W3PJ3` permission grants、関連 `00001KVFD3YSV` CLI inspection、`00001KVFDX9AF` HTTPS host API は closed で blocker ではない。
- Risk domain は filesystem / path safety / file mutation / permission grants だが、Ticket は Plugin-specific grants、no workspace authority inheritance、path normalization、traversal/symlink/root escape rejection、bounds、safe diagnostics、ordinary Tool result path を binding invariants として明示している。bounded context check 後も implementation 前に必要な追加 human decision は見つからなかった。
- `00001KVG0HR96` Component Model migration は Plugin runtime / WIT / host API shape / grants / inspection / packaging に広く触れる migration boundary で、active `fs` host API と衝突しやすいため waiting note を更新し queued のまま待機する。
Evidence checked:
- Ticket `00001KVFDX9AY` body / thread / artifacts。
- `TicketRelationQuery(00001KVFDX9AY)`: depends_on は closed。related Ticket は context であり acceptance blocker ではない。
- `TicketOrchestrationPlanQuery(00001KVFDX9AY)`: prior waiting/do_not_parallelize records を確認。HTTPS host API は closed になったため今回 `accepted_plan` を記録済み。
- Related completed Tickets:
- `00001KV5W3PHW` — minimal WASM Tool runtime closed。
- `00001KV5W3PJ3` — Plugin permission grants closed。
- `00001KVFD3YSV` — Plugin read-only CLI inspection closed。
- `00001KVFDX9AF` — Plugin HTTPS host API closed。
- Current queued Ticket `00001KVG0HR96` Component Model migration: migration boundary / conflict waiting note を更新。
- Orchestrator worktree `/home/hare/Projects/yoi/.worktree/orchestration`: clean。
- Existing branch/worktree: matching `00001KVFDX9AY` branch/worktree はなし。
- Visible Pods: self / peers only; spawned child capacity is free。
- Current code map:
- `crates/pod/src/feature/plugin.rs`: Plugin resolver, permission grants, static inspection, host API eligibility, HTTPS implementation pattern。
- `crates/pod/src/pod.rs`: WASM Tool runtime / host import validation / Tool execution path。
- `crates/manifest/src/plugin.rs`: Plugin manifest and permission model。
- `crates/yoi/src/plugin_cli.rs`: read-only inspection output should remain compatible with fs host API diagnostics。
IntentPacket:
Intent:
- WASM Plugin Tool runtime に、明示 grant された scoped path のみ read/list/write できる `fs` host API を追加する。
- Plugin は Pod/workspace filesystem authority を自動継承せず、Plugin-specific `host_api.fs` grants だけが filesystem authority になる。
Binding decisions / invariants:
- Host API name/domain は `fs`
- Broad WASI filesystem exposure は禁止。Plugin は ambient filesystem access を持たない。
- Workspace read/write authority は Plugin に自動継承しない。
- Grant がない read/list/write は fail closed。
- Grants は operation kind (`read`, `list`, `write`) と scoped root/prefix/glob 等の最小安全形を持つ。
- Path normalization、`..` traversal rejection、symlink/root escape rejection、allowed root outside rejection は binding。
- Absolute/relative path policy は明確にし、safe default を選ぶ。
- Bounds: path length、read size、write size、directory entry count、diagnostic size。
- Writes は existing file mutation safety と整合し、normalized target file ごとに unsafe race を避ける。
- Diagnostics に file content / secret-like data を漏らさない。
- Tool result path は ordinary Tool result/history path。hidden context injection しない。
- `https` host API、Service/Ingress/File watcher/package manager は non-goals。
Requirements / acceptance criteria:
- Granted Plugin Tool can read an allowed file。
- Granted Plugin Tool can list an allowed directory within bounds。
- Granted Plugin Tool can write an allowed file within bounds。
- Plugin without matching `host_api.fs` grant cannot read/list/write。
- Workspace authority is not inherited by Plugin without Plugin grant。
- `../` traversal、symlink escape、allowed-root escape reject。
- Oversize read/write/list fail closed or truncate according to explicit policy。
- File mutation safety avoids unsafe race with existing Write/Edit semantics。
- Diagnostics do not include file content or secret-like data。
- Tests cover allowed read/list/write, missing grant denied, workspace authority not inherited, traversal/symlink/root escape, bounds, diagnostics redaction, safe write conflict behavior。
Implementation latitude:
- Choose exact ABI/import shape consistent with existing `yoi-plugin-wasm-1` host import design and current HTTPS host API pattern。
- Choose narrow grant config representation for root/prefix/glob/operation allowlist consistent with current Plugin permission grant model。
- Use tempdir/local fixture files for deterministic tests。
- Choose read/list/write response shape consistent with existing Tool result/error types and CLI inspection structure。
- If write serialization requires reusing existing file mutation primitives, keep it narrow and avoid broad Worker scheduler changes。
Escalate if:
- Safe path/symlink/root escape handling cannot be represented without broad filesystem authority redesign。
- write serialization requires broad Worker scheduler or global mutation system redesign。
- Existing Plugin grant schema cannot safely represent fs scopes without breaking HTTPS grants/CLI inspection。
- Broad WASI filesystem exposure appears necessary。
- Product decision is needed for truncate-vs-fail policy beyond Tickets bounded latitude。
Validation:
- Focused plugin fs host API tests。
- Relevant `cargo test` / `cargo check` for `pod`, `manifest`, `yoi` as changed。
- `cargo fmt --check`
- `git diff --check`
- `nix build .#yoi --no-link` / `nix build .#yoi` if dependency/package-source-filter changes occur。
Critical risks / reviewer focus:
- Workspace authority leaking into Plugin without Plugin grant。
- Path traversal / symlink / root escape bypass。
- Write race / unsafe mutation behavior。
- File content or secret leakage in diagnostics。
- Unbounded read/list/write outputs。
- Hidden context injection by bypassing normal Tool result path。
- Breaking existing HTTPS host API, permission grants, or CLI inspection semantics。
Next action:
- `queued -> inprogress` を記録し、Ticket records を Orchestrator worktree に commit してから、専用 implementation worktree を作成し Coder Pod を narrow write scope で起動する。root/original workspace は操作しない。
---
<!-- event: state_changed author: yoi-orchestrator at: 2026-06-19T15:37:38Z from: queued to: inprogress reason: orchestrator_acceptance_plugin_fs_host_api field: state -->
## State changed
Ticket body/thread, relation metadata, orchestration plan records, related completed Tickets, Orchestrator worktree, visible Pods, existing branch/worktree, and bounded Plugin fs host API code context were checked. Depends-on blockers are closed, HTTPS host API and CLI inspection related work are closed, and no dirty-state blocker or missing planning decision was found. Component Model migration remains queued with migration/conflict waiting record. Accepting this queued Ticket for implementation before worktree/Pod side effects.
---
<!-- event: implementation_report author: yoi-orchestrator at: 2026-06-19T15:39:09Z -->
## Implementation report
Implementation start note:
`queued -> inprogress` acceptance、accepted plan、routing decision / IntentPacket、Component Model migration の waiting record を記録し、Orchestrator worktree で commit した後に、専用 implementation worktree と Coder Pod を起動した。
Worktree:
- `/home/hare/Projects/yoi/.worktree/00001KVFDX9AY-plugin-fs-host-api`
- branch: `impl/00001KVFDX9AY-plugin-fs-host-api`
Coder Pod:
- `yoi-coder-00001KVFDX9AY`
Scope / boundaries:
- child runtime workspace root は read scope。
- implementation worktree は write scope。
- root/original workspace と Orchestrator worktree へは書き込まないよう指示済み。
- `.yoi/memory`、runtime/log/lock/local/secret-like `.yoi` paths は編集しないよう指示済み。
Related queued Ticket:
- `00001KVG0HR96` Component Model migration remains queued due migration boundary / conflict with active fs host API work.
Next:
- Coder は scoped `fs` host API implementation、focused tests、validation、implementation commit を行い、実装報告を返す予定。
---
<!-- event: implementation_report author: yoi-orchestrator at: 2026-06-19T16:01:41Z -->
## Implementation report
Coder implementation report received / Orchestrator validation:
Implementation commit:
- `717c0999``plugin: implement fs host api`
Summary:
- Added manifest/config support for `host_api.fs` grants:
- `PluginFsGrant { root, operations }`
- `PluginFsOperation::{read,list,write}`
- Implemented WASM host import module `yoi:fs` with:
- `read`
- `list`
- `write`
- `response_len`
- `response_read`
- Enforced plugin-specific grant checks; Pod/workspace fs authority is not inherited.
- Added path safety:
- relative-only request paths;
- `..` traversal rejection;
- configured root must be absolute/non-symlink directory;
- symlink component/target rejection;
- canonical allowed-root escape checks.
- Added bounds:
- request descriptor size;
- path length;
- read size with explicit truncation flag;
- write size fail-closed;
- directory entry count with explicit truncation flag.
- Added write serialization by normalized target plus `O_NOFOLLOW` on Unix.
- Kept fs errors/diagnostics bounded and redacted.
- Extended Plugin CLI inspection to show configured fs grants.
Files changed:
- `crates/manifest/src/plugin.rs`
- `crates/pod/src/feature/plugin.rs`
- `crates/yoi/src/plugin_cli.rs`
Coder reported validation:
- `cargo fmt --check` — passed
- `cargo test -p pod feature::plugin` — passed
- `cargo test -p manifest plugin` — passed
- `cargo test -p yoi plugin_cli` — passed
- `cargo check -p pod -p manifest -p yoi` — passed
- `git diff --check` — passed
- `nix build` not run by Coder because no dependency/package-source-filter changes.
Orchestrator evidence checked:
- Pod output を確認。
- implementation worktree は clean。
- branch `impl/00001KVFDX9AY-plugin-fs-host-api` HEAD は `717c0999`
- diff stat from accepted base `6711bcf3..717c0999`: 3 files changed, 1068 insertions, 17 deletions。
Validation re-run by Orchestrator in implementation worktree:
- `cargo fmt --check` — passed
- `cargo check -p pod -p manifest -p yoi` — passed
- `cargo test -p pod feature::plugin -- --nocapture` — passed; 48 passed, 0 failed
- `cargo test -p manifest plugin -- --nocapture` — passed; 17 passed, 0 failed
- `cargo test -p yoi plugin_cli -- --nocapture` — passed; 10 passed, 0 failed
- `git diff --check` — passed
- `nix build .#yoi --no-link` — passed
Routing classification: review_needed
Next action:
- recorded intent / invariants / acceptance criteria に照らして、read-only Reviewer Pod で外部レビューする。
- 特に no ambient workspace fs authority、grant-before-filesystem access、path traversal/symlink/root escape、bounds/truncation/fail-closed policy、write serialization/O_NOFOLLOW、diagnostic redaction、ordinary Tool result path、HTTPS/CLI compatibility を確認する。
---
<!-- event: plan author: yoi-orchestrator at: 2026-06-19T16:02:39Z -->
## Plan
Review dispatch:
Reviewer Pod `yoi-reviewer-00001KVFDX9AY` を read-only scope で起動した。
Review target:
- worktree: `/home/hare/Projects/yoi/.worktree/00001KVFDX9AY-plugin-fs-host-api`
- branch: `impl/00001KVFDX9AY-plugin-fs-host-api`
- commit: `717c0999`
Reviewer focus:
- recorded intent / invariants / acceptance criteria に対する適合性。
- filesystem access が grant checks の前に発生しないこと。
- Workspace/POD filesystem authority が Plugin に自動継承されていないこと。
- traversal / symlink / root escape protections が canonicalization races を含め妥当であること。
- read/list/write bounds と truncate-vs-fail-closed policy が明確で enforce されること。
- write serialization by normalized target と `O_NOFOLLOW` が既存 file mutation safety と整合すること。portability issue がないこと。
- diagnostics に file content / secret-like data が漏れないこと。
- ordinary Tool result/history path だけに戻ること。
- tests が allowed read/list/write、missing grant、no workspace inheritance、traversal、symlink/root escape、bounds、redaction、write safety を十分に覆うこと。
- manifest/permission grant schema と CLI inspection changes が既存 HTTPS grants / Plugin inspection behavior と互換であること。
- HTTPS host API と Component Model migration が non-goals として保たれていること。
Next:
- Reviewer output を確認し、approve なら Orchestrator worktree への merge/validation/cleanup/close-ready 処理へ進む。request_changes なら blocker を記録して Coder に戻す。
---
<!-- event: review author: yoi-reviewer-00001KVFDX9AY at: 2026-06-19T16:08:53Z status: approve -->
## Review: approve
Review result: approve
対象:
- Ticket: `00001KVFDX9AY`
- branch: `impl/00001KVFDX9AY-plugin-fs-host-api`
- commit: `717c0999` (`plugin: implement fs host api`)
No blockers found.
Evidence reviewed:
- FS grant schema is explicit and additive: `PluginGrantConfig.fs`, `PluginFsGrant { root, operations }`, and `PluginFsOperation::{read,list,write}` in `crates/manifest/src/plugin.rs`. Existing HTTPS grant shape remains separate.
- Runtime dispatch checks `host_api.fs` before request parsing reaches any filesystem operation: `execute_plugin_fs_request` bounds descriptor size, then calls `authorize_plugin_host_api(record, PluginHostApi::Fs)` before read/list/write dispatch.
- Permission/grant binding is layered correctly:
- requested `host_api.fs` permission required;
- configured grant permission required;
- usable FS scope required;
- per-operation grants checked in `authorize_fs_path` / `authorize_fs_write_path`.
- No ambient WASI/workspace filesystem authority is exposed. WASM import validation only allows `yoi:tool`, `yoi:https`, and `yoi:fs`; WASI remains rejected. Runtime FS is only through `yoi:fs` imports.
- Path safety is materially addressed:
- absolute paths, NULs, and `..` traversal rejected;
- grant root must be absolute, existing, directory, and not final symlink;
- request path components are symlink-checked;
- canonicalized targets must remain under the canonical grant root;
- write target symlinks/dirs rejected;
- Unix writes add `O_NOFOLLOW`.
- Bounds are explicit:
- request descriptor, path, read bytes, write bytes, list entry count, and diagnostics are bounded/redacted;
- read/list truncation is explicit via `truncated`;
- oversize write fails closed.
- Writes serialize by normalized/canonical target with a shared lock map and use truncate/create with `sync_all`.
- Diagnostics use `PluginFsError::new` with `bounded_message(redact_secret_like(...))`; tests verify secret-like path redaction and no file-content leakage on denial.
- FS responses flow through WASM host response buffers and then ordinary plugin Tool output/error handling; no hidden context/history injection path found.
- CLI inspection reports `configured_fs_grants` alongside existing permission/HTTPS grant inspection without changing HTTPS semantics.
Reviewer validation:
- Static review of changed files and relevant tests.
- Confirmed worktree branch/head.
- `git diff --check 717c0999^..717c0999` — passed.
- Orchestrator-reported validation was reviewed:
- `cargo fmt --check`
- `cargo check -p pod -p manifest -p yoi`
- `cargo test -p pod feature::plugin`
- `cargo test -p manifest plugin`
- `cargo test -p yoi plugin_cli`
- `git diff --check`
- `nix build .#yoi --no-link`
Non-blocking risk noted:
- The implementation is still fundamentally path/canonicalization based. It rejects static symlink/root escapes and uses Unix `O_NOFOLLOW` for final write target, but it does not fully eliminate adversarial external TOCTOU races where another local process mutates granted-root directories between checks and open/read/list/write. This is judged within the “feasible scope” of the initial subset and not a blocker for this Ticket, but should be preserved as future hardening context if the threat model expands.
Conclusion:
- Implementation satisfies the recorded Ticket acceptance criteria and is ready for merge/validation in the Orchestrator worktree.
---
<!-- event: review author: yoi-reviewer-00001KVFDX9AY at: 2026-06-19T16:09:17Z status: approve -->
## Review: approve
Review result: approve
対象:
- Ticket: `00001KVFDX9AY`
- branch: `impl/00001KVFDX9AY-plugin-fs-host-api`
- commit: `717c0999` (`plugin: implement fs host api`)
No blockers found.
Evidence reviewed:
- FS grant schema is explicit and additive: `PluginGrantConfig.fs`, `PluginFsGrant { root, operations }`, and `PluginFsOperation::{read,list,write}` in `crates/manifest/src/plugin.rs`. Existing HTTPS grant shape remains separate.
- Runtime dispatch checks `host_api.fs` before request parsing reaches any filesystem operation: `execute_plugin_fs_request` bounds descriptor size, then calls `authorize_plugin_host_api(record, PluginHostApi::Fs)` before read/list/write dispatch.
- Permission/grant binding is layered correctly:
- requested `host_api.fs` permission required;
- configured grant permission required;
- usable FS scope required;
- per-operation grants checked in `authorize_fs_path` / `authorize_fs_write_path`.
- No ambient WASI/workspace filesystem authority is exposed. WASM import validation only allows `yoi:tool`, `yoi:https`, and `yoi:fs`; WASI remains rejected. Runtime FS is only through `yoi:fs` imports.
- Path safety is materially addressed:
- absolute paths, NULs, and `..` traversal rejected;
- grant root must be absolute, existing, directory, and not final symlink;
- request path components are symlink-checked;
- canonicalized targets must remain under the canonical grant root;
- write target symlinks/dirs rejected;
- Unix writes add `O_NOFOLLOW`.
- Bounds are explicit:
- request descriptor, path, read bytes, write bytes, list entry count, and diagnostics are bounded/redacted;
- read/list truncation is explicit via `truncated`;
- oversize write fails closed.
- Writes serialize by normalized/canonical target with a shared lock map and use truncate/create with `sync_all`.
- Diagnostics use `PluginFsError::new` with `bounded_message(redact_secret_like(...))`; tests verify secret-like path redaction and no file-content leakage on denial.
- FS responses flow through WASM host response buffers and then ordinary plugin Tool output/error handling; no hidden context/history injection path found.
- CLI inspection reports `configured_fs_grants` alongside existing permission/HTTPS grant inspection without changing HTTPS semantics.
Reviewer validation:
- Static review of changed files and relevant tests.
- Confirmed worktree branch/head.
- `git diff --check 717c0999^..717c0999` — passed.
- Orchestrator-reported validation was reviewed:
- `cargo fmt --check`
- `cargo check -p pod -p manifest -p yoi`
- `cargo test -p pod feature::plugin`
- `cargo test -p manifest plugin`
- `cargo test -p yoi plugin_cli`
- `git diff --check`
- `nix build .#yoi --no-link`
Non-blocking risk noted:
- The implementation is still fundamentally path/canonicalization based. It rejects static symlink/root escapes and uses Unix `O_NOFOLLOW` for final write target, but it does not fully eliminate adversarial external TOCTOU races where another local process mutates granted-root directories between checks and open/read/list/write. This is judged within the feasible scope of the initial subset and not a blocker for this Ticket, but should be preserved as future hardening context if the threat model expands.
Conclusion:
- Implementation satisfies the recorded Ticket acceptance criteria and is ready for merge/validation in the Orchestrator worktree.
---
<!-- event: review author: yoi-reviewer-00001KVFDX9AY at: 2026-06-19T16:09:50Z status: approve -->
## Review: approve
Review result: approve
対象:
- Ticket: `00001KVFDX9AY`
- branch: `impl/00001KVFDX9AY-plugin-fs-host-api`
- commit: `717c0999` (`plugin: implement fs host api`)
No blockers found.
Evidence reviewed:
- FS grant schema is explicit and additive: `PluginGrantConfig.fs`, `PluginFsGrant { root, operations }`, and `PluginFsOperation::{read,list,write}` in `crates/manifest/src/plugin.rs`. Existing HTTPS grant shape remains separate.
- Runtime dispatch checks `host_api.fs` before request parsing reaches any filesystem operation: `execute_plugin_fs_request` bounds descriptor size, then calls `authorize_plugin_host_api(record, PluginHostApi::Fs)` before read/list/write dispatch.
- Permission/grant binding is layered correctly:
- requested `host_api.fs` permission required;
- configured grant permission required;
- usable FS scope required;
- per-operation grants checked in `authorize_fs_path` / `authorize_fs_write_path`.
- No ambient WASI/workspace filesystem authority is exposed. WASM import validation only allows `yoi:tool`, `yoi:https`, and `yoi:fs`; WASI remains rejected. Runtime FS is only through `yoi:fs` imports.
- Path safety is materially addressed:
- absolute paths, NULs, and `..` traversal rejected;
- grant root must be absolute, existing, directory, and not final symlink;
- request path components are symlink-checked;
- canonicalized targets must remain under the canonical grant root;
- write target symlinks/dirs rejected;
- Unix writes add `O_NOFOLLOW`.
- Bounds are explicit:
- request descriptor, path, read bytes, write bytes, list entry count, and diagnostics are bounded/redacted;
- read/list truncation is explicit via `truncated`;
- oversize write fails closed.
- Writes serialize by normalized/canonical target with a shared lock map and use truncate/create with `sync_all`.
- Diagnostics use `PluginFsError::new` with `bounded_message(redact_secret_like(...))`; tests verify secret-like path redaction and no file-content leakage on denial.
- FS responses flow through WASM host response buffers and then ordinary plugin Tool output/error handling; no hidden context/history injection path found.
- CLI inspection reports `configured_fs_grants` alongside existing permission/HTTPS grant inspection without changing HTTPS semantics.
Reviewer validation:
- Static review of changed files and relevant tests.
- Confirmed worktree branch/head.
- `git diff --check 717c0999^..717c0999` — passed.
- Orchestrator-reported validation was reviewed:
- `cargo fmt --check`
- `cargo check -p pod -p manifest -p yoi`
- `cargo test -p pod feature::plugin`
- `cargo test -p manifest plugin`
- `cargo test -p yoi plugin_cli`
- `git diff --check`
- `nix build .#yoi --no-link`
Non-blocking risk noted:
- The implementation is still fundamentally path/canonicalization based. It rejects static symlink/root escapes and uses Unix `O_NOFOLLOW` for final write target, but it does not fully eliminate adversarial external TOCTOU races where another local process mutates granted-root directories between checks and open/read/list/write. This is judged within the feasible scope of the initial subset and not a blocker for this Ticket, but should be preserved as future hardening context if the threat model expands.
Conclusion:
- Implementation satisfies the recorded Ticket acceptance criteria and is ready for merge/validation in the Orchestrator worktree.
---
<!-- event: review author: yoi-reviewer-00001KVFDX9AY at: 2026-06-19T16:10:26Z status: approve -->
## Review: approve
Review result: approve
対象:
- Ticket: `00001KVFDX9AY`
- branch: `impl/00001KVFDX9AY-plugin-fs-host-api`
- commit: `717c0999` (`plugin: implement fs host api`)
No blockers found.
Evidence reviewed:
- FS grant schema is explicit and additive: `PluginGrantConfig.fs`, `PluginFsGrant { root, operations }`, and `PluginFsOperation::{read,list,write}` in `crates/manifest/src/plugin.rs`. Existing HTTPS grant shape remains separate.
- Runtime dispatch checks `host_api.fs` before request parsing reaches any filesystem operation: `execute_plugin_fs_request` bounds descriptor size, then calls `authorize_plugin_host_api(record, PluginHostApi::Fs)` before read/list/write dispatch.
- Permission/grant binding is layered correctly:
- requested `host_api.fs` permission required;
- configured grant permission required;
- usable FS scope required;
- per-operation grants checked in `authorize_fs_path` / `authorize_fs_write_path`.
- No ambient WASI/workspace filesystem authority is exposed. WASM import validation only allows `yoi:tool`, `yoi:https`, and `yoi:fs`; WASI remains rejected. Runtime FS is only through `yoi:fs` imports.
- Path safety is materially addressed:
- absolute paths, NULs, and `..` traversal rejected;
- grant root must be absolute, existing, directory, and not final symlink;
- request path components are symlink-checked;
- canonicalized targets must remain under the canonical grant root;
- write target symlinks/dirs rejected;
- Unix writes add `O_NOFOLLOW`.
- Bounds are explicit:
- request descriptor, path, read bytes, write bytes, list entry count, and diagnostics are bounded/redacted;
- read/list truncation is explicit via `truncated`;
- oversize write fails closed.
- Writes serialize by normalized/canonical target with a shared lock map and use truncate/create with `sync_all`.
- Diagnostics use `PluginFsError::new` with `bounded_message(redact_secret_like(...))`; tests verify secret-like path redaction and no file-content leakage on denial.
- FS responses flow through WASM host response buffers and then ordinary plugin Tool output/error handling; no hidden context/history injection path found.
- CLI inspection reports `configured_fs_grants` alongside existing permission/HTTPS grant inspection without changing HTTPS semantics.
Reviewer validation:
- Static review of changed files and relevant tests.
- Confirmed worktree branch/head.
- `git diff --check 717c0999^..717c0999` — passed.
- Orchestrator-reported validation was reviewed:
- `cargo fmt --check`
- `cargo check -p pod -p manifest -p yoi`
- `cargo test -p pod feature::plugin`
- `cargo test -p manifest plugin`
- `cargo test -p yoi plugin_cli`
- `git diff --check`
- `nix build .#yoi --no-link`
Non-blocking risk noted:
- The implementation is still fundamentally path/canonicalization based. It rejects static symlink/root escapes and uses Unix `O_NOFOLLOW` for final write target, but it does not fully eliminate adversarial external TOCTOU races where another local process mutates granted-root directories between checks and open/read/list/write. This is judged within the feasible scope of the initial subset and not a blocker for this Ticket, but should be preserved as future hardening context if the threat model expands.
Conclusion:
- Implementation satisfies the recorded Ticket acceptance criteria and is ready for merge/validation in the Orchestrator worktree.
---
<!-- event: review author: yoi-reviewer-00001KVFDX9AY at: 2026-06-19T16:11:01Z status: approve -->
## Review: approve
Review result: approve
対象:
- Ticket: `00001KVFDX9AY`
- branch: `impl/00001KVFDX9AY-plugin-fs-host-api`
- commit: `717c0999` (`plugin: implement fs host api`)
No blockers found.
Evidence reviewed:
- FS grant schema is explicit and additive: `PluginGrantConfig.fs`, `PluginFsGrant { root, operations }`, and `PluginFsOperation::{read,list,write}` in `crates/manifest/src/plugin.rs`. Existing HTTPS grant shape remains separate.
- Runtime dispatch checks `host_api.fs` before request parsing reaches any filesystem operation: `execute_plugin_fs_request` bounds descriptor size, then calls `authorize_plugin_host_api(record, PluginHostApi::Fs)` before read/list/write dispatch.
- Permission/grant binding is layered correctly:
- requested `host_api.fs` permission required;
- configured grant permission required;
- usable FS scope required;
- per-operation grants checked in `authorize_fs_path` / `authorize_fs_write_path`.
- No ambient WASI/workspace filesystem authority is exposed. WASM import validation only allows `yoi:tool`, `yoi:https`, and `yoi:fs`; WASI remains rejected. Runtime FS is only through `yoi:fs` imports.
- Path safety is materially addressed:
- absolute paths, NULs, and `..` traversal rejected;
- grant root must be absolute, existing, directory, and not final symlink;
- request path components are symlink-checked;
- canonicalized targets must remain under the canonical grant root;
- write target symlinks/dirs rejected;
- Unix writes add `O_NOFOLLOW`.
- Bounds are explicit:
- request descriptor, path, read bytes, write bytes, list entry count, and diagnostics are bounded/redacted;
- read/list truncation is explicit via `truncated`;
- oversize write fails closed.
- Writes serialize by normalized/canonical target with a shared lock map and use truncate/create with `sync_all`.
- Diagnostics use `PluginFsError::new` with `bounded_message(redact_secret_like(...))`; tests verify secret-like path redaction and no file-content leakage on denial.
- FS responses flow through WASM host response buffers and then ordinary plugin Tool output/error handling; no hidden context/history injection path found.
- CLI inspection reports `configured_fs_grants` alongside existing permission/HTTPS grant inspection without changing HTTPS semantics.
Reviewer validation:
- Static review of changed files and relevant tests.
- Confirmed worktree branch/head.
- `git diff --check 717c0999^..717c0999` — passed.
- Orchestrator-reported validation was reviewed:
- `cargo fmt --check`
- `cargo check -p pod -p manifest -p yoi`
- `cargo test -p pod feature::plugin`
- `cargo test -p manifest plugin`
- `cargo test -p yoi plugin_cli`
- `git diff --check`
- `nix build .#yoi --no-link`
Non-blocking risk noted:
- The implementation is still fundamentally path/canonicalization based. It rejects static symlink/root escapes and uses Unix `O_NOFOLLOW` for final write target, but it does not fully eliminate adversarial external TOCTOU races where another local process mutates granted-root directories between checks and open/read/list/write. This is judged within the feasible scope of the initial subset and not a blocker for this Ticket, but should be preserved as future hardening context if the threat model expands.
Conclusion:
- Implementation satisfies the recorded Ticket acceptance criteria and is ready for merge/validation in the Orchestrator worktree.
---
<!-- event: review author: yoi-reviewer-00001KVFDX9AY at: 2026-06-19T16:11:47Z status: approve -->
## Review: approve
Review result: approve
対象:
- Ticket: `00001KVFDX9AY`
- branch: `impl/00001KVFDX9AY-plugin-fs-host-api`
- commit: `717c0999` (`plugin: implement fs host api`)
No blockers found.
Evidence reviewed:
- FS grant schema is explicit and additive: `PluginGrantConfig.fs`, `PluginFsGrant { root, operations }`, and `PluginFsOperation::{read,list,write}` in `crates/manifest/src/plugin.rs`. Existing HTTPS grant shape remains separate.
- Runtime dispatch checks `host_api.fs` before request parsing reaches any filesystem operation: `execute_plugin_fs_request` bounds descriptor size, then calls `authorize_plugin_host_api(record, PluginHostApi::Fs)` before read/list/write dispatch.
- Permission/grant binding is layered correctly:
- requested `host_api.fs` permission required;
- configured grant permission required;
- usable FS scope required;
- per-operation grants checked in `authorize_fs_path` / `authorize_fs_write_path`.
- No ambient WASI/workspace filesystem authority is exposed. WASM import validation only allows `yoi:tool`, `yoi:https`, and `yoi:fs`; WASI remains rejected. Runtime FS is only through `yoi:fs` imports.
- Path safety is materially addressed:
- absolute paths, NULs, and `..` traversal rejected;
- grant root must be absolute, existing, directory, and not final symlink;
- request path components are symlink-checked;
- canonicalized targets must remain under the canonical grant root;
- write target symlinks/dirs rejected;
- Unix writes add `O_NOFOLLOW`.
- Bounds are explicit:
- request descriptor, path, read bytes, write bytes, list entry count, and diagnostics are bounded/redacted;
- read/list truncation is explicit via `truncated`;
- oversize write fails closed.
- Writes serialize by normalized/canonical target with a shared lock map and use truncate/create with `sync_all`.
- Diagnostics use `PluginFsError::new` with `bounded_message(redact_secret_like(...))`; tests verify secret-like path redaction and no file-content leakage on denial.
- FS responses flow through WASM host response buffers and then ordinary plugin Tool output/error handling; no hidden context/history injection path found.
- CLI inspection reports `configured_fs_grants` alongside existing permission/HTTPS grant inspection without changing HTTPS semantics.
Reviewer validation:
- Static review of changed files and relevant tests.
- Confirmed worktree branch/head.
- `git diff --check 717c0999^..717c0999` — passed.
- Orchestrator-reported validation was reviewed:
- `cargo fmt --check`
- `cargo check -p pod -p manifest -p yoi`
- `cargo test -p pod feature::plugin`
- `cargo test -p manifest plugin`
- `cargo test -p yoi plugin_cli`
- `git diff --check`
- `nix build .#yoi --no-link`
Non-blocking risk noted:
- The implementation is still fundamentally path/canonicalization based. It rejects static symlink/root escapes and uses Unix `O_NOFOLLOW` for final write target, but it does not fully eliminate adversarial external TOCTOU races where another local process mutates granted-root directories between checks and open/read/list/write. This is judged within the feasible scope of the initial subset and not a blocker for this Ticket, but should be preserved as future hardening context if the threat model expands.
Conclusion:
- Implementation satisfies the recorded Ticket acceptance criteria and is ready for merge/validation in the Orchestrator worktree.
---
<!-- event: review author: yoi-reviewer-00001KVFDX9AY at: 2026-06-19T16:12:41Z status: approve -->
## Review: approve
Review result: approve
対象:
- Ticket: `00001KVFDX9AY`
- branch: `impl/00001KVFDX9AY-plugin-fs-host-api`
- commit: `717c0999` (`plugin: implement fs host api`)
No blockers found.
Evidence reviewed:
- FS grant schema is explicit and additive: `PluginGrantConfig.fs`, `PluginFsGrant { root, operations }`, and `PluginFsOperation::{read,list,write}` in `crates/manifest/src/plugin.rs`. Existing HTTPS grant shape remains separate.
- Runtime dispatch checks `host_api.fs` before request parsing reaches any filesystem operation: `execute_plugin_fs_request` bounds descriptor size, then calls `authorize_plugin_host_api(record, PluginHostApi::Fs)` before read/list/write dispatch.
- Permission/grant binding is layered correctly:
- requested `host_api.fs` permission required;
- configured grant permission required;
- usable FS scope required;
- per-operation grants checked in `authorize_fs_path` / `authorize_fs_write_path`.
- No ambient WASI/workspace filesystem authority is exposed. WASM import validation only allows `yoi:tool`, `yoi:https`, and `yoi:fs`; WASI remains rejected. Runtime FS is only through `yoi:fs` imports.
- Path safety is materially addressed:
- absolute paths, NULs, and `..` traversal rejected;
- grant root must be absolute, existing, directory, and not final symlink;
- request path components are symlink-checked;
- canonicalized targets must remain under the canonical grant root;
- write target symlinks/dirs rejected;
- Unix writes add `O_NOFOLLOW`.
- Bounds are explicit:
- request descriptor, path, read bytes, write bytes, list entry count, and diagnostics are bounded/redacted;
- read/list truncation is explicit via `truncated`;
- oversize write fails closed.
- Writes serialize by normalized/canonical target with a shared lock map and use truncate/create with `sync_all`.
- Diagnostics use `PluginFsError::new` with `bounded_message(redact_secret_like(...))`; tests verify secret-like path redaction and no file-content leakage on denial.
- FS responses flow through WASM host response buffers and then ordinary plugin Tool output/error handling; no hidden context/history injection path found.
- CLI inspection reports `configured_fs_grants` alongside existing permission/HTTPS grant inspection without changing HTTPS semantics.
Reviewer validation:
- Static review of changed files and relevant tests.
- Confirmed worktree branch/head.
- `git diff --check 717c0999^..717c0999` — passed.
- Orchestrator-reported validation was reviewed:
- `cargo fmt --check`
- `cargo check -p pod -p manifest -p yoi`
- `cargo test -p pod feature::plugin`
- `cargo test -p manifest plugin`
- `cargo test -p yoi plugin_cli`
- `git diff --check`
- `nix build .#yoi --no-link`
Non-blocking risk noted:
- The implementation is still fundamentally path/canonicalization based. It rejects static symlink/root escapes and uses Unix `O_NOFOLLOW` for final write target, but it does not fully eliminate adversarial external TOCTOU races where another local process mutates granted-root directories between checks and open/read/list/write. This is judged within the feasible scope of the initial subset and not a blocker for this Ticket, but should be preserved as future hardening context if the threat model expands.
Conclusion:
- Implementation satisfies the recorded Ticket acceptance criteria and is ready for merge/validation in the Orchestrator worktree.
---
<!-- event: implementation_report author: yoi-orchestrator at: 2026-06-19T16:14:42Z -->
## Implementation report
Merge / validation report:
Implementation branch `impl/00001KVFDX9AY-plugin-fs-host-api` を Orchestrator worktree の `orchestration` branch に merge 済み。
Merge:
- merge commit: `c94e157b``merge: plugin fs host api`
- implementation commit:
- `717c0999``plugin: implement fs host api`
- changed files:
- `crates/manifest/src/plugin.rs`
- `crates/pod/src/feature/plugin.rs`
- `crates/yoi/src/plugin_cli.rs`
Validation in Orchestrator worktree after merge:
- `cargo fmt --check` — passed
- `cargo check -p pod -p manifest -p yoi` — passed
- `cargo test -p pod feature::plugin -- --nocapture` — passed; 48 passed, 0 failed
- `cargo test -p manifest plugin -- --nocapture` — passed; 17 passed, 0 failed
- `cargo test -p yoi plugin_cli -- --nocapture` — passed; 10 passed, 0 failed
- `git diff --check` — passed
- `nix build .#yoi --no-link` — passed
Review:
- Reviewer `yoi-reviewer-00001KVFDX9AY` returned `approve` with no blockers.
- Reviewer noted a non-blocking future hardening context: this implementation is path/canonicalization based and does not fully eliminate adversarial external TOCTOU races where another local process mutates granted-root directories between checks and open/read/list/write. This is accepted within the feasible scope of the initial subset.
Outcome:
- Granted scoped filesystem `fs` host API is implemented for WASM Plugin Tools.
- Missing `host_api.fs` grant denies before filesystem access.
- Workspace/POD filesystem authority is not inherited by Plugin without Plugin grant.
- Path traversal / symlink / root escape protections, read/list/write bounds, write serialization, diagnostics redaction, ordinary Tool result path, and CLI inspection compatibility are present.
- HTTPS host API and Component Model migration remain non-goals for this Ticket.
- Root/original workspace was not read/written/merged/validated for this Ticket, per Panel Queue instruction.
---
<!-- event: review author: yoi-reviewer-00001KVFDX9AY at: 2026-06-19T16:15:17Z status: approve -->
## Review: approve
Review result: approve
対象:
- Ticket: `00001KVFDX9AY`
- branch: `impl/00001KVFDX9AY-plugin-fs-host-api`
- commit: `717c0999` (`plugin: implement fs host api`)
No blockers found.
Evidence reviewed:
- FS grant schema is explicit and additive: `PluginGrantConfig.fs`, `PluginFsGrant { root, operations }`, and `PluginFsOperation::{read,list,write}` in `crates/manifest/src/plugin.rs`. Existing HTTPS grant shape remains separate.
- Runtime dispatch checks `host_api.fs` before request parsing reaches any filesystem operation: `execute_plugin_fs_request` bounds descriptor size, then calls `authorize_plugin_host_api(record, PluginHostApi::Fs)` before read/list/write dispatch.
- Permission/grant binding is layered correctly:
- requested `host_api.fs` permission required;
- configured grant permission required;
- usable FS scope required;
- per-operation grants checked in `authorize_fs_path` / `authorize_fs_write_path`.
- No ambient WASI/workspace filesystem authority is exposed. WASM import validation only allows `yoi:tool`, `yoi:https`, and `yoi:fs`; WASI remains rejected. Runtime FS is only through `yoi:fs` imports.
- Path safety is materially addressed:
- absolute paths, NULs, and `..` traversal rejected;
- grant root must be absolute, existing, directory, and not final symlink;
- request path components are symlink-checked;
- canonicalized targets must remain under the canonical grant root;
- write target symlinks/dirs rejected;
- Unix writes add `O_NOFOLLOW`.
- Bounds are explicit:
- request descriptor, path, read bytes, write bytes, list entry count, and diagnostics are bounded/redacted;
- read/list truncation is explicit via `truncated`;
- oversize write fails closed.
- Writes serialize by normalized/canonical target with a shared lock map and use truncate/create with `sync_all`.
- Diagnostics use `PluginFsError::new` with `bounded_message(redact_secret_like(...))`; tests verify secret-like path redaction and no file-content leakage on denial.
- FS responses flow through WASM host response buffers and then ordinary plugin Tool output/error handling; no hidden context/history injection path found.
- CLI inspection reports `configured_fs_grants` alongside existing permission/HTTPS grant inspection without changing HTTPS semantics.
Reviewer validation:
- Static review of changed files and relevant tests.
- Confirmed worktree branch/head.
- `git diff --check 717c0999^..717c0999` — passed.
- Orchestrator-reported validation was reviewed:
- `cargo fmt --check`
- `cargo check -p pod -p manifest -p yoi`
- `cargo test -p pod feature::plugin`
- `cargo test -p manifest plugin`
- `cargo test -p yoi plugin_cli`
- `git diff --check`
- `nix build .#yoi --no-link`
Non-blocking risk noted:
- The implementation is still fundamentally path/canonicalization based. It rejects static symlink/root escapes and uses Unix `O_NOFOLLOW` for final write target, but it does not fully eliminate adversarial external TOCTOU races where another local process mutates granted-root directories between checks and open/read/list/write. This is judged within the feasible scope of the initial subset and not a blocker for this Ticket, but should be preserved as future hardening context if the threat model expands.
Conclusion:
- Implementation satisfies the recorded Ticket acceptance criteria and is ready for merge/validation in the Orchestrator worktree.
---
<!-- event: implementation_report author: yoi-orchestrator at: 2026-06-19T16:16:56Z -->
## Implementation report
Cleanup report:
Plugin FS host API Ticket の implementation/review Pods と child worktree を cleanup した。
Stopped Pods:
- `yoi-coder-00001KVFDX9AY`
- `yoi-reviewer-00001KVFDX9AY`
Removed child implementation worktree:
- `/home/hare/Projects/yoi/.worktree/00001KVFDX9AY-plugin-fs-host-api`
Deleted merged implementation branch:
- `impl/00001KVFDX9AY-plugin-fs-host-api` at `717c0999`
Orchestrator branch remains the integration authority for this completed work. Root/original workspace was not touched for this Ticket, per Panel Queue instruction.
---
<!-- event: state_changed author: yoi-orchestrator at: 2026-06-19T16:17:29Z from: inprogress to: done reason: merged_validated_review_approved field: state -->
## State changed
Implementation commit `717c0999` was reviewed and approved, merged into the Orchestrator branch as `c94e157b`, validated in the Orchestrator worktree, and child implementation resources were cleaned up. Requirements and acceptance criteria are satisfied for this Ticket. Root/original workspace was not operated on for this Ticket per Panel Queue instruction.
---
<!-- event: state_changed author: hare at: 2026-06-19T16:17:51Z from: done to: closed reason: closed field: state -->
## State changed
Ticket を closed にしました。
---
<!-- event: close author: hare at: 2026-06-19T16:17:51Z status: closed -->
## 完了
Ticket `00001KVFDX9AY` is complete.
Completed implementation:
- Added granted scoped filesystem `fs` host API for WASM Plugin Tools.
- Added `PluginFsGrant { root, operations }` and `PluginFsOperation::{read,list,write}` to the Plugin grant model.
- Implemented `yoi:fs` WASM host imports for read/list/write with response buffer handling.
- Enforced Plugin-specific grants before filesystem access; Plugin Tools do not inherit Pod/workspace filesystem authority.
- Added path safety for relative-only requests, traversal rejection, symlink/root escape rejection, canonical root checks, and Unix `O_NOFOLLOW` for writes.
- Added read/list/write bounds, explicit truncation/fail-closed behavior, write serialization by normalized/canonical target, and bounded/redacted diagnostics.
- Updated Plugin CLI inspection to show configured fs grants.
Reviewed / merged:
- Implementation commit: `717c0999` (`plugin: implement fs host api`)
- Reviewer result: approve, no blockers.
- Reviewer noted a non-blocking future hardening context: the current implementation is path/canonicalization based and does not fully eliminate adversarial external TOCTOU races where another local process mutates granted-root directories between checks and open/read/list/write. This is accepted within the feasible scope of the initial subset.
- Orchestrator merge commit: `c94e157b` (`merge: plugin fs host api`)
Validation in Orchestrator worktree:
- `cargo fmt --check` — passed
- `cargo check -p pod -p manifest -p yoi` — passed
- `cargo test -p pod feature::plugin -- --nocapture` — passed; 48 passed, 0 failed
- `cargo test -p manifest plugin -- --nocapture` — passed; 17 passed, 0 failed
- `cargo test -p yoi plugin_cli -- --nocapture` — passed; 10 passed, 0 failed
- `git diff --check` — passed
- `nix build .#yoi --no-link` — passed
Cleanup:
- Stopped Coder Pod `yoi-coder-00001KVFDX9AY`.
- Stopped Reviewer Pod `yoi-reviewer-00001KVFDX9AY`.
- Removed child worktree `/home/hare/Projects/yoi/.worktree/00001KVFDX9AY-plugin-fs-host-api`.
- Deleted merged branch `impl/00001KVFDX9AY-plugin-fs-host-api`.
Root/original workspace was not read/written/merged/validated for this Ticket, per Panel Queue instruction. The completed work is integrated on the Orchestrator branch.
---