yoi/.yoi/tickets/00001KVFDX9AF/thread.md

20 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 周辺に触れる。
  • 00001KVFDX9AY fs 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 する。
  • その時点で fs host API Ticket との ordering / conflict も再確認する。

Decision

Routing decision: implementation_ready

Reason:

  • Panel Queue により、この Ticket は Orchestrator routing 対象として明示許可された。
  • Ticket body には、HTTPS 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 は closed で blocker ではない。
  • Risk domain は network / secrets / host API / permission grants だが、Ticket は HTTPS-only、private/local target rejection、grant allowlist、bounded request/response/timeout/diagnostics、no ambient env/network、ordinary Tool result path を binding invariants として明示している。bounded context check 後も implementation 前に必要な追加 human decision は見つからなかった。
  • 同時 queued の 00001KVFDX9AY fs host API と 00001KVG0HR96 Component Model migration は Plugin runtime/grant/diagnostic/packaging surface が重なるため、waiting/conflict notes を更新し queued のまま待機する。

Evidence checked:

  • Ticket 00001KVFDX9AF body / thread / artifacts。
  • TicketRelationQuery(00001KVFDX9AF): depends_on は closed。related Ticket は context であり acceptance blocker ではない。
  • TicketOrchestrationPlanQuery(00001KVFDX9AF): 既存 waiting/do_not_parallelize records を確認。今回 accepted_plan を記録済み。
  • Related completed Tickets:
    • 00001KV5W3PHW — minimal WASM Tool runtime closed。
    • 00001KV5W3PJ3 — Plugin permission grants closed。
    • 00001KVFD3YSV — Plugin read-only CLI inspection closed。
  • Current queued Tickets:
    • 00001KVFDX9AY fs host API: do_not_parallelize / waiting reason を維持。
    • 00001KVG0HR96 Component Model migration: migration boundary / conflict waiting note を更新。
  • Orchestrator worktree /home/hare/Projects/yoi/.worktree/orchestration: clean。
  • Existing branch/worktree: matching 00001KVFDX9AF branch/worktree はなし。
  • Visible Pods: self / peer / intake only; spawned child capacity is free。
  • Current code map:
    • crates/pod/src/feature/plugin.rs: Plugin resolver, permission grants, static inspection, WASM tool feature。
    • crates/pod/src/pod.rs: WASM Tool runtime / run_plugin_wasm_tool / host import validation。
    • crates/manifest/src/plugin.rs: Plugin manifest and permission model。
    • crates/yoi/src/plugin_cli.rs: read-only inspection output should remain compatible with host API diagnostics。

IntentPacket:

Intent:

  • WASM Plugin Tool runtime に、明示 grant された outbound HTTPS request だけを実行できる https host API を追加する。
  • Plugin は ambient network access を持たず、host API import + requested permission + config grant + allowlist を満たす場合だけ bounded HTTPS request を実行できる。

Binding decisions / invariants:

  • Host API name/domain は httpsweb ではない。
  • HTTPS-only。http://、localhost、private IP、link-local、unix socket、file URL、local/private host targets は reject。
  • Grant がない場合、network access 前に fail closed。
  • host / method / optional path prefix などの allowlist を表現し、grant と request を照合する。
  • Request/response は bounded。
    • method allowlist
    • request body size bound
    • header count/size bound
    • response body size bound
    • timeout
    • redirect policy
  • Credentials は ambient env から読まない。header/auth は explicit config / secret ref 経由だけ。
  • Diagnostics に secret-like header/token/body content を漏らさない。
  • HTTPS response は hidden context injection ではなく ordinary Tool result/history path に残す。
  • fs host API、WebSocket/SSE/timers、Service/Ingress lifecycle、Plugin package manager は non-goals。

Requirements / acceptance criteria:

  • Granted Plugin Tool can perform an allowed HTTPS request through host API。
  • Missing host_api.https grant denies before network access。
  • Disallowed host / method / URL scheme denies。
  • http://, localhost, private IP, link-local, local/private host targets reject。
  • Timeout and response-size bounds are enforced。
  • Request/response diagnostics are bounded and redact secret-like values。
  • No ambient env credentials or ambient network APIs are exposed to WASM。
  • Tool result path remains ordinary Tool result/history path。
  • Tests cover allowed HTTPS, missing grant, disallowed host/method/scheme/private target, timeout, response truncation, secret redaction, no network without host API import/grant。

Implementation latitude:

  • Choose exact ABI/import shape consistent with existing yoi-plugin-wasm-1 host import design。
  • Choose narrow grant config representation for host/method/path allowlist consistent with current Plugin permission grant model。
  • Use local deterministic test server/mock if needed for allowed HTTPS/timeout/response bound tests, but keep network-safety tests deterministic。
  • Choose bounded response header/body representation that fits existing Tool result error/result types。

Escalate if:

  • Implementing HTTPS requires broad runtime executor redesign or Component Model migration first。
  • Secure host/method/path grant model cannot be represented without breaking existing permission grant schema。
  • SecretRef handling requires new secret-store public API beyond explicit config references。
  • Safe private/local-host rejection cannot be implemented deterministically enough for tests。
  • Host API result/error shape requires product-visible Tool result schema decision beyond this Ticket。

Validation:

  • Focused plugin HTTPS host API tests。
  • Relevant cargo test / cargo check for pod, manifest, yoi as changed。
  • cargo fmt --check
  • git diff --check
  • nix build .#yoi because dependency/package/network code may change。

Critical risks / reviewer focus:

  • Network access before grant/allowlist checks。
  • Private/local/localhost bypass through DNS, redirects, IPv6, encoded URLs, or scheme confusion。
  • Secret leakage in diagnostics or Tool result/history。
  • Ambient env credential usage。
  • Unbounded request/response bodies or headers。
  • Hidden context injection by bypassing normal Tool result path。
  • Breaking existing Plugin permission grant enforcement 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 host API code context were checked. Depends-on blockers are closed, prior CLI inspection related work is closed, and no dirty-state blocker or missing planning decision was found. fs host API and Component Model migration remain queued with conflict/migration waiting records. Accepting this queued Ticket for implementation before worktree/Pod side effects.


Implementation report

Implementation start note:

queued -> inprogress acceptance、accepted plan、routing decision / IntentPacket、fs host API / Component Model migration の waiting records を記録し、Orchestrator worktree で commit した後に、専用 implementation worktree と Coder Pod を起動した。

Worktree:

  • /home/hare/Projects/yoi/.worktree/00001KVFDX9AF-plugin-https-host-api
  • branch: impl/00001KVFDX9AF-plugin-https-host-api

Coder Pod:

  • yoi-coder-00001KVFDX9AF

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 Tickets:

  • 00001KVFDX9AY fs host API remains queued due existing do_not_parallelize / conflict with HTTPS host API.
  • 00001KVG0HR96 Component Model migration remains queued due migration boundary / conflict with active host API work.

Next:

  • Coder は granted HTTPS host API implementation、focused tests、validation、implementation commit を行い、実装報告を返す予定。

Implementation report

Coder implementation report received / Orchestrator validation:

Implementation commit:

  • 73775275plugin: implement https host api

Summary:

  • Added typed HTTPS host API grant scope to Plugin permission model:
    • hosts
    • methods
    • optional path prefixes
    • bounded request/response options
  • Implemented yoi:https WASM host import handling in the Plugin Tool runtime。
  • Added deterministic local TLS / HTTPS test harness for runtime tests。
  • Added URL validation / network safety checks:
    • HTTPS-only;
    • reject http://;
    • reject localhost/private/link-local/local targets;
    • reject disallowed hosts/methods/schemes before network access。
  • Added request/response bounds and diagnostics:
    • body/header limits;
    • response truncation;
    • timeout;
    • bounded/redacted error messages。
  • Preserved no ambient env credentials and ordinary Tool result/history path semantics。
  • Updated read-only Plugin CLI inspection so HTTPS host API grant details / diagnostics remain inspectable。
  • Updated package.nix cargo hash for new dependency/build closure.

Files changed:

  • Cargo.lock
  • crates/manifest/src/plugin.rs
  • crates/pod/Cargo.toml
  • crates/pod/src/feature/plugin.rs
  • crates/pod/src/pod.rs
  • crates/yoi/src/plugin_cli.rs
  • package.nix

Coder reported validation:

  • cargo fmt --check — passed
  • cargo check -p pod -p manifest -p yoi — passed
  • cargo test -p pod feature::plugin::tests -- --nocapture — passed; 36 passed
  • cargo test -p manifest plugin -- --nocapture — passed; 17 passed
  • cargo test -p yoi plugin_cli -- --nocapture — passed; 10 passed
  • git diff --check — passed
  • nix build .#yoi --no-link — passed

Orchestrator evidence checked:

  • Pod output を確認。
  • implementation worktree は clean。
  • branch impl/00001KVFDX9AF-plugin-https-host-api HEAD は 73775275
  • diff stat from accepted base 1fdef32a..73775275: 7 files changed, 1799 insertions, 97 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::tests -- --nocapture — passed; 36 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 で外部レビューする。
  • 特に grant-before-network、private/local rejection、redirect/DNS bypass、bounds/timeouts、secret redaction、ordinary Tool result path、no ambient env credentials、CLI inspection compatibility、dependency/package.nix correctness を確認する。

Plan

Review dispatch:

Reviewer Pod yoi-reviewer-00001KVFDX9AF を read-only scope で起動した。

Review target:

  • worktree: /home/hare/Projects/yoi/.worktree/00001KVFDX9AF-plugin-https-host-api
  • branch: impl/00001KVFDX9AF-plugin-https-host-api
  • commit: 73775275

Reviewer focus:

  • recorded intent / invariants / acceptance criteria に対する適合性。
  • network access が grant/allowlist checks の前に発生しないこと。
  • private/local/localhost/link-local target rejection が DNS / IPv6 / redirect / scheme edge cases を含め妥当であること。
  • timeout / request-response size / header bounds が enforce されること。
  • secret-like values が errors / diagnostics / Tool results に漏れないこと。
  • ambient env credential / ambient network access path が WASM に exposed されていないこと。
  • HTTPS response が ordinary Tool result/history path だけに戻ること。
  • allowed HTTPS / missing grant / disallowed host-method-scheme-private target / timeout / truncation / redaction / no network without grant/import tests が意味を持つこと。
  • manifest/permission grant schema changes が existing grants / CLI inspection と整合していること。
  • Cargo.lock / package.nix update が妥当で、nix build .#yoi --no-link validation と整合していること。
  • fs host API と Component Model migration が non-goals として保たれていること。

Next:

  • Reviewer output を確認し、approve なら Orchestrator worktree への merge/validation/cleanup/close-ready 処理へ進む。request_changes なら blocker を記録して Coder に戻す。

Review: request changes

Review result: request_changes

対象:

  • Ticket: 00001KVFDX9AF
  • branch: impl/00001KVFDX9AF-plugin-https-host-api
  • commit: 7377527f (plugin: implement https host api)

Blockers:

  1. Private/local target rejection is bypassable with IPv4-mapped IPv6 literals.

    • validate_static_https_target parses the URL host as IpAddr and delegates IPv6 literals to is_forbidden_ipv6 (crates/pod/src/feature/plugin.rs:622-631, 665-669).
    • is_forbidden_ipv6 rejects loopback/unspecified/ULA/link-local/multicast (699-705) but does not check Ipv6Addr::to_ipv4_mapped() / IPv4-compatible forms.
    • Rust confirms ::ffff:127.0.0.1 is not is_loopback() as IPv6, while to_ipv4_mapped() is Some(127.0.0.1).
    • A granted request to https://[::ffff:127.0.0.1]/... would therefore pass the current private/local filter if the grant host matches, violating localhost/private IP rejection and the IPv6 edge-case reviewer focus.
  2. DNS private-address validation is TOCTOU and does not bind the checked address set to the actual connection.

    • ReqwestPluginHttpsClient::execute calls validate_dns_target(url) before constructing/sending the request (crates/pod/src/feature/plugin.rs:365-405).
    • validate_dns_target resolves with ToSocketAddrs and rejects private/local addresses in that returned set (641-655), but reqwest performs its own DNS resolution later during builder.send() (405).
    • DNS rebinding / split answers between the preflight lookup and reqwests lookup can pass validation on a public address then connect to a private/local address.
    • Ticket critical risks explicitly include DNS/private/local bypasses before network access.

Requested changes:

  • Reject IPv4-mapped IPv6 addresses by applying the existing IPv4 forbidden checks to mapped IPv4 addresses; add tests for mapped loopback/private/link-local examples.
  • Bind DNS validation to the actual connection path. Either pin validated public SocketAddrs into the reqwest client/request resolver path, or otherwise ensure the actual connected remote address is validated / not private.
  • Add deterministic test coverage around the real validation edge cases where feasible.

Supporting positive findings:

  • Grant checks happen before request parsing/DNS/network dispatch in execute_plugin_https_request, and WASM import validation denies yoi:https imports without requested/configured host_api.https grant before instantiation.
  • Scheme, embedded credentials, method allowlist, request descriptor/body/header count/size, response body/header bounds, timeout, no redirects, and no_proxy() are present.
  • WASM imports are narrow (yoi:tool, yoi:https only), WASI/ambient imports are rejected, and yoi:fs remains explicitly unimplemented.
  • Response path remains ordinary plugin Tool output/history path.
  • Manifest/CLI schema additions are mostly compatible: new PluginPermission::HostApi, PluginHttpsGrant, defaulted grants.https, and CLI display of configured HTTPS grants.

Test gap:

  • Current HTTPS-focused tests use MockHttpsClient for allowed/denied/timeout/truncation behavior. That is useful for grant ordering, but it does not exercise the real ReqwestPluginHttpsClient DNS filtering, redirect policy, TLS/HTTPS path, or actual timeout/read-limit behavior. Given the security-sensitive DNS/IP requirements, add coverage for the real validation edge cases above.

Plan

Review follow-up dispatch:

Reviewer yoi-reviewer-00001KVFDX9AFrequest_changes を返したため、Ticket review として記録し、既存 Coder Pod yoi-coder-00001KVFDX9AF に修正依頼を送った。

Blockers:

  1. IPv4-mapped IPv6 literals が private/local target rejection を bypass し得る。

    • ::ffff:127.0.0.1 などを IPv6 として見るだけでは loopback/private 判定に漏れる。
    • Ipv6Addr::to_ipv4_mapped() 等で mapped IPv4 を取り出し、既存 IPv4 forbidden checks を適用する必要がある。
  2. DNS private-address validation が TOCTOU で actual connection path に bind されていない。

    • preflight ToSocketAddrs validation 後に reqwest が別途 DNS resolution するため、DNS rebinding / split answers で public answer validation 後に private/local address へ接続し得る。
    • validated public SocketAddrs を reqwest client/request resolver path に pin する、または actual connected remote address を検証する必要がある。

Required fixes sent to Coder:

  • IPv4-mapped IPv6 addresses を mapped IPv4 として private/local/link-local/loopback checks に通す。
  • mapped loopback/private/link-local の tests を追加する。
  • DNS validation を actual connection path に bind する設計へ修正する。
  • DNS / actual connection edge の deterministic test coverage を追加する。
  • Prior positives を維持する: grant-before-network、WASM import grant validation、HTTPS-only、embedded credentials rejection、method allowlist、bounds、timeout、no redirects、no_proxy()、ordinary Tool result path、manifest/CLI schema compatibility。

Next:

  • Coder の修正 commit / validation report を待つ。
  • 修正後、network-safety edge cases と grant-before-network invariants を中心に再レビューする。