Skip to main content
The manifest is the entire contract between a plugin and the host. Get it right and everything else (install, permission grants, slot mounting, capability checks) falls into place automatically.

File location

manifest.yaml lives at the root of the .adosplug archive. The host opens the archive, reads the manifest first, and refuses to unpack anything else if the manifest fails validation.

Top-level shape

Identity and configuration live as flat top-level keys. There is no plugin: wrapper.
At least one of agent or gcs must be present. The host accepts plugins that ship only one half; the first-party Battery Health Panel, for example, is GCS-only. The manifest also accepts optional install-dialog content fields the GCS renders for a richer pre-install summary (description_long, features, hardware_requirements, resource_impact, required_fc_parameters, telemetry_fields, documentation_url, screenshots). The agent does not interpret any of them.

compatibility

Node profiles are declared on the agent half (agent.target_profiles), not here.

agent

entrypoint is a relative path inside the archive (no absolute paths, no ..). For a file-path entrypoint like agent/plugin.py the runner loads a class named Plugin. A module:Class entrypoint is also accepted and is how built-in plugins declare themselves. isolation: subprocess is the default and the only mode third-party plugins may declare. inprocess is reserved for first-party plugins that import into the supervisor. runtime: rust runs the entrypoint as its own binary (rust always runs subprocess).

Agent field reference

agent.resources

Each entry registers a MAVLink component so the router claims its id and answers component-info on the plugin’s behalf.

Permission shape

A permission entry is either a bare string (which means required) or an object with id, required, and an optional degraded_behavior:
Unknown permission ids load with a warning rather than a hard failure, so an experimental manifest still parses. See the Permissions reference.

Schema-2 agent fields

contains_vendor_binary, vendor_attribution, subprocess_spawn, and per_drone_config are schema-2 fields. A v1 manifest gets the defaults.
  • per_drone_config: true runs one process per connected drone, each with its own ctx.agent_id and config at /var/lib/ados/plugins/<plugin_id>/config/<agent_id>.yaml.
  • subprocess_spawn is an allowlist of binary basenames the plugin may exec. The plugin host rejects any spawn whose basename is not on the list, and the manifest validator requires the process.spawn permission whenever the list is non-empty.
  • contains_vendor_binary plus vendor_attribution travel together: the flag must be set when (and only when) at least one attribution record is present. Each vendor_attribution entry takes license (required) plus optional name, source_url, source_offer_url, upstream_repo, upstream_version, commit_sha, and notice. See Vendor binaries.

gcs

contributes carries skills, tabs, parameters, settings, panels, overlays, notifications, missionTemplates, mapOverlays, and models. The slot value in contributes.panels[].slot comes from the slot taxonomy (fc.tab, hardware.tab, settings.section, and the rest; see the contribution points reference). Mounting in a slot also requires the matching ui.slot.* permission listed under gcs.permissions. Locales are listed under gcs.locales, a sibling of contributes. skills declares flight Skills that surface in the cockpit Skill Bar (toggle, hotkey or gamepad binding, activation through per-drone config, read-back over an event topic). Each skill entry needs the ui.slot.flight-skill permission. The agent does not interpret skill entries; the GCS skill registry reads them. The full contribution reference, with the manifest shape of each kind and where it renders, is on the contribution points page.

Signing and the archive

The .adosplug archive is a zip. There is no per-asset hash list in the manifest and no signing: block. Instead the archive carries a separate top-level SIGNATURE file with two lines: the signer key id, then the base64 Ed25519 signature over a canonical payload hash (the SHA-256 of the sorted <path>\n<sha256-hex>\n lines for every entry except SIGNATURE). Because the hash covers every entry, any tampering after signing fails verification. Archives are size-bounded (50 MB per archive, 25 MB per entry) and reject path-traversal entries (.., absolute paths, symlinks). A manifest that fails validation raises a manifest error; a signature from an unknown or revoked signer is rejected (see Signing keys).

See also