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

48 KiB
Raw Blame History

作成

LocalTicketBackend によって作成されました。


State changed

Ticket を workspace-panel が queued にしました。


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 も再確認する。

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 は操作しない。

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.


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 を行い、実装報告を返す予定。

Implementation report

Coder implementation report received / Orchestrator validation:

Implementation commit:

  • 717c0999plugin: 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 を確認する。

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 に戻す。

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.

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.

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.

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.

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.

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.

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.

Implementation report

Merge / validation report:

Implementation branch impl/00001KVFDX9AY-plugin-fs-host-api を Orchestrator worktree の orchestration branch に merge 済み。

Merge:

  • merge commit: c94e157bmerge: plugin fs host api
  • implementation commit:
    • 717c0999plugin: 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.

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.

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.


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.


State changed

Ticket を 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.