# description
Manifest shape for a `Provider` extension. A Provider declares its own universe: the platform it recognises (Claude Code, Codex, Gemini, Obsidian vault, generic MD), the catalog of node `kind`s it emits, the per-kind frontmatter schema each kind follows, and the filesystem directory (`explorationDir`) where its content lives. The catalog lives in the `kinds` map, keyed by kind name. Each map entry declares the relative path to the kind's frontmatter schema (resolved against the Provider's directory) and the qualified `defaultRefreshAction` id the UI's probabilistic-refresh surface dispatches for that kind. Spec only ships `frontmatter/base.schema.json` (universal); per-kind schemas live with their owning Provider so that adding a new platform is purely additive — no spec bump needed to introduce kinds. Exactly zero or one Provider MUST match any given file; multiple matches → the kernel emits an issue `provider-ambiguous` and the file is left unclassified. Providers are deterministic-only — they sit at the filesystem boundary and run during boot; probabilistic classification would make boot slow, costly, and non-reproducible. The `mode` field MUST NOT appear in Provider manifests. If you need LLM-assisted classification, write a probabilistic Extractor that emits classification hints via `ctx.emitLink`. Distinct from the **hexagonal-architecture** 'adapter' (`RunnerPort.adapter`, `StoragePort.adapter`, etc.), which is an internal driven-adapter implementing a port — Providers live in the extension surface, hexagonal adapters live in `src/kernel/adapters/`. Stability: stable as of spec v1.0.0 except where noted.

# properties.explorationDir.description
Filesystem directory (relative to user home or project root) where this Provider's content lives. Required. Examples: '~/.claude' for the Claude Provider; '~/.cursor' for a hypothetical Cursor Provider. The kernel walks this directory during boot/scan to discover nodes; the Provider's `globs` (if declared) refines what to match inside. `sm doctor` validates the directory exists; missing directory yields a non-blocking warning.

# properties.roots.description
Path globs (relative to scope root) that this Provider SHOULD be consulted for. Advisory — the kernel walks all roots and consults every Provider regardless, but this field lets `sm doctor` warn when no file matched a specific Provider (i.e. the Provider was loaded for a platform that isn't in this scope).

# properties.kinds.description
Catalog of node kinds this Provider emits. Keyed by kind name (e.g. `skill`, `agent`, `note`). Each entry declares the relative path to the kind's frontmatter schema (the kernel resolves it against the Provider's package directory) and the qualified `defaultRefreshAction` id the UI dispatches when the user requests a probabilistic refresh on a node of that kind. The map MUST be non-empty: a Provider that emits no kinds is meaningless. Kind names follow camelCase / lowerCase convention; the spec does not constrain the value space (a Cursor Provider could declare `rule`, an Obsidian Provider could declare `daily`).

# properties.kinds.additionalProperties.properties.schema.description
Path to the kind's frontmatter JSON Schema, relative to the Provider's package directory. The schema MUST extend `frontmatter/base.schema.json` (declared in spec) via `allOf` + `$ref` to base's `$id`. The kernel resolves the path at boot time and registers the schema with AJV for validation during scan.

# properties.kinds.additionalProperties.properties.defaultRefreshAction.description
Qualified action id (`<plugin-id>/<action-id>`) the UI's probabilistic-refresh surface (`🧠 prob`) dispatches for nodes of this kind. The action MUST exist in the registry by the time the graph is queried; a dangling reference disables the Provider with status `invalid-manifest`.

# properties.kinds.additionalProperties.properties.ui.description
Presentation metadata the UI uses to render nodes of this kind (palette swatches, list tags, graph nodes, filter chips). Required so the UI never has to invent visuals for a kind a Provider declares. The Provider declares intent (label + base color, optional dark variant + emoji + icon); the UI derives bg/fg tints from `color` per theme via a deterministic helper. Reaches the UI via the `kindRegistry` field embedded in REST envelopes (`api/rest-envelope.schema.json`).

# properties.kinds.additionalProperties.properties.ui.properties.label.description
Plural human-readable label for groups of this kind (e.g. `'Skills'`, `'Agents'`, `'Cursor Rules'`). Used in filter dropdowns, palette tooltips, and any list grouping.

# properties.kinds.additionalProperties.properties.ui.properties.color.description
Base hex color (light theme). The UI derives `bg` and `fg` tints from this value at runtime; declaring a single base value (instead of three) keeps the manifest small and lets the UI control accessibility-driven contrast.

# properties.kinds.additionalProperties.properties.ui.properties.colorDark.description
Optional dark-theme variant of `color`. When absent, the UI falls back to `color`. Declared explicitly because a luminosity flip rarely matches the brand intent for kinds that should stand out in dark mode.

# properties.kinds.additionalProperties.properties.ui.properties.emoji.description
Optional decorative emoji used as a fallback when `icon` is absent or fails to render. Bound to a small length so the UI can lay it out predictably alongside text.

# properties.kinds.additionalProperties.properties.ui.properties.icon.description
Optional discriminated icon descriptor. The UI prefers `icon` over `emoji`; when both are absent, the UI falls back to the first letter of `label` colored with `color`.

# properties.kinds.additionalProperties.properties.ui.properties.icon.oneOf[].properties.id.description
PrimeIcons identifier (e.g. `pi-cog`, `pi-bolt`). Matched verbatim against the `pi pi-<id>` class the UI emits.

# properties.kinds.additionalProperties.properties.ui.properties.icon.oneOf[].properties.path.description
Raw SVG path data (the `d` attribute of one or more `` elements, joined). The UI wraps it in ` ` and tints it with `currentColor`.