Plugin runtime boundaries
Plugin manifests are executable policy, not descriptive metadata. PluginRuntime is the initial registry for developer-controlled native packages and explicitly refuses sandboxed manifests; a host-provided SandboxPluginRunner owns those.
Capabilities
Before a plugin performs an operation, the host calls assertCapability(pluginId, capability). In a sandbox, the stronger rule is preferred: undeclared host APIs are never placed on the plugin context. Native packages retain direct same-process power and therefore are restricted to developer-controlled deployments.
Lifecycle hooks
dispatchHook() invokes only handlers that are both declared in the manifest and registered by the plugin. A missing declared handler fails closed. Hook execution is bounded by a host-configured timeout; a timeout rejects the lifecycle step. beforeSave and beforePublish should perform bounded validation only. Long-running delivery, indexing, and integrations belong after the durable command commit.
Storage namespace
storageKey() permits only manifest-declared collections and safe key segments. It produces an isolated plugin prefix beneath the host’s tenant/site storage scope. The host still enforces tenant/site prefixing, quotas, encryption/retention policy, and capability checks before any backing-store operation.
Sandboxed execution is the default for third-party distribution. CloudflareSandboxPluginRunner crosses a service binding into a non-public Worker with no site-data bindings. Signed alpha artifacts contain only a small declarative validation instruction set and are persisted by verified digest in that Worker’s own Durable Object. The host sends one bounded event envelope; missing artifacts, undeclared hooks, timeouts, and failed instructions fail closed. The SandboxPluginRunner interface leaves room for Dynamic Workers or another host’s equivalent isolate without weakening installation policy.