Skip to main content

Module manifest

Module manifest 

Source
Expand description

The plugin manifest — a plugin’s declared capability request.

Design fragment: docs/dev/architecture/plugin-host.md §6. Slice: PH7.2.

A manifest declares what a plugin asks for, not what it gets. The grant — what a plugin is actually granted — is computed from the manifest plus its crate::TrustTier (and, for user-installed plugins, consent); see crate::capability. The manifest is untrusted input: a plugin cannot declare its own trust tier (that would defeat the point), so the tier is a host-supplied argument to grant computation, never a manifest field.

The manifest is a committed TOML format so the Phase-8 plugin manager can discover + parse it off disk; the host itself consumes an already-parsed PluginManifest (there is no on-disk plugin discovery at PH7.2 — that is the plugin manager, deferred to Phase 8).

id = "fuzzy-finder"
capabilities = ["fs:read:/home/alice/project", "net:http:crates.io"]
editor_capabilities = ["tree-sitter"]

Two capability namespaces meet here and stay distinct:

  • OS capabilities (Capability) gate the plugin’s WASI view (fs:* / net:* / proc:*). These are enforced by the runtime.
  • Editor capabilities (CapabilitySet) are the same set lattice_mode::Mode::required_capabilities returns; a plugin that declares a mode carries its capability requirements here. Enforcement stays the mode-activation path (PH7.11) — this slice only sizes the manifest honestly per fragment §6.

Structs§

CapabilityParseError
The string s was not a recognised capability form.
PluginManifest
Everything a plugin declares about itself and what it needs. Untrusted input; the trust tier is supplied separately at grant time.

Enums§

Capability
An OS-level capability a plugin requests in its manifest. Distinct from CapabilitySet (editor/buffer capabilities); these gate the plugin’s WASI view (filesystem / network / process).
ManifestError
Why a manifest failed to parse. Every failure is a value — the host logs + skips a bad manifest (graceful degradation), never panics.
PluginSeam
Which extension seam a plugin’s component implements — the WIT world it exports. Each seam is its own world (picker-source, events-plugin, …); a component implements one, and the manifest declares which so the plugin loader (lattice-plugin-loader) knows which spawn_* path to drive. An empty provides list is a lifecycle-only plugin (the base plugin world — init.rs, the no-op fixture), driven through instantiate_plugin + activate rather than a seam actor.

Functions§

is_safe_plugin_id
Is id a single, safe path component — usable as a directory name that cannot escape its parent? The plugin id keys the per-plugin data dir, which is joined into a host path and mounted writable into the guest; a crafted id (/etc/cron.d, ../../.ssh, .) would otherwise relocate that writable mount outside the sandbox with no fs grant (the CRITICAL isolation contract, lib.rs build_plugin_wasi). Accepts exactly one Component::Normal; rejects empty, absolute, separators, and . / ...