# Plugin Module Notes
`src/plugin` is Alma's boundary for untrusted local Wasm plugins. It is not an
extension point for Bevy plugins, ECS systems, raw filesystem access, process
execution, or runtime discovery.
The module is intentionally conservative: validate static input, derive narrow
proof types, authorize host imports, collect proposed effects, and hand typed
requests back to existing ECS owners. Guest code never mutates editor state.
## Current State
Implemented:
- static plugin registry config
- stable plugin identity validation
- component path shape validation
- manifest parsing
- authorized manifest/config matching proof
- config/manifest capability intersection
- validated enabled config views
- workspace-relative grant validation
- explicit whole-workspace grant spelling
- runtime limit validation with closed runtime limit field diagnostics and a
host-sized non-zero scheduler cap proof after config validation
- host queues and batches consume validated limit and budget proof types
directly after trust-boundary validation, with infallible constructors once
those proofs exist
- registry-level scheduler policy for `PluginIntentQueue`
- WIT world and capability vocabulary checks
- closed guest-decode field vocabulary for generated-to-Alma validation errors
- guest decode limits derived from validated runtime policy and retained as
non-zero caps through adapter return-size checks
- capability atoms as the policy source for stable capability spellings,
authorization-ref path arity, and redacted shapes
- optional generated Wasmtime component bindings behind `plugin-runtime`
- feature-gated Wasmtime lifecycle execution
- generated `status.publish` host import adapter behind `plugin-runtime`
- generated `buffer.observe` host import adapter behind `plugin-runtime`
- generated `buffer.propose_edit` host import adapter behind `plugin-runtime`
- generated task-based `workspace.observe` start/poll/take host import
adapters behind `plugin-runtime`
- generated `workspace.artifact_write` host import adapter behind
`plugin-runtime`
- borrowed WIT resources for update-scoped view and buffer authority
- host-owned WIT task resources for guest-visible workspace observations, with
bounded live resource accounting and canonical drop handling, including
drop-before-commit cancellation
- real Wasm component fixture coverage for accepted and denied `status.publish`
- real Wasm component fixture coverage for accepted and denied `buffer.observe`
- real Wasm component fixture coverage for accepted and denied
`buffer.propose_edit`
- real Wasm component fixture coverage for accepted `workspace.artifact_write`
and invalid workspace paths after queued workspace I/O
- generated host-import adapter coverage for denied and oversized
`workspace.artifact_write`
- real Wasm component coverage for observe-then-propose execution through
`PluginIntentQueue` and the buffer owner
- real Wasm component abuse coverage for fuel exhaustion, timeout, invalid
strings, oversized payloads, invalid resources, stale handles, and invalid
workspace paths
- real Wasm `buffer.propose_edit` publication through `PluginIntentQueue` and
the buffer owner
- deterministic multi-plugin FIFO coverage for runtime-produced
`buffer.propose_edit` batches
- canonical component lifecycle `post_return` handling after successful exports
- single active-update proof for Wasmtime update scheduling
- store-local Wasmtime active update state that pairs the discardable host
import session with rooted update resources, so they cannot drift as
independent runtime options
- store-local Wasmtime workspace observation task state that pairs the
host-owned queue, persistent task resources, and active-update resource reps,
with typed task resource reps and a non-zero resource cap derived from the
queue limit
- first visible proposal-lane chrome summary with redacted edit shape
- proposal-lane apply/reject chrome controls that emit typed proposal requests
- bounded proposal receipt log for lane rejection, owner acceptance, and owner
rejection
- proposal-lane chrome status for pending proposals and latest retained receipt
outcomes
- checked-in plugin config and manifest schema drift fixtures
- policy-opened manifest and component byte tokens
- pending/sealed/drained plugin proposal and effect batch shapes
- pending effect batch failures expose closed limit-field and rejection-class
diagnostics
- bounded `PluginIntent` ECS queue initialized from validated runtime config
- retry-safe `PluginIntentQueue` admission that preserves a saturated
still-sealed effect batch for retry or explicit redacted discard, with named
queue-error and batch fields when consuming the split
- empty sealed effect, workspace I/O, and workspace observe-task batches are
scheduler no-ops and do not consume bounded queue capacity
- closed error-kind vocabularies for the plugin intent queue, proposal lane,
proposal decision, and proposal receipt-log diagnostics
- plugin buffer edit proposals with source identity, capability atom, target, and
observed base revision provenance
- buffer edit proposal provenance and receipts whose proposal-specific
capability type derives its spelling from `CapabilityAtom`
- revision-guarded plugin edit proposals rejected by the buffer owner when stale
- per-plugin buffer edit proposal review policy with `auto_apply` default and
explicit `manual_review`
- public identity-proof accessors for plugin-scoped runtime, host, effect,
workspace I/O, effective-plugin, and revocation boundary values
- shared host authority proof for plugin identity and effective grants, reused
by live contexts and per-update import snapshots
- host-owned typed buffer and view handles with generation invalidation
and bounded live-handle counts
- store-local Wasmtime `ResourceTable` lookup for component resources
- workspace I/O request and policy-token bridge types that route through
`fs_utils`, with closed budget field diagnostics
- deferred synchronous workspace I/O batches for the v1 runtime stepping stone
- shared workspace request-budget accounting across deferred I/O, direct
observations, and task-style observation reservations
- deferred workspace I/O request counts derive from pending batch storage
instead of duplicating a mutable deferred counter in the shared ledger
- task-style workspace observation reservations reject cross-plugin request
ledgers before charging budget or reserving task ids
- workspace observation task reservations use explicit RAII queue-slot
accounting while retaining `Send + Sync` batch shapes, and counter underflow
fails in all builds
- workspace I/O and observe-task queue admission failures carry closed error
classes and mismatch sources, so access-proof, request-ledger, identity, and
queue reservation mismatches cannot collapse into one presentation convention;
consuming retryable splits expose named queue-error and batch fields
- workspace request-budget, pending-effect, intent queue, proposal lane,
observe-task pending, workspace worker, and operational queue saturation
diagnostics retain non-zero cap proofs from validated budgets and queue limits
- non-zero workspace byte cap proofs at the filesystem-policy read/write bridge
- bounded workspace artifact write payload proofs retained by pending and
sealed deferred I/O batches
- redacted workspace I/O report debug output for successful reads and writes,
with explicit accessors retaining owner-facing success data
- bytes-only workspace observe delivery projection for guest-visible reads,
separate from owner-facing read report metadata
- redacted workspace observe outcome shapes shared by task-result diagnostics
and runtime trace adapters
- count-shaped debug output for observe-task queues and pending or sealed
observe-task batches, with task handles exposed only through explicit
task-result and enqueue-report accessors
- count-shaped debug output for successful-return aggregate batches, so
host-import and owner-batch proofs do not format nested sealed effects,
workspace I/O, or observe-task batches
- count-shaped debug output for failed-update, owner-work, post-update
schedule, and scheduled owner discard reports, so outer diagnostics do not
format nested discard reports or scheduled task-handle lists
- release-enforced same-plugin identity pairing for successful-return,
owner-work, post-update schedule, and scheduled owner-publication proofs
- direct host-session workspace observation through the pending workspace I/O
ledger and explicit filesystem policy, returning only bounded bytes or a
closed rejection, spending the per-update workspace request budget, rejecting
cross-plugin access proofs before budget charge, and queuing no deferred
workspace I/O; public guest reads use the task/result ABI
- workspace I/O worker queue failures expose closed limit-field and
rejection-class diagnostics
- sealed workspace I/O worker queue saturation retains the still-sealed batch
for retry or explicit discard with a redacted cleanup report and named
queue-error and batch fields when consuming the split
- workspace I/O worker and observation task queues can cancel all queue-owned
work for shutdown or broad teardown with deterministic per-identity redacted
reports
- Wasmtime instance revocation cleanup for workspace observation tasks is gated
by a matching `PluginRevocationReport`, clears queue-owned task state,
uncommitted active-update task requests, and persistent task resources before
unload
- Wasmtime instance shutdown cleanup clears runtime-owned workspace observation
task queue state, uncommitted active-update task requests, and persistent
task resources without requiring lifecycle mutation
- Wasmtime state revocation helper that rejects runtime/state identity drift
before mutating host state, then returns lifecycle revocation and
runtime-owned workspace observation cleanup together
- Wasmtime workspace observation task enqueue rejects sealed batches whose
plugin identity does not match the runtime instance, and enqueue,
single-task execution, capped batch execution, and drain-all execution
require the matching active `PluginInstanceState`, denying late queue
admission or filesystem work after revocation
- Wasmtime update scheduling helper for the owner loop, returning a
`WasmtimePluginScheduledUpdate` proof that pairs sealed editor and workspace
I/O owner work with task-based workspace observations already admitted back
onto the producing runtime queue
- post-update observe-task schedule recovery consumes the paired schedule-error
proof and rebuilds the scheduled-update proof after a successful task retry
- Wasmtime scheduled-update and post-update schedule-error debug output is
count-shaped and does not format retained owner batches or retryable task
batches
- scheduled-update and scheduled-owner-publication public split APIs return
named part structs instead of positional tuples for owner work, retryable
queue errors, discard evidence, and already-scheduled task evidence
- successful-return and owner-batch public split APIs return named part structs
instead of positional tuples for editor effects, workspace I/O, and
runtime-owned observe-task work
- active-update setup, task-resource authority, Wasmtime revocation cleanup,
and adapter-local update resource splits return named boundary structs
instead of positional tuples
- drained effect reports split into named owner request batches with the
drained plugin identity retained instead of returning positional tuples
- ECS owner publication validates the intent queue and workspace I/O worker
queue into a private paired admission proof that retains the target queue
borrows until publication. Each owner queue admission owns its sealed batch
until publication, returning paired owner work for retry or redacted discard on
saturation and returning a named owner-publication report on success, with
count-shaped debug output for retained or published owner work. Retryable
owner-queue enqueue errors split into named queue-error and owner-work fields.
- scheduled-update owner publication accepts `WasmtimePluginScheduledUpdate`,
returns a named publication report carrying both owner-publication evidence
and the observe-task scheduling report on success, and keeps the task report
paired with retryable owner work if owner queue admission fails
- scheduled-update owner-publication retry consumes the paired owner-queue
failure and preserves the already-scheduled observe-task report until owner
queue admission succeeds or the caller discards unpublished owner work
- scheduled-update owner-publication reports expose already-admitted
observe-task evidence through explicit scheduled-task accessors and
count-shaped debug output without retained owner batch internals
- Wasmtime observe-task schedule failures retain that unpublished owner-work
proof and the retryable task enqueue error in one private-field payload
- Wasmtime observe-task enqueue failures keep their source and retryable batch
paired behind a private-field payload, with a closed public kind and
source-specific accessors for caller decisions, including runtime/batch
identity mismatches before queue admission. State and batch mismatch identity
accessors return named borrowed pairs instead of positional tuples.
- Wasmtime observe-task enqueue failure debug output is count-shaped and does
not format the retained retryable sealed task batch
- scheduled-update and observe-task enqueue failures expose redacted
operational events for owner-loop reporting without exposing unpublished
owner work
- persistent Wasmtime task resources retain their authorizing workspace path;
the host-session boundary pairs the reserved task handle with that authorized
path in one proof before Wasmtime persists the resource; poll/take
revalidates the path against the current update snapshot before resource-table
lookup or queue access, tombstoning the resource on denied authority without
freeing the table rep, and resource-table/tracker divergence fails closed as
a typed resource-handle rejection in release builds while reused tracked reps
and table lookup/delete errors tombstone the tracked resource before
returning; dropping a task resource before successful guest return removes
the matching pending request before it can be sealed for filesystem work
- Wasmtime update setup tombstones workspace observation task resources still
marked as started by a prior abandoned update before accepting fresh update
resources
- host-owned workspace observation task queue with closed pending, completed,
and unknown state, payload-free poll, consuming take, bounded single-task and
capped batch execution, an explicitly named all-task drain, and limit-field
projections for guest-visible reads
- host-session workspace observation task reservation backs the public
task-based `workspace.observe` start import while keeping filesystem work
behind successful-return sealed batches
- workspace observation task requests retain their update's read byte cap until
queue execution
- sealed workspace observation task enqueue errors retain the still-sealed
batch for retry or explicit discard with a redacted cleanup report
- sealed workspace observation task admission retains the validated pending
queue storage through enqueue, so reservation validation and pending
publication stay one internal proof boundary
- task ids, owned identity-scoped task handles and queue keys, internal
handle-borrowed lookup matching, shared closed task state, payload-free queue
state queries, payload-free poll results, consuming take results, shared
redacted poll/take result shapes, and identity-scoped
`PluginWorkspaceObserveTaskCompletionShape` split from queue mutation for
task/resource adapters
- Wasmtime host-import rejection retention as one adapter-local envelope
containing the first redacted import class and typed source error
- host-import source errors project their own closed operational rejection
class before runtime adapters build events
- bounded workspace I/O worker queue with revocation cancellation
- loaded plugin instance lifecycle and revocation policy
- registry-level plugin scheduler policy
- redacted operational event shapes for load, unload, revocation, denied
import, non-authorization host import rejection, timeout, guest trap, intent
queue saturation, workspace I/O queue saturation, and proposal lane
saturation
- redacted plugin runtime trace vocabulary for drained effects, discarded
updates, workspace I/O completions, workspace I/O cancellations, workspace
observation task completions with identity-scoped completion shapes,
workspace observation task cancellations, operational events, and proposal
receipts
- redacted load and host-import diagnostic regression tests
- WIT resource and lifecycle drift checks against `wit/alma-editor-plugin.wit`
- WIT resource authority drift checks
- task-based `workspace.observe` start/poll/take import metadata, with
operational import classes and drift coverage proving the current WIT exposes
no blocking read import and no partial task group
- host-import session boundary for handle resolution, capability checks,
discardable effects, and deferred workspace I/O
Not implemented:
- additional Wasmtime host import adapters beyond `status.publish`,
`buffer.observe`, `buffer.propose_edit`, task-based `workspace.observe`, and
`workspace.artifact_write`
- plugin event subscriptions
- background workspace I/O worker threads
- guest-driven `PluginIntent` scheduling and subscriptions
- synchronous guest-visible `workspace.observe`; workspace reads use the
task/resource ABI instead
## Files
- `policy/config/mod.rs`: static config facade and public re-exports.
- `policy/config/registry.rs`: registry uniqueness validation and enabled
load-entry proofs.
- `policy/config/entry.rs`: untrusted static config entries and effective
manifest grant projection.
- `policy/config/identity.rs`: stable plugin identity grammar.
- `policy/config/world.rs`: current WIT-world proof.
- `policy/config/component.rs`: component path shape validation.
- `policy/config/proposal.rs`: proposal review policy schema.
- `policy/config/tests.rs`: config-boundary tests and property coverage.
- `policy/capability.rs`: capability grants and host-import query shapes.
- `policy/workspace.rs`: workspace-relative grants and path refs, not filesystem
authority.
- `policy/manifest.rs`: untrusted manifest parsing, authorized manifest/config
matching proof, and effective grant projection.
- `policy/scheduler.rs`: registry-level publication burst policy.
- `runtime/mod.rs`: runtime boundary re-exports.
- `runtime/component.rs`: policy-opened component bytes.
- `runtime/limits.rs`: bounded execution and ECS publication limits.
- `runtime/instance.rs`: runtime spec, loaded instance lifecycle, and
revocation policy.
- `runtime/wasmtime/mod.rs`: feature-gated Wasmtime adapter facade.
- `runtime/wasmtime/adapter.rs`: runtime construction, instantiation, update
orchestration, task scheduling, task execution, and revocation entry points.
- `runtime/wasmtime/error.rs`: redacted runtime failures and retryable
observe-task enqueue errors.
- `runtime/wasmtime/execution.rs`: fuel and epoch-deadline guard machinery.
- `runtime/wasmtime/resources.rs`: typed Wasmtime update-resource table reps.
- `runtime/wasmtime/schedule.rs`: scheduled-update and revocation proof shapes.
- `runtime/wasmtime/store.rs`: store-local host-import state and generated host
import adapters.
- `runtime/wasmtime/workspace_observe.rs`: runtime-owned workspace observe task
queue/resource state and guest ABI result projection.
- `runtime/wasmtime/tests.rs`: Wasmtime adapter and component fixture coverage.
- `host/context.rs`: per-plugin authorization context and shared host
authority proof.
- `host/import/mod.rs`: host-import boundary facade and re-export surface.
- `host/import/snapshot.rs`: per-update authority and handle-store capture.
- `host/import/session.rs`: active import-session mutation methods, direct
workspace observation policy path, and discardable work collection.
- `host/import/batches.rs`: successful-return owner/task batches and failed
update discard reports.
- `host/import/resource.rs`: observe-task resource-authority proofs and
component-resource rejection vocabulary.
- `host/import/error.rs`: layered host-import rejection types and redacted
operational rejection projection.
- `host/effect/mod.rs`: effect boundary facade and re-export surface.
- `host/effect/limit.rs`: non-zero effect admission limit proof and stable
limit-field vocabulary.
- `host/effect/error.rs`: effect admission rejection classes and commit error
vocabulary.
- `host/effect/proposal.rs`: internal effect payload storage, status shapes,
and snapshot-derived buffer edit proposals.
- `host/effect/batch.rs`: pending and sealed effect batches, successful-return
sealing, and typed admission methods.
- `host/effect/report.rs`: discard evidence, drained owner request reports,
named owner request splits, and redacted drained request shapes.
- `host/handles.rs`: per-plugin typed handle table and short-lived resolved
proofs.
- `host/workspace_io/mod.rs`: workspace I/O facade and re-export surface.
- `host/workspace_io/batch.rs`: pending and sealed deferred workspace I/O
batch ownership, bounded write payload proofs, and discard evidence.
- `host/workspace_io/error.rs`: shared workspace I/O commit rejection classes
and identity-mismatch source vocabulary.
- `host/workspace_io/budget.rs`: workspace I/O limit proofs and shared
per-update request accounting.
- `host/workspace_io/access.rs`: workspace read/write access proofs, internal
filesystem-policy tokens, operation kind vocabulary, and operation-specific
policy errors.
- `host/workspace_io/report.rs`: owner-facing workspace I/O reports and
guest-delivery read projections.
- `host/workspace_io/observe_result.rs`: workspace observation task ids,
owned identity-scoped task handles and queue keys, internal handle-borrowed
lookup matching, shared closed task state, redacted poll/take result shapes,
payload-free poll results, consuming take results, and identity-scoped
`PluginWorkspaceObserveTaskCompletionShape`.
- `host/workspace_io/observe_tasks/mod.rs`: observe-task facade and re-export
surface.
- `host/workspace_io/observe_tasks/batch.rs`: pending and sealed
observe-task batches plus successful-return sealing and explicit discard.
- `host/workspace_io/observe_tasks/queue.rs`: host-owned task queue, queue
limits, non-reusing task ids, FIFO execution, retained outcomes, state,
poll, take, and cancellation.
- `host/workspace_io/observe_tasks/error.rs`: reserve/enqueue errors, closed
queue rejection classes, limit-field vocabulary, and reservation mismatch
vocabulary.
- `host/workspace_io/observe_tasks/report.rs`: redacted discard, enqueue, and
cancellation reports.
- `host/workspace_io/observe_tasks/reservation.rs`: identity-scoped task
reservations and RAII pending-slot accounting.
- `host/workspace_io/worker.rs`: sealed workspace I/O FIFO worker queue,
retryable admission, revocation or shutdown cancellation, queue limits, and
saturation diagnostics.
- `trace/`: redacted replay/telemetry facade over reports, receipts, and
operational events, split by event envelope, effect/status payloads,
workspace payloads, proposal receipts, shared display adapters, and tests.
- `abi/wit.rs`: stable hand-written ABI vocabulary for default builds.
- `abi/decode/mod.rs`: generated-to-Alma decode facade and re-export surface.
- `abi/decode/limits.rs`: non-zero decode limits derived from validated
runtime policy.
- `abi/decode/field.rs`: closed guest-decode diagnostic field vocabulary.
- `abi/decode/error.rs`: redacted guest-decode error vocabulary.
- `abi/decode/scalar.rs`: bounded guest string, payload, count, and text-range
proofs.
- `abi/decode/workspace_path.rs`: normalized workspace path decode proof.
- `abi/decode/capability.rs`: WIT capability references decoded into
Alma-owned authorization refs.
- `abi/decode/buffer_edit.rs`: guest buffer edits decoded into bounded
owner-facing edit requests.
- `abi/decode/tests.rs`: decode-boundary field, limit, redaction, and owner
conversion tests.
- `abi/bindings.rs`: feature-gated generated component bindings; keep private.
- `policy/error.rs`: redacted policy and authorization errors.
- `../ecs/plugin.rs`: ECS queue and drain adapter for sealed plugin effects.
- `../ecs/events/plugin.rs`: ECS diagnostic message for redacted plugin
operational events.
## Design Records
Keep this file as the module inventory. The durable plugin design records live
under `docs/plugins/`:
- `docs/plugins/runtime.md`: runtime dataflow, commit points, module map,
lifecycle, and cancellation
- `docs/plugins/security.md`: boundary model, proof types, capability rules,
ABI rules, and redacted diagnostics
- `docs/plugins/testing.md`: required coverage, fixture inventory, abuse-test
rules, and capability extension checklist
When adding a host import, update this module inventory only for file-level
ownership changes. Update the split docs for runtime behavior, authority, and
test obligations.