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 setlattice_mode::Mode::required_capabilitiesreturns; 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§
- Capability
Parse Error - The string
swas not a recognised capability form. - Plugin
Manifest - 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). - Manifest
Error - Why a manifest failed to parse. Every failure is a value — the host logs + skips a bad manifest (graceful degradation), never panics.
- Plugin
Seam - 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 whichspawn_*path to drive. An emptyprovideslist is a lifecycle-only plugin (the basepluginworld —init.rs, the no-op fixture), driven throughinstantiate_plugin+activaterather than a seam actor.
Functions§
- is_
safe_ plugin_ id - Is
ida 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.rsbuild_plugin_wasi). Accepts exactly oneComponent::Normal; rejects empty, absolute, separators, and./...