@skill-map/spec 0.4.0 → 0.5.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,39 @@
1
1
  # Spec changelog
2
2
 
3
+ ## 0.5.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 69572fd: Align `spec/index.json` with the manifest changes declared in the `0.3.0` changelog (they had been documented but never written to the file), and fix two small referential drifts surfaced in the same audit pass.
8
+
9
+ **`spec/index.json`** — closes the gap between what `0.3.0` notes promised and what actually shipped:
10
+
11
+ - `specVersion` top-level field renamed to `indexPayloadVersion`. The old name collided semantically with `specPackageVersion` and with every other use of `specVersion` in the spec (compat logic, `scan-result.specVersion`, `sm help --format json`). `indexPayloadVersion` describes the shape of `index.json` itself and bumps only when this manifest's structure changes — pinned at `0.0.1` today. **This is the breaking rename already announced in the `0.3.0` release notes.**
12
+ - `schemas.topLevel` gains `history-stats` (shape for `sm history stats --json`, already referenced from `cli-contract.md` §History and hashed under `integrity.files`).
13
+ - New `schemas.extensions` subsection listing the 7 kind-manifest schemas (`base`, `adapter`, `detector`, `rule`, `action`, `audit`, `renderer`) — already required by `architecture.md` §Extension kinds for load-time manifest validation and already present under `schemas/extensions/`.
14
+
15
+ **`spec/versioning.md` §Change process step 4** — the parenthetical `(see CLAUDE.md: "Every feature: update spec/ first, then src/")` was stale. `CLAUDE.md` has been a bare `@AGENTS.md` pointer since the 18d0c20 dedup; the rule itself lives in `AGENTS.md`. Reference fixed.
16
+
17
+ **`spec/CHANGELOG.md` 0.3.0 entry** — text-only renumber of "decision #40a" → "decision #40". The sub-letter was a leftover from an unreleased draft; the roadmap Decision log uses `40` as the canonical anchor (see companion ROADMAP edit).
18
+
19
+ Classification: minor per §Pre-1.0 (`0.Y.Z`). The `specVersion → indexPayloadVersion` rename is breaking for any consumer that read the old field, but the old name never shipped alongside a file that spelled it `indexPayloadVersion` — the rename is being applied here for the first time, not re-applied. The `topLevel`/`extensions` additions are purely additive.
20
+
21
+ ### Patch Changes
22
+
23
+ - 2699276: Fix the extension-kind schemas so they actually validate against real extension manifests.
24
+
25
+ The six kind schemas (`schemas/extensions/action.schema.json`, `adapter.schema.json`, `audit.schema.json`, `detector.schema.json`, `renderer.schema.json`, `rule.schema.json`) used `additionalProperties: false` together with `allOf: [{ $ref: "base.schema.json" }]` — a classic JSON Schema Draft 2020-12 footgun. `additionalProperties` is evaluated independently per schema in an `allOf`, so when a consumer validated `{ id, kind, version, emitsLinkKinds, defaultConfidence }` against `detector.schema.json`, detector's `additionalProperties: false` rejected `id` / `version` / `description` (defined only on `base`) and base's own `additionalProperties: false` would have rejected `emitsLinkKinds` / `defaultConfidence` — the union of both closures is empty. No real extension could ever pass validation.
26
+
27
+ Discovered during Step 1b while wiring the AJV validators in `skill-map` (kernel plugin loader). The right fix is `unevaluatedProperties: false` — it sees through `allOf` composition and only rejects keys that no sibling schema declared.
28
+
29
+ Changes:
30
+
31
+ - Every kind schema: `additionalProperties: false` → `unevaluatedProperties: false` at the manifest level. Nested `additionalProperties: false` declarations inside `$defs` / `properties` were likewise replaced with `unevaluatedProperties: false` where they participate in `allOf` composition (e.g. `action.schema.json#/$defs/Parameter`, `audit.schema.json` nested items).
32
+ - `extensions/base.schema.json`: closure removed entirely. Closed-content is now enforced only on the kind schemas, which see base's properties as "evaluated" through the `allOf` — adding closure to base too would force every kind to re-list every base key to stay valid.
33
+ - `base.schema.json` description updated to spell out the new composition rule so a future reader does not accidentally re-introduce the footgun.
34
+
35
+ Classification: patch. No normative shape changes — every manifest that was _supposed_ to pass under the old schemas still passes under the new ones, and the authored intent (closed content on kind manifests, additive base fields) is preserved. Consumers that never wired strict JSON Schema validation see zero behavioural change.
36
+
3
37
  ## 0.4.0
4
38
 
5
39
  ### Minor Changes
@@ -80,7 +114,7 @@
80
114
  - `tokenizer: string` (default `cl100k_base`) — name of the offline tokenizer; stored alongside counts so consumers know which encoder produced them.
81
115
  - `scan.maxFileSizeBytes: integer` (default `1048576`) — files larger are skipped with an `info` log.
82
116
  - `jobs.ttlSeconds: integer` (default `3600`) — global fallback TTL when an action manifest omits `expectedDurationSeconds` (typically `mode: local` actions where the field is advisory).
83
- - `jobs.perActionPriority: { <actionId>: integer }` — per-action priority overrides. Frozen on `state_jobs.priority` at submit time; overrides action manifest `defaultPriority`; overridden by CLI `--priority`. Ratifies decision #40a in the schema.
117
+ - `jobs.perActionPriority: { <actionId>: integer }` — per-action priority overrides. Frozen on `state_jobs.priority` at submit time; overrides action manifest `defaultPriority`; overridden by CLI `--priority`. Ratifies decision #40 in the schema.
84
118
  - `jobs.retention: { completed, failed }` — GC policy for `state_jobs` rows. Defaults: `completed = 2592000` (30 days), `failed = null` (never auto-prune; keep for post-mortem). `sm job prune` reads these; no implicit pruning during normal verbs.
85
119
 
86
120
  **`job-events.md` — new `Non-job events` section, Stability: experimental across v0.x:**
package/index.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "specVersion": "0.0.1",
2
+ "indexPayloadVersion": "0.0.1",
3
3
  "dialect": "https://json-schema.org/draft/2020-12/schema",
4
4
  "canonicalUrlPrefix": "https://skill-map.dev/spec/v0",
5
5
  "schemas": {
@@ -43,6 +43,40 @@
43
43
  {
44
44
  "id": "conformance-case",
45
45
  "path": "schemas/conformance-case.schema.json"
46
+ },
47
+ {
48
+ "id": "history-stats",
49
+ "path": "schemas/history-stats.schema.json"
50
+ }
51
+ ],
52
+ "extensions": [
53
+ {
54
+ "id": "extensions/base",
55
+ "path": "schemas/extensions/base.schema.json"
56
+ },
57
+ {
58
+ "id": "extensions/adapter",
59
+ "path": "schemas/extensions/adapter.schema.json"
60
+ },
61
+ {
62
+ "id": "extensions/detector",
63
+ "path": "schemas/extensions/detector.schema.json"
64
+ },
65
+ {
66
+ "id": "extensions/rule",
67
+ "path": "schemas/extensions/rule.schema.json"
68
+ },
69
+ {
70
+ "id": "extensions/action",
71
+ "path": "schemas/extensions/action.schema.json"
72
+ },
73
+ {
74
+ "id": "extensions/audit",
75
+ "path": "schemas/extensions/audit.schema.json"
76
+ },
77
+ {
78
+ "id": "extensions/renderer",
79
+ "path": "schemas/extensions/renderer.schema.json"
46
80
  }
47
81
  ],
48
82
  "frontmatter": [
@@ -156,11 +190,11 @@
156
190
  }
157
191
  ]
158
192
  },
159
- "specPackageVersion": "0.4.0",
193
+ "specPackageVersion": "0.5.0",
160
194
  "integrity": {
161
195
  "algorithm": "sha256",
162
196
  "files": {
163
- "CHANGELOG.md": "38364d4ca30475e3e1eb35019037532547c1e5bdc245ecfcc60eb5e1570985d0",
197
+ "CHANGELOG.md": "adf0e49a213a8996cc2689749c47f2ed27cb9d31b40c18cece07b6d6ef94cd28",
164
198
  "README.md": "a233e6b5ab1c41c13cb4790485f0514f7c111880eb70165e77e1253999069120",
165
199
  "architecture.md": "be4085b7bbb3476f8a9d6df940b5794839b936ac5dd1921203a91558b008c7bc",
166
200
  "cli-contract.md": "7657b6e60089afdd3644e7e38d96593158349259ab105d76199ce5eb65993cae",
@@ -182,13 +216,13 @@
182
216
  "prompt-preamble.md": "9b7478ddce0a77043983f35932677d702319348048fe5d6b1c60257bd1c9f605",
183
217
  "schemas/conformance-case.schema.json": "2740874e00269de6d8121300339401d0283197b6d97dcd77538ec5d108b14de2",
184
218
  "schemas/execution-record.schema.json": "ec0f3acf1d0ce099c059d73eb434936bfd1bcf12023693bd572efb2a7352faa6",
185
- "schemas/extensions/action.schema.json": "d22a98aca9ad3d7bee475b370135372913e5756ad5987084c77e91e04c8472e8",
186
- "schemas/extensions/adapter.schema.json": "882c23b0c914eb37af5d50704268e028eb94e1601ceb5fc61aaf932f1ab82eb2",
187
- "schemas/extensions/audit.schema.json": "a871f96d340a9b72fc4cd3ce6f56a553bb6b56636e342501dcb5d3b724475502",
188
- "schemas/extensions/base.schema.json": "845f0abe723f1916354f05f6c1cd134c4b8da25fd612976f5ca1e205bf0d0fdb",
189
- "schemas/extensions/detector.schema.json": "58957bf96ca58218eadd1fceecfb0203bcc11d93eb8cef6bba90e89deca3e195",
190
- "schemas/extensions/renderer.schema.json": "a8cfc40c8be525fb69e62d53bd98f622b82599bb95e3fac66ec324d4298e46f5",
191
- "schemas/extensions/rule.schema.json": "eca5a877f3eb6d52cbe62e97bbd2ca3ccd2724bbc760e16e63d7473dfb4fa61a",
219
+ "schemas/extensions/action.schema.json": "c7520d3cefecf75d27d3e04473821fd6e5dc5a7924eede147f74275ba6caccad",
220
+ "schemas/extensions/adapter.schema.json": "429b865e738664bb437ac62690a2d7282ce992339fbb300417c73625f5cdb7c8",
221
+ "schemas/extensions/audit.schema.json": "9ec2c68584707696423a1d617bc1e003cf8ee96a2c67b2f008f6647b2927c86c",
222
+ "schemas/extensions/base.schema.json": "c832a8c9976a7ddc70b8f9226a54de14aa3e85d71bc77ed7a8671a77d599c0e4",
223
+ "schemas/extensions/detector.schema.json": "077b9cccb0bd3d58ca53d61d59c609aa42709225d187e341412a857ab341462f",
224
+ "schemas/extensions/renderer.schema.json": "2ec52545c85bb5e36d0f4f67c155b0e1656468b62a1045d2eb268255202306f0",
225
+ "schemas/extensions/rule.schema.json": "dd957deaafd41699309cb073a4620e4e8e45d3ba15541adba0e693e6d85cdf76",
192
226
  "schemas/frontmatter/agent.schema.json": "0e63d7692efb29facccc69472fff48a25f44934618346bfc09738864c6917787",
193
227
  "schemas/frontmatter/base.schema.json": "e68fbb85d3e873c4897af776eaf873860bd6e86b5abc1799e801d35c4f7937cf",
194
228
  "schemas/frontmatter/command.schema.json": "7b8463ce9c83edd2e3073dd4cd1bbeec4b42e53b03b48bc9a59e540136c2de89",
@@ -209,7 +243,7 @@
209
243
  "schemas/summaries/hook.schema.json": "36f876f3b1a60d45be97a0848c79fd18744b434dfdcefc366f033b253d56268c",
210
244
  "schemas/summaries/note.schema.json": "ae510f3ee1b6092c1061625e425c9bb7de9c9caa3f3774770c148f658d505753",
211
245
  "schemas/summaries/skill.schema.json": "f01bab92c51d64ee23e61587e42cf0dc5b37a2f518f5b12b3d1d456390338aa8",
212
- "versioning.md": "e35d4a492f4cba7ff7c9168802fe11a17daa92c60fc3333ed04e2dbb8b3b6795"
246
+ "versioning.md": "76a38d6b7e245a80274173a3cef791a04432e6ae3017ea3f66d7a37eb550fccf"
213
247
  }
214
248
  }
215
249
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skill-map/spec",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "JSON Schemas, prose contracts, and conformance suite for the skill-map specification.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -8,7 +8,7 @@
8
8
  ],
9
9
  "type": "object",
10
10
  "required": ["id", "kind", "version", "mode", "reportSchemaRef"],
11
- "additionalProperties": false,
11
+ "unevaluatedProperties": false,
12
12
  "properties": {
13
13
  "kind": { "const": "action" },
14
14
  "mode": {
@@ -32,7 +32,7 @@
32
32
  "precondition": {
33
33
  "type": "object",
34
34
  "description": "Declarative filter that nodes must satisfy for this action to be applicable. Consumed by `--all` fan-out, UI button gating, `sm actions show`.",
35
- "additionalProperties": false,
35
+ "unevaluatedProperties": false,
36
36
  "properties": {
37
37
  "kind": {
38
38
  "type": "array",
@@ -8,7 +8,7 @@
8
8
  ],
9
9
  "type": "object",
10
10
  "required": ["id", "kind", "version", "emits", "defaultRefreshAction"],
11
- "additionalProperties": false,
11
+ "unevaluatedProperties": false,
12
12
  "properties": {
13
13
  "kind": { "const": "adapter" },
14
14
  "emits": {
@@ -8,7 +8,7 @@
8
8
  ],
9
9
  "type": "object",
10
10
  "required": ["id", "kind", "version", "composes", "reportSchemaRef"],
11
- "additionalProperties": false,
11
+ "unevaluatedProperties": false,
12
12
  "properties": {
13
13
  "kind": { "const": "audit" },
14
14
  "composes": {
@@ -18,7 +18,7 @@
18
18
  "items": {
19
19
  "type": "object",
20
20
  "required": ["kind", "id"],
21
- "additionalProperties": false,
21
+ "unevaluatedProperties": false,
22
22
  "properties": {
23
23
  "kind": { "type": "string", "enum": ["rule", "action"] },
24
24
  "id": { "type": "string" },
@@ -37,7 +37,7 @@
37
37
  "exitCodeMap": {
38
38
  "type": "object",
39
39
  "description": "How the audit report maps to CLI exit codes. Absent → standard behaviour: exit 0 on pass, 1 on any error-severity issue, 2 on operational error.",
40
- "additionalProperties": false,
40
+ "unevaluatedProperties": false,
41
41
  "properties": {
42
42
  "pass": { "type": "integer", "default": 0 },
43
43
  "fail": { "type": "integer", "default": 1 }
@@ -2,10 +2,9 @@
2
2
  "$schema": "https://json-schema.org/draft/2020-12/schema",
3
3
  "$id": "https://skill-map.dev/spec/v0/extensions/base.schema.json",
4
4
  "title": "ExtensionBase",
5
- "description": "Base manifest shape common to every extension kind. Kind-specific schemas (`adapter`, `detector`, `rule`, `action`, `audit`, `renderer`) extend this via `allOf` and add a discriminant `kind` literal plus kind-specific fields. camelCase keys throughout. `additionalProperties: false` the extension manifest shape is kernel-controlled and unknown keys are a bug.",
5
+ "description": "Base manifest shape common to every extension kind. Kind-specific schemas (`adapter`, `detector`, `rule`, `action`, `audit`, `renderer`) 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.",
6
6
  "type": "object",
7
7
  "required": ["id", "kind", "version"],
8
- "additionalProperties": false,
9
8
  "properties": {
10
9
  "id": {
11
10
  "type": "string",
@@ -8,7 +8,7 @@
8
8
  ],
9
9
  "type": "object",
10
10
  "required": ["id", "kind", "version", "emitsLinkKinds", "defaultConfidence"],
11
- "additionalProperties": false,
11
+ "unevaluatedProperties": false,
12
12
  "properties": {
13
13
  "kind": { "const": "detector" },
14
14
  "emitsLinkKinds": {
@@ -8,7 +8,7 @@
8
8
  ],
9
9
  "type": "object",
10
10
  "required": ["id", "kind", "version", "format"],
11
- "additionalProperties": false,
11
+ "unevaluatedProperties": false,
12
12
  "properties": {
13
13
  "kind": { "const": "renderer" },
14
14
  "format": {
@@ -8,7 +8,7 @@
8
8
  ],
9
9
  "type": "object",
10
10
  "required": ["id", "kind", "version", "emitsRuleIds", "defaultSeverity"],
11
- "additionalProperties": false,
11
+ "unevaluatedProperties": false,
12
12
  "properties": {
13
13
  "kind": { "const": "rule" },
14
14
  "emitsRuleIds": {
package/versioning.md CHANGED
@@ -79,7 +79,7 @@ The first stable commitment is `spec-v1.0.0`. In the current reference roadmap,
79
79
  1. PR proposes a spec change. Include rationale and classification (patch/minor/major).
80
80
  2. If major, PR includes a migration note draft for `CHANGELOG.md`.
81
81
  3. If the change affects reference-impl behavior, a companion PR in `src/` lands the implementation behind the bumped `specCompat`.
82
- 4. Merge order: spec change first, implementation second. An implementation MUST NOT ship a feature that is not yet in the spec (see `CLAUDE.md`: "Every feature: update spec/ first, then src/").
82
+ 4. Merge order: spec change first, implementation second. An implementation MUST NOT ship a feature that is not yet in the spec (see `AGENTS.md`: "Every feature: update spec/ first, then src/").
83
83
  5. Tag spec release (`spec-vX.Y.Z`) independent from any CLI tag.
84
84
 
85
85
  ## Canonical URLs