# `@suaveplan/api-events-worker-proxy` — worker-side proxy to main-process `@suaveplan/events` bus **Package**: `@suaveplan/api-events-worker-proxy` **Status**: PROPOSED **Type**: new-package **Stage**: 3 (Worker isolation infrastructure) ## Why Per design doc §5.2a, every capability ships a proxy surface for worker-tier plugins. The `events` capability is special: there is no abstract `api-events` contract package — the host injects the existing `@suaveplan/events` bus directly into `PluginContext.events`. So this proxy is a worker-side surface over the existing `@suaveplan/events` `EventBusLike` interface, NOT a new contract layer. Worker-side `ctx.events.emit(...)` / `ctx.events.on(...)` calls marshal across `MessagePort` to the main-process bus. Per §5.2b sandboxed gating: only manifested `publishes` topics are emittable; only manifested `subscribes` topics deliverable. That gating is enforced MAIN-SIDE; this proxy is the transport. ## What changes Net-new package. **ADDED exports:** - `./client` — `createEventsProxyClient(port): WorkerProxyOf`. - `./subscriber` — `on(topic, handler)` / `off` / `once`; handlers run worker-side; backpressure carried by `api-worker-rpc` so a slow worker-side subscriber cannot exhaust main-side memory. - `./publisher` — `emit(topic, payload)` marshals payload; main-side does the topic-allow check + actual bus publish; emit-not-allowed returns `EVENTS_PROXY_TOPIC_NOT_ALLOWED` (rebuilt `SuaveplanError`). - `./error-codes` — `EVENTS_PROXY_*` codes (`EVENTS_PROXY_TOPIC_NOT_ALLOWED`, `EVENTS_PROXY_HANDLER_THROW`, `EVENTS_PROXY_PORT_CLOSED`, `EVENTS_PROXY_BACKPRESSURE_DROP`). - `./testing` — paired `MessageChannel` + stub bus. ## Out of scope - **Topic allowlisting policy** — enforced main-side per §5.2b. - **Cross-host fan-out** — `@suaveplan/events`'s job (and `api-ws-broker-redis` for WS specifically). - **Bounded-queue capability** — `events.bounded-queue` capability flag is honored main-side; the proxy only marshals. ## Source mapping Genesis-original. Design doc sections: §5.2a (worker-RPC variants), §5.2b (sandboxed gating), §6 (capability scoping). | Requirement | Design doc section | |---|---| | Proxy surface over existing `@suaveplan/events` bus (no new contract) | §5.2a | | Topic allow-check on main side; proxy rejects with reconstructed error | §5.2b | | Handler throws reconstructed via `api-worker-rpc` | §5.2a | ## Verification approach - `src/publisher/publisher.test.ts` — emit allowed topic round-trips; disallowed topic throws. - `src/subscriber/subscriber.test.ts` — handler invocation; off cancels; backpressure throttles main → worker. - `tests/conformance/run-events-bus-conformance.test.ts` — `runEventsBusConformance` from `@suaveplan/events/testing` passes against the proxy as surface. **Required before Stage 4 can complete.** ## Migration impact None — additive only.