Documentation
¶
Overview ¶
Package wasm — Capabilities collects every resource a wasm plugin can request: filesystem mounts, environment variables, network hosts, memory cap, and per-invocation timeout. The Runtime consumes Capabilities to shape the wazero ModuleConfig and host-side proxies — keeping the declarative shape (manifest) separate from the imperative shape (wazero config) makes the cap surface explicit and unit-testable.
A zero-value Capabilities denies everything except CPU/memory at the safe defaults. Per-capability constructor helpers exist for composition in tests; the production path always derives a single Capabilities from the manifest via FromManifest.
Package wasm implements the WASM-tier plugin loader using tetratelabs/wazero. The runtime is pure-Go and embedded in the samuel binary — no host wasm-runtime install required.
Host functions exposed under the `samuel` namespace:
- samuel.fs.read(ptr, len) -> bytes — capability-gated by filesystem.read
- samuel.fs.write(ptr, len, body) — capability-gated by filesystem.write
- samuel.exec(cmd) -> exit_code — capability-gated by exec
- samuel.net.outbound(host, body) — capability-gated by network.outbound
- samuel.log(level, msg) — always allowed
- samuel.config.get(key) -> value — always allowed (read-only)
- samuel.callback(name, payload) — always allowed
Each module must export `samuel_protocol_version() -> u32`. The runtime rejects modules whose protocol falls outside the framework's supported range (RFD 0001 resolution #2). Modules also expose `health() -> i32` (0=ok, non-zero=fail) used by Check.
Compiled modules are cached at ~/.samuel/cache/wasm-compiled/<plugin>@<version>-<hash>.bin per wazero's CompilationCache contract.
Index ¶
- Constants
- func BuildFixtureWasm(healthVal, protocolVal int32) []byte
- func BuildModuleConfig(caps Capabilities, instanceName string) wazero.ModuleConfig
- func CacheKey(name, version string, body []byte) string
- func CachePath(cacheRoot, key string) string
- func WithHostState(ctx context.Context, s *HostState) context.Context
- type CacheStats
- type Capabilities
- type FilesystemMount
- type HostState
- type Plugin
- func (p *Plugin) Check(ctx context.Context) plugin.HealthStatus
- func (p *Plugin) Detect(_ context.Context) (plugin.DetectResult, error)
- func (p *Plugin) Install(ctx context.Context, opts plugin.InstallOptions) (plugin.InstallResult, error)
- func (p *Plugin) Manifest() plugin.Manifest
- func (p *Plugin) Name() string
- func (p *Plugin) Run(ctx context.Context, export string) ([]uint64, error)
- func (p *Plugin) Uninstall(_ context.Context, opts plugin.UninstallOptions) (plugin.UninstallResult, error)
- type Runtime
- func (r *Runtime) CacheStats() CacheStats
- func (r *Runtime) Close(ctx context.Context) error
- func (r *Runtime) CompileAndCache(ctx context.Context, modulePath string) (wazero.CompiledModule, error)
- func (r *Runtime) InstantiateWithBudgets(ctx context.Context, body []byte, name string, caps Capabilities, ...) (api.Module, context.Context, context.CancelFunc, error)
- func (r *Runtime) LoadCached(ctx context.Context, body []byte) (wazero.CompiledModule, string, error)
- func (r *Runtime) RegisterHost(ctx context.Context) error
- func (r *Runtime) SetCacheBudget(b int64)
Constants ¶
const ( DefaultMaxMemoryMiB = 64 DefaultSoftTimeout = 5 * time.Second DefaultHardTimeout = 30 * time.Second )
Default budgets — PRD 0009 §Requirements.
const ( SupportedProtocolMin = 1 SupportedProtocolMax = 1 )
SupportedProtocolMin / Max define the protocol-version window the framework accepts. Modules report their protocol via `samuel_protocol_version() -> u32` (see RFD 0001).
const Component = "plugin/wasm"
Component is the structured-error namespace.
const ModuleFileName = "plugin.wasm"
ModuleFileName is the canonical filename inside the install directory.
Variables ¶
This section is empty.
Functions ¶
func BuildFixtureWasm ¶
BuildFixtureWasm hand-encodes a minimal WebAssembly module that exports two i32-returning functions:
"health" -> i32 (returns healthVal) "samuel_protocol_version" -> i32 (returns protocolVal)
Used by wasm tests and by `scripts/wasm-fixtures` to materialize the committed binary fixture for the e2e suite (testdata/wasm-fixture/ plugin.wasm). The encoding follows wasm core spec §5 (binary format).
func BuildModuleConfig ¶
func BuildModuleConfig(caps Capabilities, instanceName string) wazero.ModuleConfig
BuildModuleConfig translates Capabilities into a wazero.ModuleConfig suitable for one invocation: env keys are pulled from the host process, filesystem mounts are derived from the declared mounts, and the module name is namespaced per-invocation so wazero treats each call as fresh.
memMaxPages is enforced via RuntimeConfig (see Runtime.NewWithLimit), not the per-module config; we still record the requested value on the returned config for diagnostic purposes.
func CacheKey ¶
CacheKey builds the cache filename pattern for a plugin module. Used by Install to materialize a deterministic cache path even though wazero's CompilationCache uses its own internal layout.
Types ¶
type CacheStats ¶
type CacheStats struct {
Hits uint64 `json:"hits"`
Misses uint64 `json:"misses"`
HitRate float64 `json:"hit_rate"`
Modules int `json:"modules"`
BudgetBytes int64 `json:"budget_bytes"`
UsedBytes int64 `json:"used_bytes"`
}
CacheStats reports observed module-cache behavior. Surfaced by `samuel doctor --json` per PRD 0009 §Non-functional.
type Capabilities ¶
type Capabilities struct {
Filesystem []FilesystemMount
Env []string // allowlist of env keys
NetworkHost []string // allowlist of hosts (deny-by-default if empty)
MaxMemoryMiB uint32
SoftTimeout time.Duration
HardTimeout time.Duration
}
Capabilities is the per-instance gate set.
func CapabilitiesFromManifest ¶
func CapabilitiesFromManifest(m *manifest.Manifest) (Capabilities, error)
FromManifest derives Capabilities from a parsed manifest. Returns an error if the manifest is internally inconsistent for a wasm plugin (missing module, conflicting mounts, etc.).
func (Capabilities) AllowsHost ¶
func (c Capabilities) AllowsHost(host string) bool
AllowsHost reports whether host is on the network allowlist. A host allowlist with a single "*" entry allows everything; per RFD 0010 the recommendation is to enumerate explicit hosts.
func (Capabilities) AllowsPath ¶
func (c Capabilities) AllowsPath(path string, write bool) bool
AllowsPath reports whether the absolute host path falls inside a declared filesystem mount and the requested write satisfies the mount's read-only flag.
func (*Capabilities) Validate ¶
func (c *Capabilities) Validate() error
Validate reports configuration conflicts that the manifest validator could not catch on its own — e.g. a write mount referencing a path that was not declared as readable.
type FilesystemMount ¶
FilesystemMount is a single mount instruction derived from the manifest. Source is a host path; ReadOnly mirrors whether the path appeared in [capabilities.filesystem] read vs write.
type HostState ¶
type HostState struct {
Plugin string
Grants []capability.Grant
LogBuf []string
OutboundOK func(host string) bool
ExecOK func(cmd string) bool
// Caps is the per-invocation capability snapshot (PRD 0009). When
// non-nil it overrides the grant list — every host-side privileged
// call routes through Caps.Allows* before the grant check runs.
Caps *Capabilities
}
HostState holds the per-instance authorization context for the `samuel.*` host functions. The instance log buffer captures everything the plugin emits via samuel.log so tests can assert.
type Plugin ¶
type Plugin struct {
Manifest_ manifest.Manifest
ProjectDir string
SourceDir string
Runtime *Runtime
Grants []capability.Grant
CacheKeyOut string // populated by Install for samuel.lock recording
}
Plugin is the wasm-tier plugin.Plugin implementation.
func New ¶
func New(m manifest.Manifest, projectDir, sourceDir string, rt *Runtime, grants []capability.Grant) *Plugin
New constructs a wasm-tier Plugin. rt may be nil; Detect/Uninstall do not need it. Install + Check require a runtime.
func (*Plugin) Check ¶
func (p *Plugin) Check(ctx context.Context) plugin.HealthStatus
Check instantiates the module and calls health().
func (*Plugin) Install ¶
func (p *Plugin) Install(ctx context.Context, opts plugin.InstallOptions) (plugin.InstallResult, error)
Install copies plugin.wasm out of the source tree, verifies the protocol export, and stages the file into .samuel/plugins/<name>/.
Atomicity: tmp file → rename.
func (*Plugin) Run ¶
Run instantiates and invokes a named export with no args. Used for hook execution and tests. Returns the raw u64 result list.
func (*Plugin) Uninstall ¶
func (p *Plugin) Uninstall(_ context.Context, opts plugin.UninstallOptions) (plugin.UninstallResult, error)
Uninstall removes the plugin directory.
type Runtime ¶
type Runtime struct {
// contains filtered or unexported fields
}
Runtime is the per-process wazero runtime + host-function registry. One Runtime is shared across all WASM plugins to enable module reuse and a single compilation cache.
func NewRuntime ¶
NewRuntime constructs a Runtime backed by an on-disk wazero compilation cache rooted at cacheDir. cacheDir may be empty (cache disabled, slower startup, useful for tests).
func (*Runtime) CacheStats ¶
func (r *Runtime) CacheStats() CacheStats
CacheStats snapshots the module cache counters.
func (*Runtime) CompileAndCache ¶
func (r *Runtime) CompileAndCache(ctx context.Context, modulePath string) (wazero.CompiledModule, error)
CompileAndCache compiles a wasm module by path; cache is shared with the runtime. Returns the wazero compiled module ready for instantiation.
func (*Runtime) InstantiateWithBudgets ¶
func (r *Runtime) InstantiateWithBudgets(ctx context.Context, body []byte, name string, caps Capabilities, grants []capability.Grant) (api.Module, context.Context, context.CancelFunc, error)
InstantiateWithBudgets compiles+caches the module, attaches the per-invocation HostState (carrying caps), and instantiates with a context that carries the hard-timeout deadline. The returned cancel must always be called by the caller.
func (*Runtime) LoadCached ¶
func (r *Runtime) LoadCached(ctx context.Context, body []byte) (wazero.CompiledModule, string, error)
LoadCached compiles body once per SHA256 and reuses the wazero.CompiledModule on subsequent calls. Bumps the LRU on hit so hot modules survive eviction.
func (*Runtime) RegisterHost ¶
RegisterHost installs the `samuel.*` host functions on the runtime. Call once per Runtime; idempotent. Per-instance authorization is performed by reading HostState off the wazero context (see Module.Run).
func (*Runtime) SetCacheBudget ¶
SetCacheBudget overrides the in-memory module cache budget (bytes). 0 disables eviction; the wazero on-disk cache is unaffected.