Overviewâ
Runtime() is a capability exclusive to dynamic plugins. Dynamic plugins run within the WASM guest boundary and cannot directly access host-process logging, time, node identity, or local state implementations. They therefore need to call host-provided runtime primitives through service: runtime.
Source plugins already run inside the host process and typically use native host logging, request context, and injected domain services directly, so they do not need the Runtime() wrapper.
Capability Phase: Runtime
Supported Types: Dynamic plugins
Design Philosophyâ
Dynamic Plugin Exclusive Entry Pointâ
Runtime() lives in pluginbridge.Services and does not belong to the capability.Services standard domain capability directory. It serves the dynamic plugin bridge runtime environment rather than business domain data access.
Boundary with Infra()â
Runtime() reads dynamic plugin runtime primitives; Infra() reads infrastructure component state. The two are not interchangeable:
| Capability | Boundary | Primary Responsibility |
|---|---|---|
Runtime() | Dynamic plugin exclusive | Logging, plugin state, time, UUID, and node identity |
Infra() | Shared between source and dynamic plugins | Infrastructure component state views |
If a dynamic plugin needs to check whether an infrastructure component is available, it should declare service: infra rather than treating runtime.info.* as a component status capability.
Core Capabilitiesâ
| Dynamic Method | Dynamic SDK Method | Description |
|---|---|---|
log.write | Runtime().Log | Writes a structured runtime log entry |
state.get | Runtime().StateGet, Runtime().StateGetInt | Reads plugin-scoped runtime state |
state.set | Runtime().StateSet, Runtime().StateSetInt | Writes plugin-scoped runtime state |
state.delete | Runtime().StateDelete | Deletes plugin-scoped runtime state |
info.now | Runtime().Now | Reads the host time string |
info.uuid | Runtime().UUID | Generates a host-side unique identifier |
info.node | Runtime().Node | Reads the current host node identity |
runtime is a none resource type and does not declare paths, tables, keys, or resources. Authorization boundaries are controlled by service + method.
Usageâ
Dynamic plugins declare the runtime service in plugin.yaml:
hostServices:
- service: runtime
methods:
- log.write
- state.get
- state.set
- state.delete
- info.now
- info.uuid
- info.node
Call through pluginbridge.Default().Runtime() on the dynamic plugin side:
runtime := pluginbridge.Default().Runtime()
err := runtime.Log(protocol.LogLevelInfo, "export started", map[string]string{
"taskID": taskID,
})
if err != nil {
return err
}
now, err := runtime.Now()
if err != nil {
return err
}
err = runtime.StateSet("last_export_time", now)
if err != nil {
return err
}
lastExport, found, err := runtime.StateGet("last_export_time")
if err != nil {
return err
}
id, err := runtime.UUID()
if err != nil {
return err
}
node, err := runtime.Node()
Design Constraintsâ
- Dynamic plugin exclusive.
Runtime()only exists in thepluginbridgedynamic SDK and does not enter the source plugincapability.Servicesdirectory. - Runtime state is not a cache substitute.
runtime.state.*is suitable for storing small amounts of plugin-scoped state. Cross-plugin sharing, counters, and expiration policies should use the Cache capability. - Log fields should be short and stable. Dynamic plugins should not put large bodies, secrets, tokens, or personally identifiable information into log fields.
- Info reads are not health checks.
info.now,info.uuid, andinfo.nodeonly provide basic runtime information and do not express component availability. - Infrastructure state goes through
Infra(). Component state reads should use the Infra capability andservice: infra.