Skip to content

feat(channels): route plugin events through shared runtime#9143

Draft
JordanTheJet wants to merge 27 commits into
zeroclaw-labs:masterfrom
JordanTheJet:feat/plugin-typed-event-runtime
Draft

feat(channels): route plugin events through shared runtime#9143
JordanTheJet wants to merge 27 commits into
zeroclaw-labs:masterfrom
JordanTheJet:feat/plugin-typed-event-runtime

Conversation

@JordanTheJet

Copy link
Copy Markdown
Collaborator

Summary

  • Base branch: master. This is one review commit directly above feat(plugins): activate logical channel instances #8852; merge the plugin stack bottom-up.
  • What changed and why:
    • Connects the generic plugin event-router foundation to the ordinary channel runtime through a bounded typed request queue and per-request acknowledgement.
    • Resolves package, exact binding alias, configured owner, allowed sender, agent target, and optional SOP target from live host-owned declarations before enqueueing; the guest cannot inject routing authority into a ChannelMessage.
    • Dispatches each admitted event through the same agent/SOP path as built-in channels, with one exact route and no generic-agent fallback or duplicate SOP invocation.
    • Requires the production plugin runtime to receive a real shared dispatcher while health/test construction explicitly uses a non-dispatching path.
    • Adds focused queue/router/runtime tests and real Wasm component coverage for acknowledged success, denial, unavailable dispatch, exact alias attribution, and SOP selection.
  • Scope boundary: Process-local handoff only. This does not add webhook listeners, vendor protocol parsing, durable retry/outbox use, new routing config fields, a guest-selected agent/SOP, or a bundled production plugin.
  • Blast radius: Channel orchestration, plugin-channel runtime construction, the Wasmtime channel adapter, channel/plugin integration fixtures, and plugin protocol documentation.
  • Linked issue(s): Related Move optional channels & tools from compile-time feature flags to runtime plugins #8850. Depends on feat(plugins): activate logical channel instances #8852 and feat(plugins): add typed event routing foundation #9138.
  • Labels: enhancement, docs, core, channel, runtime, tests, runtime:wasm, risk:high, size:XL.

The isolated review slice is one commit and 11 files (+1,034/-48) above #8852. The generic router stays in zeroclaw-plugins; the channel crate owns only the bounded handoff into its existing dispatcher.

Testing (required)

How you can test (when useful)

  • Reviewer testing requested? Yes.
  • Interface(s) exercised: channel.
  • Setup / preconditions: Rust with wasm32-wasip2; no vendor account or external network is required.
  • Steps to run: cargo test --locked -p zeroclaw-channels --lib --features plugins-wasm, cargo test --locked -p zeroclaw-plugins --features plugins-wasm-cranelift --test channel_plugin_e2e, and cargo test --locked --features plugins-wasm-cranelift --test plugin_channel_runtime_e2e.
  • Expected on this branch (after): The full channel library passes; a real component submits an event whose route is host-resolved and acknowledged through the shared dispatcher; denied or unavailable routes fail closed without a fallback dispatch.
  • Prior behavior on master (before): Plugin channels can be activated but have no production bridge from typed guest events into the shared agent/SOP dispatcher.

How I tested

  • CI checks relied on and why they cover this change: None yet; this draft starts fresh exact-head CI. Local validation covers the complete channel library, generic event router, runtime activation, strict lint, and two real component boundaries.
  • Known CI coverage gap, if any: No external vendor transport or live SOP side effect was used. Synthetic agents/SOPs exercise exact resolution and dispatch without credentials.
  • Commands run and tail output:
$ cargo test --locked -p zeroclaw-channels --lib --features plugins-wasm
test result: ok. 1248 passed; 0 failed; 1 ignored (credential-gated)

$ cargo test --locked -p zeroclaw-plugins --features plugins-wasm-cranelift --test channel_plugin_e2e
test result: ok. 5 passed; 0 failed

$ cargo test --locked --features plugins-wasm-cranelift --test plugin_channel_runtime_e2e
test result: ok. 1 passed; 0 failed

$ cargo test --locked -p zeroclaw-plugins event::tests --lib
test result: ok. 6 passed; 0 failed

$ cargo test --locked -p zeroclaw-runtime --features plugins-wasm plugin_runtime --lib
test result: ok. 4 passed; 0 failed

$ cargo clippy --locked -p zeroclaw-channels --lib --features plugins-wasm -- -D warnings
$ cargo clippy --locked -p zeroclaw-plugins --all-targets --features plugins-wasm-cranelift -- -D warnings
$ cargo clippy --locked -p zeroclaw-plugins -p zeroclaw-runtime --lib --features zeroclaw-runtime/plugins-wasm -- -D warnings
Finished `dev` profile; no warnings

$ cargo fmt --all -- --check
$ git diff --check
$ git show --check
# clean
  • Beyond CI, what did you manually verify? I traced one event from the exact admitted PluginInstanceId through live declaration/owner/sender/agent/SOP resolution, queue reservation, shared dispatch, and the matching acknowledgement. I also confirmed routing fields are not read from guest messages, there is no generic fallback or second SOP pass, and unavailable dispatch never reports success.
  • If any command was intentionally skipped, why: Full workspace and live-vendor tests were not duplicated; the full channel crate and real plugin components cover the changed integration boundary.

Security & Privacy Impact (required)

  • New permissions, capabilities, or file system access scope? No. Existing admitted channel instances and host-owned declarations determine authority.
  • New external network calls? No.
  • Secrets / tokens / credentials handling changed? No.
  • PII, real identities, or personal data in diff, tests, fixtures, or docs? No. Fixtures use synthetic identifiers.
  • Prompt injection or untrusted model-visible text introduced/changed? Yes. Plugin-originated channel content can now reach the shared agent/SOP path. The host stamps the instance identity, resolves owner/sender/targets live, rejects unauthorized senders before enqueue, and never accepts guest routing fields.
  • If any Yes, describe the risk and mitigation: The primary risks are sender/alias spoofing, cross-agent delivery, fallback dispatch, duplicate SOP execution, queue exhaustion, and false success during cancellation. Mitigations are exact structural identity, live fail-closed resolution, typed routes, a bounded queue, one request/one acknowledgement, and a single shared dispatch pass.

Compatibility (required)

  • Backward compatible? Yes. This wires the experimental plugin runtime internally; built-in channels and inactive plugin builds retain their existing paths.
  • Config / env / CLI surface changed? No.
  • Rust/MSRV/toolchain floor changed? No.
  • If backward compatibility is No or either surface/floor question is Yes: N/A.

Rollback (required for medium/high-risk PRs)

  • Fast rollback command/path: git revert dc15bf35 before squash merge, or revert the eventual squash commit.
  • Feature flags or config toggles: Build without plugins-wasm, or disable the plugin channel instance.
  • Observable failure symptoms: Plugin-event queue unavailable/full errors, denied sender/route errors, dropped acknowledgements, plugin channel health failure, missing agent/SOP dispatch, or a duplicated SOP side effect.

Keep the canonical tool field keyed by the exported callable name while retaining package, capability, and binding identity on the host-issued scope. Also keep no-Wasmtime builds warning-free.
Document HTTP authority as the intersection of an admitted grant and a capability adapter with a tested host surface. Tool and channel opt in; memory remains HTTP-free.
Expose the runtime feature decision once and consume it in the canonical channel inventory so list/self-test distinguish a compiled plugin family from a configured-but-unavailable one.
@JordanTheJet JordanTheJet added enhancement New feature or request docs Auto scope: docs/markdown/template files changed. core Auto scope: root src/*.rs files changed. channel Auto scope: src/channels/** changed. labels Jul 18, 2026
@JordanTheJet JordanTheJet added runtime Auto scope: src/runtime/** changed. tests Auto scope: tests/** changed. runtime:wasm Auto module: runtime/wasm changed. risk:high Auto risk: security/runtime/gateway/tools/workflows. size:XL Auto size: more than 1000 non-doc changed lines. labels Jul 18, 2026
@github-actions github-actions Bot added ci Auto scope: CI/workflow/hook files changed. dependencies Auto scope: dependency manifest/lock/policy changed. config Auto scope: src/config/** changed. cron Auto scope: src/cron/** changed. skills Auto scope: src/skills/** changed. tool Auto scope: src/tools/** changed. channel:core Auto module: channel core files changed. security:secrets Auto module: security/secrets changed. labels Jul 18, 2026
@JordanTheJet
JordanTheJet force-pushed the feat/plugin-typed-event-runtime branch from dc15bf3 to 560626a Compare July 18, 2026 11:11
@JordanTheJet

Copy link
Copy Markdown
Collaborator Author

Updated the draft branch to fix the workspace CI Clippy failure by using ZeroClaw's attributed spawn helper in the event-dispatch acknowledgement test.

  • New head: 560626afddbce507c39b39ea4dde4b4560cbc620
  • Preserved prior head: backup/plugin-typed-event-runtime-pre-clippy-20260718 (dc15bf3569f5790a459cb561c05da244707819b5)
  • Reproduced the failure locally, then passed the exact CI lint command: cargo clippy --workspace --exclude zeroclaw-desktop --all-targets --features ci-all -- -D warnings
  • cargo fmt --all -- --check and git diff --check also pass.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel:core Auto module: channel core files changed. channel Auto scope: src/channels/** changed. ci Auto scope: CI/workflow/hook files changed. config Auto scope: src/config/** changed. core Auto scope: root src/*.rs files changed. cron Auto scope: src/cron/** changed. dependencies Auto scope: dependency manifest/lock/policy changed. docs Auto scope: docs/markdown/template files changed. enhancement New feature or request risk:high Auto risk: security/runtime/gateway/tools/workflows. runtime:wasm Auto module: runtime/wasm changed. runtime Auto scope: src/runtime/** changed. security:secrets Auto module: security/secrets changed. size:XL Auto size: more than 1000 non-doc changed lines. skills Auto scope: src/skills/** changed. tests Auto scope: tests/** changed. tool Auto scope: src/tools/** changed.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant