spec / v0 v0.14.0
25 JSON Schemas served from this path. Each $id equals its URL.
Top-level
-
api/rest-envelope.schema.jsonRestEnvelopeWrapper shape for REST responses under `/api/*` (Step 14.2). Three variants distinguished by the `kind` discriminator and which payload field is present (`items` for list kinds, `item` for single-resource kinds, `value` for `kind: 'config'`). The `/api/scan` and `/api/health` responses are exempt — they carry the underlying `ScanResult` / `IHealthResponse` shape directly. The `/api/graph` response is also exempt — it returns the formatter's native textual output (text/plain or text/markdown). Step 14.5.d adds the required `kindRegistry` field on every payload-bearing variant so the UI can render Provider-declared kinds (label, color, icon) without hardcoding visuals; sentinel kinds (`health`, `scan`, `graph`) stay exempt because they don't carry an envelope payload. The change keeps `schemaVersion` at `'1'` — the BFF is greenfield (no released consumers run against `'1'` without `kindRegistry`), so a versioned migration buys nothing.
-
conformance-case.schema.jsonConformanceCaseShape of a single declarative test case under `spec/conformance/cases/<id>.json`. Consumed by language-neutral conformance runners. See `spec/conformance/README.md` for the runner contract.
-
execution-record.schema.jsonExecutionRecordA single row in the execution history (`state_executions`). One record per action invocation — regardless of whether the runner was CLI, Skill, or in-process.
-
extensions/action.schema.jsonExtensionActionManifest shape for an `Action` extension. An action operates on one or more nodes in one of two modes: `deterministic` (code runs in-process, returns a report JSON directly) or `probabilistic` (kernel renders a prompt, a runner executes it against an LLM, the callback closes the job). The `mode` discriminator drives which additional fields are required. See `architecture.md` §Execution modes for the cross-extension contract.
-
extensions/base.schema.jsonExtensionBaseBase manifest shape common to every extension kind. Kind-specific schemas (`provider`, `extractor`, `rule`, `action`, `formatter`, `hook`) extend this via `allOf` and add a discriminant `kind` literal plus kind-specific fields. camelCase keys throughout. Closed-content enforcement (unknown keys = bug) lives on the kind schemas via `unevaluatedProperties: false`; those see base's evaluated keys through the `allOf` composition. Adding closure here too would force every kind schema to re-list every base key, which is the footgun the spec used to trip on before 2026-04-22.
-
extensions/extractor.schema.jsonExtensionExtractorManifest shape for an `Extractor` extension. An extractor consumes a parsed node (frontmatter + body) and emits output through three context-supplied callbacks rather than returning a value: `ctx.emitLink(link)` writes to the kernel's `links` table (validated against `emitsLinkKinds` before persistence), `ctx.enrichNode(partial)` merges author-canonical properties into the kernel's enrichment layer (separate from the author-supplied frontmatter), and `ctx.store` persists into the plugin's own KV namespace or dedicated tables. The runtime method is `extract(ctx) → void`. Extractors run in isolation: they MUST NOT read other nodes, the graph, or the DB. Cross-node reasoning lives in Rules. Extractors are dual-mode: `deterministic` extractors run synchronously inside `sm scan`; `probabilistic` extractors invoke an LLM through the kernel's `RunnerPort` (exposed as `ctx.runner`) and execute only as queued jobs (never during scan). See `architecture.md` §Execution modes for the full contract. Renamed from `detector` in spec 0.8.x — the FindBugs/SpotBugs lineage of "detector" connoted bug finding, while this kind extracts signals (relations, enrichments, custom data); ENRE (Entity Relationship Extractor) is the closer precedent.
-
extensions/formatter.schema.jsonExtensionFormatterManifest shape for a `Formatter` extension. A formatter serializes the graph (or a filtered subgraph) into a string in a declared format. Formatters are invoked by `sm graph --format <format>` and `sm export`. Formatters are deterministic-only — they sit at the graph-to-string boundary and their output MUST be byte-deterministic for the same input graph (the snapshot-test suite relies on this). The `mode` field MUST NOT appear in formatter manifests. Probabilistic narrators of the graph are a valid product but they live in jobs and emit Findings, not in formatters.
-
extensions/hook.schema.jsonExtensionHookManifest shape for a `Hook` extension. Subscribes declaratively to a curated set of kernel lifecycle events. Dual-mode (deterministic / probabilistic). Hooks react to events; they cannot block or alter the main pipeline. Probabilistic hooks are deferred to the job subsystem and never run in-scan. The set of hookable triggers is intentionally small — eight events out of the full job-events catalog. Other events (per-node `scan.progress`, `model.delta`, `run.*`, internal job lifecycle) are deliberately not hookable: too verbose for a reactive surface, internal to the runner, or covered elsewhere. Declaring a trigger outside the hookable set yields `invalid-manifest` at load time. See `architecture.md` §Hook · curated trigger set for the per-trigger payload contracts.
-
extensions/provider.schema.jsonExtensionProviderManifest 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.
-
extensions/rule.schema.jsonExtensionRuleManifest shape for a `Rule` extension. A rule consumes the full graph (nodes + links) after all extractors have run and emits `Issue[]`. Rules are dual-mode: `deterministic` rules MUST be byte-for-byte reproducible (same graph in → same issues out; time, random, and network are forbidden) and run synchronously inside `sm check` / `sm scan`. `probabilistic` rules invoke an LLM through the kernel's `RunnerPort` and execute only as queued jobs (`sm job submit rule:<id>`); their output MAY vary across runs and they NEVER participate in `sm scan`. See `architecture.md` §Execution modes for the full contract.
-
history-stats.schema.jsonHistoryStatsMachine-readable output of `sm history stats --json`. Aggregates over `state_executions` within a time window. camelCase keys throughout. The `elapsedMs` top-level field is the command's own wall-clock (see `cli-contract.md` §Elapsed time) — distinct from `totals.durationMsTotal`, which is the sum of every execution record's duration.
-
issue.schema.jsonIssueDeterministic finding emitted by a rule when evaluating the graph. Not to be confused with `Finding`, which is probabilistic (LLM-produced).
-
job.schema.jsonJobRow in `state_jobs`. Non-terminal state until it reaches `completed` or `failed`, at which point an `ExecutionRecord` is also written.
-
link.schema.jsonLinkDirected relation between two nodes, produced by one or more extractors during a scan.
-
node.schema.jsonNodeA single markdown file in the graph. Identified by its relative path from the scope root. The `kind` is whatever the classifying Provider declares; built-in kinds today are `skill`, `agent`, `command`, `hook`, `note`, but external Providers (Cursor, Obsidian, …) MAY emit their own.
-
plugins-registry.schema.jsonPluginsRegistryTwo shapes in one file: (1) the per-plugin manifest that authors ship as `plugin.json` (see `$defs/PluginManifest`); (2) the aggregate registry the implementation produces on disk (e.g. `~/.skill-map/plugins.json`), which lists all discovered plugins with their compat status. Both shapes are normative. camelCase keys throughout.
-
project-config.schema.jsonProjectConfigShape of `.skill-map/settings.json` (and its `.skill-map/settings.local.json` partner) inside a scope. Loaded by the layered config hierarchy (library defaults → user → user-local → project → project-local → env/flags) and deep-merged per key. All fields optional; defaults apply when absent. camelCase keys throughout — consistent with the rest of the spec.
-
report-base.schema.jsonReportBaseBase shape for any probabilistic report produced by an LLM-backed action (summarizers, `sm what`, `sm cluster-triggers`, etc.). All per-kind summary schemas under `summaries/` extend this. Kernel validates the `confidence` and `safety` fields regardless of action-specific extensions.
-
scan-result.schema.jsonScanResultCanonical output of `sm scan --json` (and the data shape sent over WebSocket scan events). Self-describing and versioned; consumers MUST check `schemaVersion` before parsing.
Frontmatter
-
frontmatter/base.schema.jsonFrontmatterBaseBase shape of the YAML frontmatter block on every node, across all kinds. Universal — common to every Provider's nodes regardless of platform. Per-kind schemas live in the Provider that emits the kind (declared via `provider.kinds[<kind>].schema`) and extend this base via `allOf` + `$ref` to its `$id`. camelCase keys throughout. `additionalProperties` is intentionally permissive; the deterministic `unknown-field` rule emits warnings for keys outside the catalog so that the JSON Schema remains shape-only and policy lives in rules.
Summaries
-
summaries/agent.schema.jsonSummaryAgentReport produced by `agent-summarizer` for a single `agent` node. Extends `report-base.schema.json`. Stability: experimental.
-
summaries/command.schema.jsonSummaryCommandReport produced by `command-summarizer` for a single `command` node. Extends `report-base.schema.json`. Stability: experimental.
-
summaries/hook.schema.jsonSummaryHookReport produced by `hook-summarizer` for a single `hook` node. Extends `report-base.schema.json`. Stability: experimental.
-
summaries/note.schema.jsonSummaryNoteReport produced by `note-summarizer` for a single `note` node. Extends `report-base.schema.json`. Stability: experimental.
-
summaries/skill.schema.jsonSummarySkillReport produced by `skill-summarizer` for a single `skill` node. Extends `report-base.schema.json`. Stability: experimental — field set may tighten as real summarizer output stabilizes.
Prose contracts
-
README.mdREADMEOverview of the spec and what it defines.
-
versioning.mdVersioningEvolution policy, stability tags, deprecation window.
-
CHANGELOG.mdChangelogNormative history of spec changes.
-
architecture.mdArchitectureHexagonal ports & adapters, 6 extension kinds.
-
cli-contract.mdCLI contractVerbs, flags, exit codes, JSON introspection.
-
job-lifecycle.mdJob lifecycleJob state machine, atomic claim, TTL, reap.
-
job-events.mdJob eventsCanonical event stream emitted during execution.
-
prompt-preamble.mdPrompt preambleVerbatim injection-mitigation text prepended to every job.
-
db-schema.mdDB schemaZoned table catalog, naming conventions, migrations.
-
plugin-kv-api.mdPlugin KV APIctx.store contract for mode A + mode B dedicated rules.
-
interfaces/security-scanner.mdSecurity scanner interfaceConvention for third-party security scanners.