@skill-map/spec 0.53.0 → 0.55.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,7 +7,7 @@ The suite splits across two ownership boundaries:
7
7
  - **Spec-owned cases**, kernel-agnostic. They live in this directory and ship with `@skill-map/spec`. Today: `kernel-empty-boot` (boot invariant) and the `preamble-bitwise-match` deferred case. The universal preamble fixture (`preamble-v1.txt`) lives here too.
8
8
  - **Provider-owned cases**, exercise a Provider's own `kinds` catalog. They live next to the Provider's manifest, under `<plugin-dir>/conformance/`. The reference impl ships one such suite at [`src/extensions/providers/claude/conformance/`](../../src/extensions/providers/claude/conformance/) covering Claude's five kinds (`skill` / `agent` / `command` / `hook` / `note`) via cases `basic-scan`, `rename-high`, `orphan-detection`.
9
9
 
10
- The shape below is normative; the case count in either bucket expands before spec-v1.0.0 (see [`../versioning.md`](../versioning.md)). See [`coverage.md`](./coverage.md) for the spec-owned matrix and the Provider's own coverage file (e.g. `src/extensions/providers/claude/conformance/coverage.md`) for the matching Provider-owned matrix.
10
+ The shape below is normative; the case count in either bucket expands before spec-v1.0.0 (see [`../versioning.md`](../versioning.md)). See [`coverage.md`](./coverage.md) for the spec-owned matrix and the Provider's own coverage file (e.g. `src/extensions/providers/claude/conformance/coverage.md`) for the Provider-owned matrix.
11
11
 
12
12
  The reference CLI exposes both buckets via `sm conformance run`:
13
13
 
@@ -17,7 +17,7 @@ sm conformance run --scope provider:claude # the Claude Provider's cases
17
17
  sm conformance run --scope all # both (default)
18
18
  ```
19
19
 
20
- External consumers (alt-impl authors, Provider authors validating their own work) can drive the suite without bespoke scripting, the verb provisions the same isolated tmp scope per case as the in-process reference runner does.
20
+ External consumers (alt-impl authors, Provider authors validating their own work) can drive the suite without bespoke scripting; the verb provisions the same isolated tmp scope per case as the in-process reference runner does.
21
21
 
22
22
  ---
23
23
 
@@ -44,14 +44,14 @@ src/extensions/providers/<id>/conformance/ ← Provider-owned, mirrors the lay
44
44
  Fixtures are read-only inputs. Cases declare what to invoke and what to assert. A conformance runner is implementation-specific code that:
45
45
 
46
46
  1. Reads every file under `cases/`.
47
- 2. For each case: provisions a clean scope, copies the referenced fixture into it, invokes the implementation as described, compares output against the assertions.
47
+ 2. For each case: provisions a clean scope, copies the referenced fixture into it, invokes the implementation, compares output against the assertions.
48
48
  3. Emits a pass/fail summary.
49
49
 
50
50
  ---
51
51
 
52
52
  ## Case format
53
53
 
54
- Cases are validated against [`conformance-case.schema.json`](../schemas/conformance-case.schema.json). That file is the normative shape; this section is the human-readable walkthrough. Include `"$schema": "https://skill-map.ai/spec/v0/conformance-case.schema.json"` in every case file for IDE support.
54
+ Cases are validated against [`conformance-case.schema.json`](../schemas/conformance-case.schema.json), the normative shape; this section is the human-readable walkthrough. Include `"$schema": "https://skill-map.ai/spec/v0/conformance-case.schema.json"` in every case file for IDE support.
55
55
 
56
56
  A case is a JSON document with this shape:
57
57
 
@@ -108,7 +108,7 @@ A case is a JSON document with this shape:
108
108
  | `file-matches-schema` | `path: string`, `schema: string` | File at `path` (glob permitted; resolves to exactly one) MUST be valid JSON and MUST validate against `schemas/<schema>`. |
109
109
  | `stderr-matches` | `pattern: string` | stderr MUST match the regex (ECMAScript). |
110
110
 
111
- Assertion types beyond this list MAY be proposed via spec-vX.Y.Z minor bumps. Implementations MUST reject unknown assertion types loudly, silently skipping a check is a conformance violation in itself.
111
+ Assertion types beyond this list MAY be proposed via spec-vX.Y.Z minor bumps. Implementations MUST reject unknown assertion types loudly; silently skipping a check is itself a conformance violation.
112
112
 
113
113
  ---
114
114
 
@@ -121,8 +121,8 @@ Assertion types beyond this list MAY be proposed via spec-vX.Y.Z minor bumps. Im
121
121
  | `kernel-empty-boot` | With every Provider/Extractor/Analyzer disabled, scanning an empty scope returns a valid empty graph. |
122
122
  | `no-global-scope` | The `-g/--global` flag does not exist. Implementations MUST reject it on every verb (exit `2`, "unknown option"). Guards `cli-contract.md` §Scope is always project-local. |
123
123
  | `orphan-markdown-fallback` | Multi-Provider corpus where one node lands via the universal `core/markdown` fallback and another via vendor-specific claude classification. Locks the orchestrator's path-dedup contract. |
124
- | `plugin-missing-ui-rejected` | Drop-in Provider whose `kinds[*]` entry omits the required `ui` block fails AJV validation with `invalid-manifest` while the rest of the pipeline keeps running. |
125
- | `score-phase-confidence` | Drop-in analyzer declaring `phase: 'score'` composes a confidence adjustment (`delta -0.4`, then a no-op `floor 0.5`) on top of the kernel's 1.0 baseline (a clean resolved link keeps that baseline, no built-in op); the folded, clamped `scan_links.confidence` lands at exactly `0.6`. |
124
+ | `plugin-missing-ui-rejected` | Drop-in Provider whose `kinds[*]` entry omits the required `ui` block fails AJV validation with `invalid-manifest`; the rest of the pipeline keeps running. |
125
+ | `score-phase-confidence` | Drop-in analyzer declaring `phase: 'score'` composes a confidence adjustment (`delta -0.4`, then a no-op `floor 0.5`) on top of the kernel's 1.0 baseline (a clean resolved link keeps that baseline, no built-in op); the folded `scan_links.confidence` lands at exactly `0.6`. |
126
126
  | `sidecar-end-to-end` | Co-located `.sm` sidecar shape, stale / orphan detection, populated `Node.sidecar` overlay, both `annotation-stale` and `annotation-orphan` issues emitted. |
127
127
  | `view-action-button` | An analyzer declaring the unified `inspector.header.badge` + the new `inspector.action.button` slots loads clean, while a sibling declaring the retired `inspector.header.badge.counter` slot fails as `invalid-manifest`; `sm scan` survives. |
128
128
 
@@ -144,7 +144,7 @@ Cases explicitly referenced elsewhere in the spec (landing before v1.0):
144
144
 
145
145
  ## Runner (reference pseudocode)
146
146
 
147
- Implementations are free to write their runner in any language. A minimal Node ESM version looks like:
147
+ Implementations may write their runner in any language. A minimal Node ESM version:
148
148
 
149
149
  ```js
150
150
  import { readdir, readFile, cp, rm, mkdir } from 'node:fs/promises';
@@ -162,7 +162,7 @@ for (const caseFile of await readdir('spec/conformance/cases')) {
162
162
 
163
163
  A Provider-owned runner mirrors the loop with a different cases / fixtures root, `<plugin-dir>/conformance/cases/` and `<plugin-dir>/conformance/fixtures/`. The reference CLI ships both as `sm conformance run`; the verb resolves the spec scope via `@skill-map/spec` and discovers Provider scopes by walking each built-in plugin's `conformance/` directory.
164
164
 
165
- The reference implementation's runner ships under `src/conformance/index.ts`; the verb lives at `src/cli/commands/conformance.ts` and uses the runner one case at a time.
165
+ The reference runner ships under `src/conformance/index.ts`; the verb lives at `src/cli/commands/conformance.ts` and uses the runner one case at a time.
166
166
 
167
167
  ---
168
168
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  Authoritative map of JSON Schemas in [`../schemas/`](../schemas/) to the conformance cases that exercise them. Every schema MUST have at least one case before spec v1.0.0 ships, missing case → missing release ([`../../context/spec.md`](../../context/spec.md) §Analyzers for AI agents editing spec/).
4
4
 
5
- This file is hand-maintained. A CI check before spec release compares the schema inventory against this table and fails if any schema lacks a case.
5
+ Hand-maintained. A CI check before spec release compares the schema inventory against this table and fails if any schema lacks a case.
6
6
 
7
7
  ## Coverage matrix
8
8
 
@@ -46,7 +46,7 @@ This file is hand-maintained. A CI check before spec release compares the schema
46
46
  | 35 | `user-settings.schema.json` | (indirect via `no-global-scope`) | 🟡 partial | Per-user / per-machine settings file at `~/.skill-map/settings.json` (the narrow `$HOME` exception, see `cli-contract.md` §User-settings file). Direct case is not added because alt-impls MAY choose to not ship an update-check feature, requiring them to produce this file would over-prescribe. The implementation-side AJV round-trip is covered by `src/test/user-settings-store.test.ts` (15 cases: defaults, malformed JSON, schemaVersion mismatch, wrong-type fields, unknown top-level keys, deep-merge writes, off-shape rejection). The behavioral counterpart (no global / user scope) lives at `no-global-scope` in the non-schema table below. |
47
47
  | 37 | `signal.schema.json` | `extractor-emits-signal`, `extractor-collision-detection` | ✅ covered | Intermediate Representation (IR) emitted by extractors via `ctx.emitSignal()`; the kernel resolver phase consumes Signals and materialises Links. Opt-in: the existing `ctx.emitLink()` path coexists. Phase 2.A wired the resolver end-to-end (filter -> rank -> overlap -> materialise + annotate); Phase 2.B + 2.C migrated all six link-emitter extractors (`claude/at-directive`, `claude/slash-command`, `core/markdown-link`, `core/annotations`, `core/mcp-tools`, `core/external-url-counter`); Phase 2.D added the `core/extractor-collision` analyzer + the two cases. The cases cover (a) `extractor-emits-signal`, a markdown body with one `[text](path)` link materialises one Link via the Signal IR path; (b) `extractor-collision-detection`, a body with both `[label](./api.md)` AND `@./api.md` at overlapping byte ranges triggers a cross-extractor collision, the resolver materialises ONE Link (markdown-link wins on confidence) and the loser's `resolution.rejectedBy` reaches the `core/extractor-collision` analyzer which emits a `warn` issue naming WHO won, WHO lost, and WHY. |
48
48
 
49
- > **Note on Provider-owned schemas.** Per-kind frontmatter schemas (`skill`, `agent`, `command`, `note` for the built-in Claude Provider; other Providers MAY declare different kinds) live with the Provider that emits them, for the built-in Claude Provider, under `src/extensions/providers/claude/schemas/`. Those schemas are NOT counted in the spec's coverage matrix above; they belong to the Provider's own conformance suite at `src/extensions/providers/claude/conformance/coverage.md`. The same split applies to the cases that exercise Provider-specific kinds (`basic-scan`, `rename-high`, `orphan-detection`), they live in the Provider's `cases/` directory.
49
+ > **Note on Provider-owned schemas.** Per-kind frontmatter schemas (`skill`, `agent`, `command`, `note` for the built-in Claude Provider; other Providers MAY declare different kinds) live with the Provider that emits them, for the built-in Claude Provider under `src/extensions/providers/claude/schemas/`. Those schemas are NOT counted in the coverage matrix above; they belong to the Provider's own conformance suite at `src/extensions/providers/claude/conformance/coverage.md`. The same split applies to the cases exercising Provider-specific kinds (`basic-scan`, `rename-high`, `orphan-detection`): they live in the Provider's `cases/` directory.
50
50
 
51
51
  Status legend: 🟢 covered (at least one case asserts the schema end-to-end) · 🟡 partial (covered only indirectly or via a sub-shape) · 🔴 missing.
52
52
 
@@ -74,12 +74,12 @@ These have their own conformance cases even though they are not JSON Schemas.
74
74
 
75
75
  - **spec v0.x**: partial coverage acceptable. Every case added as the reference impl lands the verb that makes it runnable.
76
76
  - **spec v1.0.0 release**: all rows above MUST be 🟢 covered or explicitly 🟠 deferred to v1.1 with a linked issue.
77
- - **CI check**: [`spec/scripts/check-coverage.js`](../scripts/check-coverage.js) compares `spec/schemas/**/*.schema.json` against the matrix above on every PR. A schema without a row here, or a row pointing at a missing schema, fails CI (exit 1 with a `::error::` annotation). Wired into the spec workspace's `spec:check` script (which is invoked by `npm run validate` from the repo root, picked up by CI).
77
+ - **CI check**: [`spec/scripts/check-coverage.js`](../scripts/check-coverage.js) compares `spec/schemas/**/*.schema.json` against the matrix above on every PR. A schema without a row here, or a row pointing at a missing schema, fails CI (exit 1 with a `::error::` annotation). Wired into the spec workspace's `spec:check` script (invoked by `npm run validate` from the repo root, picked up by CI).
78
78
 
79
79
  ## Stability
80
80
 
81
- The **coverage matrix gating policy** (every shipped schema MUST have a row; every row MUST be 🟢 covered or 🟠 deferred-to-v1.1 before the spec v1.0.0 tag) is stable as of spec v1.0.0. Relaxing the v1.0 release gate (e.g. allowing 🔴 missing rows to ship) is a major bump. Tightening the gate further (e.g. forbidding 🟠 deferrals) is a minor bump.
81
+ The **coverage matrix gating policy** (every shipped schema MUST have a row; every row MUST be 🟢 covered or 🟠 deferred-to-v1.1 before the spec v1.0.0 tag) is stable as of spec v1.0.0. Relaxing the v1.0 release gate (e.g. allowing 🔴 missing rows to ship) is a major bump. Tightening it further (e.g. forbidding 🟠 deferrals) is a minor bump.
82
82
 
83
83
  The **assertion-type vocabulary** (`exit-code`, `json-path`, `file-exists`, `file-contains-verbatim`, `file-matches-schema`, `stderr-matches`) is stable as of spec v1.0.0. Adding a new assertion type is a minor bump; renaming or removing one is a major bump.
84
84
 
85
- The **per-row schema and case set** above is mutable through every spec release: rows are added when a new schema or normative artifact lands, marked deferred when the runtime that exercises them ships in a later step, and flipped to 🟢 covered when the case file is committed. Adding rows is non-breaking; deleting rows MUST coincide with deleting the corresponding schema (which is itself a major bump).
85
+ The **per-row schema and case set** above is mutable through every spec release: rows are added when a new schema or normative artifact lands, marked deferred when the runtime that exercises them ships in a later step, and flipped to 🟢 covered when the case file is committed. Adding rows is non-breaking; deleting a row MUST coincide with deleting the corresponding schema (itself a major bump).