@skill-map/spec 0.5.0 → 0.5.1
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 +11 -5
- package/README.md +25 -24
- package/architecture.md +23 -10
- package/cli-contract.md +11 -0
- package/conformance/README.md +12 -3
- package/conformance/coverage.md +20 -20
- package/db-schema.md +20 -11
- package/index.json +14 -14
- package/interfaces/security-scanner.md +13 -4
- package/job-events.md +12 -4
- package/job-lifecycle.md +14 -4
- package/package.json +1 -1
- package/plugin-kv-api.md +12 -5
- package/prompt-preamble.md +15 -6
- package/versioning.md +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Spec changelog
|
|
2
2
|
|
|
3
|
+
## 0.5.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 18d758a: Editorial pass across spec/ and src/ docs: convert relative-path text references (e.g. `plugin-kv-api.md`, `schemas/node.schema.json`) to proper markdown links, so they resolve on GitHub and in renderers. No normative or behavioural changes — prose, schemas, and CLI contract are unchanged.
|
|
8
|
+
|
|
3
9
|
## 0.5.0
|
|
4
10
|
|
|
5
11
|
### Minor Changes
|
|
@@ -123,7 +129,7 @@
|
|
|
123
129
|
- `issue.*`: `issue.added`, `issue.resolved` — emitted after `scan.completed` when the new scan's issue set differs from the previous one. Diff key: `(ruleId, nodeIds sorted, message)`.
|
|
124
130
|
- Synthetic run ids follow the existing `r-<mode>-YYYYMMDD-HHMMSS-XXXX` pattern (`r-scan-...`, `r-check-...`) alongside `r-ext-...` for external Skill claims.
|
|
125
131
|
|
|
126
|
-
These families ship at Step
|
|
132
|
+
These families ship at Step 13 of the reference impl alongside the WebSocket broadcaster. Marking them experimental keeps the shape mutable until real UI consumers exercise the stream; promotion to `stable` is a later minor bump.
|
|
127
133
|
|
|
128
134
|
Classification: minor per §Pre-1.0. All additions are optional fields in a permissive config schema and new event types outside the stable job family — zero impact on existing implementations. Matching `ROADMAP.md` §Notable config keys and §Progress events updates land in the same change.
|
|
129
135
|
|
|
@@ -149,7 +155,7 @@
|
|
|
149
155
|
- **Exempt** verbs (sub-millisecond, informational): `sm --version`, `sm --help`, `sm version`, `sm help`, `sm config get`, `sm config list`, `sm config show`.
|
|
150
156
|
- Measurement spans from after arg-parsing to before terminal write.
|
|
151
157
|
- **cli-contract.md** `sm history stats` entry: flags enumerated (`--since`, `--until`, `--period`, `--top`) and schema referenced.
|
|
152
|
-
- **Coverage matrix**: row `29` for `history-stats.schema.json` (blocked by Step
|
|
158
|
+
- **Coverage matrix**: row `29` for `history-stats.schema.json` (blocked by Step 5); artifact row `L` for the elapsed-time reporting invariant (blocked by Step 4).
|
|
153
159
|
|
|
154
160
|
Classification: minor per §Pre-1.0. The elapsed-time contract introduces a SHOULD-emit line that didn't exist before — no existing consumer breaks, and the line goes to stderr where it doesn't clash with stdout JSON.
|
|
155
161
|
|
|
@@ -225,7 +231,7 @@
|
|
|
225
231
|
|
|
226
232
|
**Breaking (pre-1.0 minor per `versioning.md` §Pre-1.0):**
|
|
227
233
|
|
|
228
|
-
- **Remove** `history.retentionDays`. The field promised execution-record GC, but `ROADMAP.md` §Step
|
|
234
|
+
- **Remove** `history.retentionDays`. The field promised execution-record GC, but `ROADMAP.md` §Step 7 and the job-retention section make it explicit that `state_executions` is append-only in `v0.1` and that the kernel does not use this key. Declaring a config key whose behaviour is "silently ignored" is worse than not declaring it — consumers would wire it in and never see an effect. The field will be re-introduced in a later minor bump when the GC path actually lands, with a concrete default and enforcement semantics.
|
|
229
235
|
|
|
230
236
|
**Editorial:**
|
|
231
237
|
|
|
@@ -237,7 +243,7 @@
|
|
|
237
243
|
|
|
238
244
|
- 93ffe34: Promote the trigger-normalization pipeline (Decision #21) from implicit to normative in `spec/architecture.md`.
|
|
239
245
|
|
|
240
|
-
Before this change, `link.trigger` carried `originalTrigger` and `normalizedTrigger` fields (defined in `schemas/link.schema.json`), and the `trigger-collision` rule keyed on the normalized value — but no spec prose documented **how** to normalize. The pipeline lived only in `AGENTS.md §Decisions already locked` and in `ROADMAP.md` as a one-line Step
|
|
246
|
+
Before this change, `link.trigger` carried `originalTrigger` and `normalizedTrigger` fields (defined in `schemas/link.schema.json`), and the `trigger-collision` rule keyed on the normalized value — but no spec prose documented **how** to normalize. The pipeline lived only in `AGENTS.md §Decisions already locked` and in `ROADMAP.md` as a one-line Step 7 bullet. That left implementations free to diverge, which silently breaks the `trigger-collision` rule across implementations (two conforming CLIs could disagree on whether `hacer-review` and `Hacer Review` collide).
|
|
241
247
|
|
|
242
248
|
Added under `architecture.md §Extension kinds`, paralleling the existing `Adapter · defaultRefreshAction` subsection:
|
|
243
249
|
|
|
@@ -390,7 +396,7 @@
|
|
|
390
396
|
- Referenced in `conformance/README.md` (§"Cases explicitly referenced elsewhere in the spec"). Entry moved from "pending" to "current" in the case inventory.
|
|
391
397
|
- Registered in `spec/index.json` and the integrity block (SHA256 regenerated).
|
|
392
398
|
|
|
393
|
-
The second pending case, `preamble-bitwise-match`, is deferred to Step
|
|
399
|
+
The second pending case, `preamble-bitwise-match`, is deferred to Step 10 (requires `sm job preview` from the job subsystem).
|
|
394
400
|
|
|
395
401
|
- 4e0aec4: Initial public spec surface (`v0.1.0`):
|
|
396
402
|
|
package/README.md
CHANGED
|
@@ -24,15 +24,15 @@ This document is the **source of truth**. The reference implementation under `..
|
|
|
24
24
|
- Logging format, telemetry, or distribution channels.
|
|
25
25
|
- Plugin marketplace mechanics.
|
|
26
26
|
|
|
27
|
-
These are implementation decisions. The reference impl picks them (see `../
|
|
27
|
+
These are implementation decisions. The reference impl picks them (see [`../AGENTS.md`](../AGENTS.md) and [`../ROADMAP.md`](../ROADMAP.md)); other implementations may pick differently and still conform.
|
|
28
28
|
|
|
29
29
|
## Properties
|
|
30
30
|
|
|
31
31
|
- **Machine-readable**: all domain shapes are JSON Schemas. Validate from any language that has a JSON Schema validator.
|
|
32
32
|
- **Human-readable**: prose documents for each subsystem, with examples.
|
|
33
|
-
- **Independently versioned**: spec `v1.0.0` can be implemented by CLI `v0.3.2`. See `versioning.md
|
|
33
|
+
- **Independently versioned**: spec `v1.0.0` can be implemented by CLI `v0.3.2`. See [`versioning.md`](./versioning.md).
|
|
34
34
|
- **Platform-neutral**: no platform (Claude Code, Obsidian, …) is privileged. Each is expressed as an adapter extension.
|
|
35
|
-
- **Conformance-tested**: every conforming implementation passes the suite under `conformance
|
|
35
|
+
- **Conformance-tested**: every conforming implementation passes the suite under [`conformance/`](./conformance/README.md). Pass/fail is binary.
|
|
36
36
|
|
|
37
37
|
## Naming conventions
|
|
38
38
|
|
|
@@ -49,17 +49,17 @@ The SQL persistence layer is the sole exception: tables, columns, and migration
|
|
|
49
49
|
spec/ ← published as @skill-map/spec
|
|
50
50
|
├── README.md ← this file
|
|
51
51
|
├── CHANGELOG.md ← spec history (independent from CLI)
|
|
52
|
-
├── versioning.md
|
|
52
|
+
├── [versioning.md](./versioning.md) ← evolution policy
|
|
53
53
|
├── package.json ← npm manifest for @skill-map/spec
|
|
54
54
|
├── index.json ← machine-readable manifest + per-file sha256 (generated)
|
|
55
55
|
│
|
|
56
|
-
├── architecture.md
|
|
57
|
-
├── cli-contract.md
|
|
58
|
-
├── job-events.md
|
|
59
|
-
├── prompt-preamble.md
|
|
60
|
-
├── db-schema.md
|
|
61
|
-
├── plugin-kv-api.md
|
|
62
|
-
├── job-lifecycle.md
|
|
56
|
+
├── [architecture.md](./architecture.md) ← hexagonal ports & adapters
|
|
57
|
+
├── [cli-contract.md](./cli-contract.md) ← verbs, flags, exit codes, JSON introspection
|
|
58
|
+
├── [job-events.md](./job-events.md) ← canonical event stream schema
|
|
59
|
+
├── [prompt-preamble.md](./prompt-preamble.md) ← canonical injection-mitigation preamble (verbatim normative)
|
|
60
|
+
├── [db-schema.md](./db-schema.md) ← table catalog (kernel-owned)
|
|
61
|
+
├── [plugin-kv-api.md](./plugin-kv-api.md) ← ctx.store contract for storage mode A
|
|
62
|
+
├── [job-lifecycle.md](./job-lifecycle.md) ← queued → running → completed | failed
|
|
63
63
|
│
|
|
64
64
|
├── schemas/ ← 29 JSON Schemas, draft 2020-12, camelCase keys
|
|
65
65
|
│ ├── node.schema.json ┐
|
|
@@ -99,26 +99,27 @@ spec/ ← published as @skill-map/spec
|
|
|
99
99
|
│ └── note.schema.json ┘
|
|
100
100
|
│
|
|
101
101
|
├── interfaces/
|
|
102
|
-
│ └── security-scanner.md
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
102
|
+
│ └── [security-scanner.md](./interfaces/security-scanner.md) ← convention over the Action kind (NOT a 7th extension kind)
|
|
103
|
+
├── [conformance/](./conformance/README.md)
|
|
104
|
+
│ ├── [coverage.md](./conformance/coverage.md) ← schema-to-case coverage matrix
|
|
105
|
+
│ ├── fixtures/ ← controlled MD corpora + preamble-v1.txt
|
|
106
|
+
│ └── cases/ ← declarative test cases: basic-scan, kernel-empty-boot
|
|
107
|
+
│ (preamble-bitwise-match deferred to ../ROADMAP.md Step 10)
|
|
107
108
|
```
|
|
108
109
|
|
|
109
110
|
## How to read this spec
|
|
110
111
|
|
|
111
|
-
- **Building a tool or plugin that consumes skill-map output?** Start with `schemas/scan-result.schema.json` and `schemas/node.schema.json
|
|
112
|
-
- **Building a custom detector, rule, or renderer?** Read `architecture.md
|
|
113
|
-
- **Building an alternative CLI implementation?** Read `cli-contract.md` and run `conformance
|
|
114
|
-
- **Integrating a new platform (adapter)?** Read `architecture.md` §adapters, then the Claude adapter source in `../src/extensions/adapters/claude/` as a worked example.
|
|
115
|
-
- **Shipping a job-running runner?** Read `job-events.md
|
|
112
|
+
- **Building a tool or plugin that consumes skill-map output?** Start with [`schemas/scan-result.schema.json`](./schemas/scan-result.schema.json) and [`schemas/node.schema.json`](./schemas/node.schema.json).
|
|
113
|
+
- **Building a custom detector, rule, or renderer?** Read [`architecture.md`](./architecture.md), then the relevant schema under [`schemas/extensions/`](./schemas/extensions/).
|
|
114
|
+
- **Building an alternative CLI implementation?** Read [`cli-contract.md`](./cli-contract.md) and run [`conformance/`](./conformance/README.md).
|
|
115
|
+
- **Integrating a new platform (adapter)?** Read [`architecture.md`](./architecture.md) §adapters, then the Claude adapter source in `../src/extensions/adapters/claude/` as a worked example.
|
|
116
|
+
- **Shipping a job-running runner?** Read [`job-events.md`](./job-events.md), [`job-lifecycle.md`](./job-lifecycle.md), [`prompt-preamble.md`](./prompt-preamble.md).
|
|
116
117
|
|
|
117
118
|
## Relationship to the reference implementation
|
|
118
119
|
|
|
119
|
-
The reference implementation (`../src/`) is one conforming consumer of this spec. It ships the CLI binary `sm`, a built-in SQLite storage adapter, and a bundle of default extensions.
|
|
120
|
+
The reference implementation ([`../src/`](../src/README.md)) is one conforming consumer of this spec. It ships the CLI binary `sm`, a built-in SQLite storage adapter, and a bundle of default extensions.
|
|
120
121
|
|
|
121
|
-
The reference impl has no privileged access to the spec. Breaking changes to the spec must follow `versioning.md` regardless of reference-impl convenience.
|
|
122
|
+
The reference impl has no privileged access to the spec. Breaking changes to the spec must follow [`versioning.md`](./versioning.md) regardless of reference-impl convenience.
|
|
122
123
|
|
|
123
124
|
When spec and reference impl disagree, the spec wins. File an issue; one of them is wrong.
|
|
124
125
|
|
|
@@ -162,7 +163,7 @@ console.log(actual === index.integrity.files[file] ? 'ok' : 'drift');
|
|
|
162
163
|
|
|
163
164
|
### JSON Schema Store
|
|
164
165
|
|
|
165
|
-
The schemas will be registered on JSON Schema Store once the canonical URLs under `skill-map.dev/spec/v0/` are stable (Step
|
|
166
|
+
The schemas will be registered on JSON Schema Store once the canonical URLs under `skill-map.dev/spec/v0/` are stable (Step 14).
|
|
166
167
|
|
|
167
168
|
## License
|
|
168
169
|
|
package/architecture.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Normative description of skill-map's internal boundaries: the **kernel**, the **ports** it exposes, the **adapters** that drive and serve it, and the six **extension kinds** that live outside the kernel.
|
|
4
4
|
|
|
5
|
-
Any conforming implementation — reference or third-party — MUST respect these boundaries. The conformance suite under `conformance/` enforces them.
|
|
5
|
+
Any conforming implementation — reference or third-party — MUST respect these boundaries. The conformance suite under [`conformance/`](./conformance/README.md) enforces them.
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -47,11 +47,11 @@ An implementation MUST expose these five ports. Each is an interface (TypeScript
|
|
|
47
47
|
|
|
48
48
|
Persistence for all kernel tables in all three zones (`scan_*`, `state_*`, `config_*`). Exposes typed repositories, not raw SQL. Implementations MAY back this with SQLite, Postgres, in-memory, or anything else, as long as:
|
|
49
49
|
|
|
50
|
-
- Transactional semantics for atomic claim (see `job-lifecycle.md`).
|
|
50
|
+
- Transactional semantics for atomic claim (see [`job-lifecycle.md`](./job-lifecycle.md)).
|
|
51
51
|
- Migration application with `PRAGMA user_version`-equivalent tracking.
|
|
52
52
|
- Read isolation sufficient to avoid phantom reads across a single scan write.
|
|
53
53
|
|
|
54
|
-
The reference impl backs this with `node:sqlite` + Kysely + `CamelCasePlugin`.
|
|
54
|
+
The reference impl backs this with `node:sqlite` + Kysely + `CamelCasePlugin`. See [`db-schema.md`](./db-schema.md) for the full table catalog.
|
|
55
55
|
|
|
56
56
|
### `FilesystemPort`
|
|
57
57
|
|
|
@@ -77,13 +77,13 @@ Two reference implementations:
|
|
|
77
77
|
- `ClaudeCliRunner` — subprocess `claude -p < jobfile`.
|
|
78
78
|
- `MockRunner` — deterministic fake for tests.
|
|
79
79
|
|
|
80
|
-
The **Skill agent** does NOT implement this port: it is a peer driving adapter (alongside CLI and Server) that runs inside an LLM session and consumes `sm job claim` + `sm record` as a kernel client. The name "Skill runner" is descriptive, not structural — only the `ClaudeCliRunner` (and its test fake) implement `RunnerPort`. See `job-lifecycle.md
|
|
80
|
+
The **Skill agent** does NOT implement this port: it is a peer driving adapter (alongside CLI and Server) that runs inside an LLM session and consumes `sm job claim` + `sm record` as a kernel client. The name "Skill runner" is descriptive, not structural — only the `ClaudeCliRunner` (and its test fake) implement `RunnerPort`. See [`job-lifecycle.md`](./job-lifecycle.md).
|
|
81
81
|
|
|
82
82
|
### `ProgressEmitterPort`
|
|
83
83
|
|
|
84
84
|
Emits progress events during long operations (scans, job runs). Consumers: CLI pretty printer, `--json` ndjson, Server's WebSocket broadcaster.
|
|
85
85
|
|
|
86
|
-
Operations: `emit(event)`, `subscribe(listener)`. Events are defined in `job-events.md
|
|
86
|
+
Operations: `emit(event)`, `subscribe(listener)`. Events are defined in [`job-events.md`](./job-events.md).
|
|
87
87
|
|
|
88
88
|
---
|
|
89
89
|
|
|
@@ -92,8 +92,8 @@ Operations: `emit(event)`, `subscribe(listener)`. Events are defined in `job-eve
|
|
|
92
92
|
The kernel is the only component that:
|
|
93
93
|
- Maintains the extension registry.
|
|
94
94
|
- Runs the scan orchestrator.
|
|
95
|
-
- Validates scan output against `scan-result.schema.json
|
|
96
|
-
- Applies the canonical prompt preamble to job files (`prompt-preamble.md`).
|
|
95
|
+
- Validates scan output against [`scan-result.schema.json`](./schemas/scan-result.schema.json).
|
|
96
|
+
- Applies the canonical prompt preamble to job files ([`prompt-preamble.md`](./prompt-preamble.md)).
|
|
97
97
|
- Enforces duplicate-prevention and atomic-claim invariants for jobs.
|
|
98
98
|
- Persists execution records.
|
|
99
99
|
|
|
@@ -117,7 +117,7 @@ No extension is privileged. The Claude adapter ships bundled with the reference
|
|
|
117
117
|
|
|
118
118
|
## Extension kinds
|
|
119
119
|
|
|
120
|
-
Six kinds, all first-class, all loaded through the same registry. Each kind has a JSON Schema describing its manifest shape under `
|
|
120
|
+
Six kinds, all first-class, all loaded through the same registry. Each kind has a JSON Schema describing its manifest shape under [`schemas/extensions/`](./schemas/extensions/). Implementations MUST validate every extension manifest against the schema for its declared kind at load time; validation failure → the extension is skipped with status `invalid-manifest`.
|
|
121
121
|
|
|
122
122
|
| Kind | Role | Input | Output |
|
|
123
123
|
|---|---|---|---|
|
|
@@ -134,7 +134,7 @@ Every `Adapter` extension MUST declare a map `defaultRefreshAction: { <kind>: <a
|
|
|
134
134
|
|
|
135
135
|
### Detector · trigger normalization
|
|
136
136
|
|
|
137
|
-
Detectors that emit invocation-style links (slashes, at-directives, command names) populate the `link.trigger` block defined in `schemas/link.schema.json
|
|
137
|
+
Detectors that emit invocation-style links (slashes, at-directives, command names) populate the `link.trigger` block defined in [`schemas/link.schema.json`](./schemas/link.schema.json):
|
|
138
138
|
|
|
139
139
|
- `originalTrigger` — the exact source text the detector saw, byte-for-byte. Used only for display.
|
|
140
140
|
- `normalizedTrigger` — the output of the pipeline below. Used for equality and collision detection — the built-in `trigger-collision` rule keys on this field.
|
|
@@ -171,7 +171,7 @@ Characters outside the separator set that are not letters or digits (e.g. `/`, `
|
|
|
171
171
|
|
|
172
172
|
1. An extension declares its kind in its module export and its manifest. Kind mismatch → load-error.
|
|
173
173
|
2. An extension MAY declare `preconditions` — predicates that must be satisfied for the extension to be offered (e.g., `action.requires: ["kind=skill"]`).
|
|
174
|
-
3. An extension MUST NOT retain state across invocations. Scoped persistence goes through `ctx.store` (storage mode `kv`) or the plugin's dedicated tables (`dedicated`).
|
|
174
|
+
3. An extension MUST NOT retain state across invocations. Scoped persistence goes through `ctx.store` (storage mode `kv`) or the plugin's dedicated tables (`dedicated`). See [`plugin-kv-api.md`](./plugin-kv-api.md).
|
|
175
175
|
4. An extension MUST NOT import another extension directly. Cross-extension communication goes through the kernel's registry lookup.
|
|
176
176
|
5. An extension MUST provide a sibling test file. The reference impl treats a missing test as a contract-check failure; other impls MAY relax this to a warning.
|
|
177
177
|
|
|
@@ -248,6 +248,19 @@ This is what makes "CLI-first" a coherent rule: every CLI verb is a kernel funct
|
|
|
248
248
|
|
|
249
249
|
---
|
|
250
250
|
|
|
251
|
+
## See also
|
|
252
|
+
|
|
253
|
+
- [`cli-contract.md`](./cli-contract.md) — verb surface of the CLI driving adapter.
|
|
254
|
+
- [`db-schema.md`](./db-schema.md) — table catalog backing `StoragePort`.
|
|
255
|
+
- [`job-lifecycle.md`](./job-lifecycle.md) — state machine for jobs, atomic claim, TTL/reap.
|
|
256
|
+
- [`job-events.md`](./job-events.md) — event stream emitted through `ProgressEmitterPort`.
|
|
257
|
+
- [`prompt-preamble.md`](./prompt-preamble.md) — canonical injection-mitigation preamble for job files.
|
|
258
|
+
- [`plugin-kv-api.md`](./plugin-kv-api.md) — `ctx.store` contract for extension persistence.
|
|
259
|
+
- [`versioning.md`](./versioning.md) — spec/impl version independence and semver policy.
|
|
260
|
+
- [`interfaces/security-scanner.md`](./interfaces/security-scanner.md) — convention over the Action kind for security scanners.
|
|
261
|
+
|
|
262
|
+
---
|
|
263
|
+
|
|
251
264
|
## Stability
|
|
252
265
|
|
|
253
266
|
The **port list** is stable as of spec v1.0.0. Adding a sixth port is a major bump.
|
package/cli-contract.md
CHANGED
|
@@ -384,6 +384,17 @@ The `done in …` stderr line, its format grammar, and the `elapsedMs` field con
|
|
|
384
384
|
|
|
385
385
|
---
|
|
386
386
|
|
|
387
|
+
## See also
|
|
388
|
+
|
|
389
|
+
- [`architecture.md`](./architecture.md) — CLI as a driving adapter; kernel-first design; dependency rules.
|
|
390
|
+
- [`job-lifecycle.md`](./job-lifecycle.md) — state machine behind `sm job` verbs.
|
|
391
|
+
- [`job-events.md`](./job-events.md) — event stream emitted via `--json` and `--stream-output`.
|
|
392
|
+
- [`db-schema.md`](./db-schema.md) — tables behind `sm db` verbs.
|
|
393
|
+
- [`../docs/cli-reference.md`](../docs/cli-reference.md) — auto-generated reference from `sm help --format md`.
|
|
394
|
+
- [`conformance/`](./conformance/README.md) — test suite exercising CLI behavior.
|
|
395
|
+
|
|
396
|
+
---
|
|
397
|
+
|
|
387
398
|
## Stability
|
|
388
399
|
|
|
389
400
|
The **verb list** is stable as of spec v1.0.0. Adding a verb is a minor bump. Removing a verb is a major bump.
|
package/conformance/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Language-neutral test suite the specification demands. A conforming implementation passes every case; failing any case is a conformance bug.
|
|
4
4
|
|
|
5
|
-
This directory is **stub-level** as of spec v0.1.0. Two cases ship (`basic-scan`, `kernel-empty-boot`) with a single shared fixture (`minimal-claude`). The shape below is normative; the case count expands before spec-v1.0.0 (see `versioning.md`).
|
|
5
|
+
This directory is **stub-level** as of spec v0.1.0. Two cases ship (`basic-scan`, `kernel-empty-boot`) with a single shared fixture (`minimal-claude`). The shape below is normative; the case count expands before spec-v1.0.0 (see [`../versioning.md`](../versioning.md)). See [`coverage.md`](./coverage.md) for the full schema-to-case matrix.
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -33,7 +33,7 @@ Fixtures are read-only inputs. Cases declare what to invoke and what to assert.
|
|
|
33
33
|
|
|
34
34
|
## Case format
|
|
35
35
|
|
|
36
|
-
Cases are validated against [`
|
|
36
|
+
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.dev/spec/v0/conformance-case.schema.json"` in every case file for IDE support.
|
|
37
37
|
|
|
38
38
|
A case is a JSON document with this shape:
|
|
39
39
|
|
|
@@ -106,7 +106,7 @@ Cases explicitly referenced elsewhere in the spec (landing before v1.0):
|
|
|
106
106
|
|
|
107
107
|
| Id | Source | Verifies |
|
|
108
108
|
|---|---|---|
|
|
109
|
-
| `preamble-bitwise-match` | `prompt-preamble.md` | Rendered job files contain `preamble-v1.txt` byte-for-byte. Deferred to Step
|
|
109
|
+
| `preamble-bitwise-match` | `prompt-preamble.md` | Rendered job files contain `preamble-v1.txt` byte-for-byte. Deferred to Step 10 (requires `sm job preview`). |
|
|
110
110
|
|
|
111
111
|
---
|
|
112
112
|
|
|
@@ -132,6 +132,15 @@ The reference implementation's runner will ship under `src/conformance/` during
|
|
|
132
132
|
|
|
133
133
|
---
|
|
134
134
|
|
|
135
|
+
## See also
|
|
136
|
+
|
|
137
|
+
- [`coverage.md`](./coverage.md) — schema-to-case coverage matrix and release gates.
|
|
138
|
+
- [`../versioning.md`](../versioning.md) — what constitutes a major/minor/patch change to the suite.
|
|
139
|
+
- [`../architecture.md`](../architecture.md) — kernel empty-boot invariant exercised by `kernel-empty-boot`.
|
|
140
|
+
- [`../prompt-preamble.md`](../prompt-preamble.md) — verbatim text checked by `preamble-bitwise-match` (deferred).
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
135
144
|
## Stability
|
|
136
145
|
|
|
137
146
|
- The **case format** above is stable as of the first spec release that includes the suite. Adding an assertion type is a minor bump. Removing or changing one is a major bump.
|
package/conformance/coverage.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Conformance coverage
|
|
2
2
|
|
|
3
|
-
Authoritative map of JSON Schemas in
|
|
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 ([`../../AGENTS.md`](../../AGENTS.md) §Rules for AI agents editing spec/).
|
|
4
4
|
|
|
5
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.
|
|
6
6
|
|
|
@@ -12,10 +12,10 @@ This file is hand-maintained. A CI check before spec release compares the schema
|
|
|
12
12
|
| 2 | `link.schema.json` | — | 🔴 missing | Needs fixture with at least one `invokes` + `references` + `mentions` link, both `high`/`medium`/`low` confidence. |
|
|
13
13
|
| 3 | `issue.schema.json` | — | 🔴 missing | Needs fixture triggering `trigger-collision` + `broken-ref` + `superseded`. |
|
|
14
14
|
| 4 | `scan-result.schema.json` | `basic-scan`, `kernel-empty-boot` | 🟢 covered | Zero-filled (empty-boot) + populated (minimal-claude) both asserted. |
|
|
15
|
-
| 5 | `execution-record.schema.json` | — | 🔴 missing | Blocked by Step
|
|
15
|
+
| 5 | `execution-record.schema.json` | — | 🔴 missing | Blocked by Step 5 (history). Needs a case that runs a `local` action and inspects `state_executions` via `sm history --json`. |
|
|
16
16
|
| 6 | `project-config.schema.json` | — | 🔴 missing | Case: init a scope, write a partial `.skill-map.json`, assert effective config after merge. |
|
|
17
17
|
| 7 | `plugins-registry.schema.json` | — | 🔴 missing | Two sub-cases required: (a) `PluginManifest` validation via `sm plugins show --json`; (b) aggregate `PluginsRegistry` via `sm plugins list --json`. |
|
|
18
|
-
| 8 | `job.schema.json` | — | 🔴 missing | Blocked by Step
|
|
18
|
+
| 8 | `job.schema.json` | — | 🔴 missing | Blocked by Step 10 (job system). Needs a case that submits a local action (no LLM), inspects `sm job show --json`. |
|
|
19
19
|
| 9 | `report-base.schema.json` | — | 🔴 missing | Indirect coverage once any summarizer case lands. Direct contract case: validate a handcrafted minimal report ({confidence, safety}) against the base schema. |
|
|
20
20
|
| 10 | `conformance-case.schema.json` | — | 🔴 missing | Self-referential: every `*.json` under `cases/` MUST validate against this schema. Add a meta-case that enumerates + validates all cases. |
|
|
21
21
|
| 11 | `frontmatter/base.schema.json` | `basic-scan` (indirect) | 🟡 partial | Covered via every kind schema's `allOf`. Direct case: fixture with min-required frontmatter only. |
|
|
@@ -24,11 +24,11 @@ This file is hand-maintained. A CI check before spec release compares the schema
|
|
|
24
24
|
| 14 | `frontmatter/command.schema.json` | `basic-scan` | 🟢 covered | One command in `minimal-claude`. |
|
|
25
25
|
| 15 | `frontmatter/hook.schema.json` | `basic-scan` | 🟢 covered | One hook in `minimal-claude`. |
|
|
26
26
|
| 16 | `frontmatter/note.schema.json` | `basic-scan` | 🟢 covered | One note in `minimal-claude`. |
|
|
27
|
-
| 17 | `summaries/skill.schema.json` | — | 🔴 missing | Blocked by Step
|
|
28
|
-
| 18 | `summaries/agent.schema.json` | — | 🔴 missing | Blocked by Step
|
|
29
|
-
| 19 | `summaries/command.schema.json` | — | 🔴 missing | Blocked by Step
|
|
30
|
-
| 20 | `summaries/hook.schema.json` | — | 🔴 missing | Blocked by Step
|
|
31
|
-
| 21 | `summaries/note.schema.json` | — | 🔴 missing | Blocked by Step
|
|
27
|
+
| 17 | `summaries/skill.schema.json` | — | 🔴 missing | Blocked by Step 10 (`skill-summarizer`). Case: submit summarizer, validate report. |
|
|
28
|
+
| 18 | `summaries/agent.schema.json` | — | 🔴 missing | Blocked by Step 11. |
|
|
29
|
+
| 19 | `summaries/command.schema.json` | — | 🔴 missing | Blocked by Step 11. |
|
|
30
|
+
| 20 | `summaries/hook.schema.json` | — | 🔴 missing | Blocked by Step 11. |
|
|
31
|
+
| 21 | `summaries/note.schema.json` | — | 🔴 missing | Blocked by Step 11. |
|
|
32
32
|
| 22 | `extensions/base.schema.json` | — | 🔴 missing | Meta-case: every manifest under `src/extensions/` validates against the appropriate kind schema (which extends base via `allOf`). |
|
|
33
33
|
| 23 | `extensions/adapter.schema.json` | — | 🔴 missing | Case: the `claude` adapter manifest validates; a crafted invalid manifest (missing `defaultRefreshAction`) fails with `invalid-manifest`. |
|
|
34
34
|
| 24 | `extensions/detector.schema.json` | — | 🔴 missing | Case: `frontmatter` + `slash` + `at-directive` detector manifests validate; a detector emitting a disallowed `emitsLinkKinds` value fails. |
|
|
@@ -36,7 +36,7 @@ This file is hand-maintained. A CI check before spec release compares the schema
|
|
|
36
36
|
| 26 | `extensions/action.schema.json` | — | 🔴 missing | Case: a `local` action manifest validates; an `invocation-template` action WITHOUT `promptTemplateRef` fails. |
|
|
37
37
|
| 27 | `extensions/audit.schema.json` | — | 🔴 missing | Case: `validate-all` audit manifest validates; an audit referencing a non-existent rule id in `composes` fails at load with `invalid-manifest`. |
|
|
38
38
|
| 28 | `extensions/renderer.schema.json` | — | 🔴 missing | Case: `ascii` renderer manifest validates. |
|
|
39
|
-
| 29 | `history-stats.schema.json` | — | 🔴 missing | Blocked by Step
|
|
39
|
+
| 29 | `history-stats.schema.json` | — | 🔴 missing | Blocked by Step 5 (history). Case: seed `state_executions` with a deterministic fixture, run `sm history stats --json --since <T0> --until <T1> --period month --top 5`, assert the document validates and that `totals.executionsCount == sum(perAction.executionsCount)` and `errorRates.global == totals.failedCount / totals.executionsCount`. Percentiles (`p95`/`p99`) intentionally omitted in v1 — add later as a minor bump without breaking consumers. |
|
|
40
40
|
|
|
41
41
|
Status legend: 🟢 covered (at least one case asserts the schema end-to-end) · 🟡 partial (covered only indirectly or via a sub-shape) · 🔴 missing.
|
|
42
42
|
|
|
@@ -46,18 +46,18 @@ These have their own conformance cases even though they are not JSON Schemas.
|
|
|
46
46
|
|
|
47
47
|
| # | Artifact | Case | Status | Notes |
|
|
48
48
|
|---|---|---|---|---|
|
|
49
|
-
| A | Preamble verbatim text | `preamble-bitwise-match` | 🟠 deferred | Deferred to Step
|
|
49
|
+
| A | Preamble verbatim text | `preamble-bitwise-match` | 🟠 deferred | Deferred to Step 10 (needs `sm job preview` to render a job file). Fixture: `fixtures/preamble-v1.txt` (already present, byte-identical to `prompt-preamble.md` source). |
|
|
50
50
|
| B | Kernel empty-boot invariant | `kernel-empty-boot` | 🟢 covered | All extensions disabled → empty ScanResult. |
|
|
51
|
-
| C | Atomic-claim race safety | — | 🔴 missing | Blocked by Step
|
|
52
|
-
| D | Duplicate detection | — | 🔴 missing | Blocked by Step
|
|
53
|
-
| E | `--force` bypass | — | 🔴 missing | Blocked by Step
|
|
54
|
-
| F | Nonce mismatch | — | 🔴 missing | Blocked by Step
|
|
55
|
-
| G | Reap | — | 🔴 missing | Blocked by Step
|
|
56
|
-
| H | `run.*` event envelope for Skill agent | — | 🔴 missing | Blocked by Step
|
|
57
|
-
| I | Rename heuristic | — | 🔴 missing | Blocked by Step
|
|
58
|
-
| J | Plugin DDL rejection | — | 🔴 missing | Blocked by Step
|
|
59
|
-
| K | Plugin prefix injection | — | 🔴 missing | Blocked by Step
|
|
60
|
-
| L | Elapsed-time reporting | — | 🔴 missing | Blocked by Step
|
|
51
|
+
| C | Atomic-claim race safety | — | 🔴 missing | Blocked by Step 10. Two concurrent `sm job claim` invocations against a single queued row — exactly one MUST succeed. |
|
|
52
|
+
| D | Duplicate detection | — | 🔴 missing | Blocked by Step 10. Two `sm job submit` with same `(action, version, node, contentHash)` — second exits 3. |
|
|
53
|
+
| E | `--force` bypass | — | 🔴 missing | Blocked by Step 10. |
|
|
54
|
+
| F | Nonce mismatch | — | 🔴 missing | Blocked by Step 10. `sm record` with wrong nonce → exit 4. |
|
|
55
|
+
| G | Reap | — | 🔴 missing | Blocked by Step 10. Set TTL to 1s; claim; wait; next `sm job run` reaps with reason `abandoned`. |
|
|
56
|
+
| H | `run.*` event envelope for Skill agent | — | 🔴 missing | Blocked by Step 10. Skill-agent flow emits synthetic `r-ext-*` run envelope around one job. |
|
|
57
|
+
| I | Rename heuristic | — | 🔴 missing | Blocked by Step 5. Move a file; same-`body_hash` → high-confidence auto-rename; `state_*` FK rows migrated; no issue emitted. |
|
|
58
|
+
| J | Plugin DDL rejection | — | 🔴 missing | Blocked by Step 9. Plugin migration referencing `state_jobs` → disabled with `invalid-manifest`. |
|
|
59
|
+
| K | Plugin prefix injection | — | 🔴 missing | Blocked by Step 9. Plugin declares `CREATE TABLE foo` → kernel applies as `plugin_<id>_foo`. |
|
|
60
|
+
| L | Elapsed-time reporting | — | 🔴 missing | Blocked by Step 4 (first real verb work). Run any in-scope verb; stderr last line MUST match `/^done in (\d+ms\|\d+\.\d+s\|\d+m \d+s)$/`. In-scope verb with `--json` returning an object MUST carry `elapsedMs`. Exempt verb (`sm version`) MUST NOT emit the line. |
|
|
61
61
|
|
|
62
62
|
## Release gates
|
|
63
63
|
|
package/db-schema.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# Database schema
|
|
2
2
|
|
|
3
|
-
Normative catalog of tables owned by the kernel. Plugins MAY add their own tables under a strict prefix (see `plugin-kv-api.md`). An implementation MUST provision every kernel table described here and MUST reject writes that violate the stated constraints.
|
|
3
|
+
Normative catalog of tables owned by the kernel. Plugins MAY add their own tables under a strict prefix (see [`plugin-kv-api.md`](./plugin-kv-api.md)). An implementation MUST provision every kernel table described here and MUST reject writes that violate the stated constraints.
|
|
4
4
|
|
|
5
5
|
The spec assumes a relational, SQL-like store but is **engine-agnostic**. The reference implementation uses SQLite (`node:sqlite`) + Kysely + `CamelCasePlugin`. Alternative backends (Postgres, DuckDB, in-memory) are permitted as long as:
|
|
6
6
|
|
|
7
|
-
- Atomic single-statement transitions are available for the job claim (see `job-lifecycle.md`).
|
|
7
|
+
- Atomic single-statement transitions are available for the job claim (see [`job-lifecycle.md`](./job-lifecycle.md)).
|
|
8
8
|
- Migrations track applied versions per scope.
|
|
9
9
|
- Read isolation avoids phantom reads inside a single scan write.
|
|
10
10
|
|
|
@@ -67,7 +67,7 @@ Domain types exposed to driving adapters use `camelCase`. The SQLite reference i
|
|
|
67
67
|
|
|
68
68
|
### `scan_nodes`
|
|
69
69
|
|
|
70
|
-
One row per detected node, matching `schemas/node.schema.json
|
|
70
|
+
One row per detected node, matching [`schemas/node.schema.json`](./schemas/node.schema.json).
|
|
71
71
|
|
|
72
72
|
| Column | Type | Constraint | Notes |
|
|
73
73
|
|---|---|---|---|
|
|
@@ -97,7 +97,7 @@ Indexes: `ix_scan_nodes_kind`, `ix_scan_nodes_adapter`, `ix_scan_nodes_body_hash
|
|
|
97
97
|
|
|
98
98
|
### `scan_links`
|
|
99
99
|
|
|
100
|
-
One row per detected link, matching `schemas/link.schema.json
|
|
100
|
+
One row per detected link, matching [`schemas/link.schema.json`](./schemas/link.schema.json).
|
|
101
101
|
|
|
102
102
|
| Column | Type | Constraint | Notes |
|
|
103
103
|
|---|---|---|---|
|
|
@@ -118,7 +118,7 @@ Indexes: `ix_scan_links_source_path`, `ix_scan_links_target_path`, `ix_scan_link
|
|
|
118
118
|
|
|
119
119
|
### `scan_issues`
|
|
120
120
|
|
|
121
|
-
One row per rule-emitted issue, matching `schemas/issue.schema.json
|
|
121
|
+
One row per rule-emitted issue, matching [`schemas/issue.schema.json`](./schemas/issue.schema.json).
|
|
122
122
|
|
|
123
123
|
| Column | Type | Constraint | Notes |
|
|
124
124
|
|---|---|---|---|
|
|
@@ -140,7 +140,7 @@ Indexes: `ix_scan_issues_rule_id`, `ix_scan_issues_severity`.
|
|
|
140
140
|
|
|
141
141
|
### `state_jobs`
|
|
142
142
|
|
|
143
|
-
Matching `schemas/job.schema.json
|
|
143
|
+
Matching [`schemas/job.schema.json`](./schemas/job.schema.json). See [`job-lifecycle.md`](./job-lifecycle.md) for the state machine and transitions.
|
|
144
144
|
|
|
145
145
|
| Column | Type | Constraint |
|
|
146
146
|
|---|---|---|
|
|
@@ -166,7 +166,7 @@ Indexes: `ix_state_jobs_status`, `ix_state_jobs_action_node_hash` (unique partia
|
|
|
166
166
|
|
|
167
167
|
### `state_executions`
|
|
168
168
|
|
|
169
|
-
Matching `schemas/execution-record.schema.json
|
|
169
|
+
Matching [`schemas/execution-record.schema.json`](./schemas/execution-record.schema.json).
|
|
170
170
|
|
|
171
171
|
| Column | Type | Constraint |
|
|
172
172
|
|---|---|---|
|
|
@@ -192,7 +192,7 @@ Indexes: `ix_state_executions_extension_id`, `ix_state_executions_started_at`, `
|
|
|
192
192
|
|
|
193
193
|
### `state_summaries`
|
|
194
194
|
|
|
195
|
-
One row per `(node_id, summarizer_action_id)`. See `schemas/summaries
|
|
195
|
+
One row per `(node_id, summarizer_action_id)`. See [`schemas/summaries/`](./schemas/summaries/).
|
|
196
196
|
|
|
197
197
|
| Column | Type | Constraint |
|
|
198
198
|
|---|---|---|
|
|
@@ -223,7 +223,7 @@ Primary key: `(node_id, provider_id)`. Indexes: `ix_state_enrichments_stale_afte
|
|
|
223
223
|
|
|
224
224
|
### `state_plugin_kvs`
|
|
225
225
|
|
|
226
|
-
Shared key-value store for plugins that declared storage mode `kv`. See `plugin-kv-api.md` for the accessor contract.
|
|
226
|
+
Shared key-value store for plugins that declared storage mode `kv`. See [`plugin-kv-api.md`](./plugin-kv-api.md) for the accessor contract.
|
|
227
227
|
|
|
228
228
|
| Column | Type | Constraint |
|
|
229
229
|
|---|---|---|
|
|
@@ -294,11 +294,11 @@ The kernel ALSO maintains `PRAGMA user_version` (or the engine equivalent) as a
|
|
|
294
294
|
|
|
295
295
|
## Plugin storage
|
|
296
296
|
|
|
297
|
-
Two modes declared in `plugin.json` (see `schemas/plugins-registry.schema.json`).
|
|
297
|
+
Two modes declared in `plugin.json` (see [`schemas/plugins-registry.schema.json`](./schemas/plugins-registry.schema.json)).
|
|
298
298
|
|
|
299
299
|
| Mode | Manifest | Backing |
|
|
300
300
|
|---|---|---|
|
|
301
|
-
| **KV** (mode A) | `"storage": { "mode": "kv" }` | Shared `state_plugin_kvs`. See `plugin-kv-api.md
|
|
301
|
+
| **KV** (mode A) | `"storage": { "mode": "kv" }` | Shared `state_plugin_kvs`. See [`plugin-kv-api.md`](./plugin-kv-api.md). |
|
|
302
302
|
| **Dedicated** (mode B) | `"storage": { "mode": "dedicated", "tables": [...], "migrations": [...] }` | Plugin-owned tables, prefixed `plugin_<normalized_id>_`. |
|
|
303
303
|
|
|
304
304
|
Normalization of `plugin_id` for the prefix:
|
|
@@ -386,6 +386,15 @@ Failures are reported with suggested remediation (e.g., "run `sm db migrate`", "
|
|
|
386
386
|
|
|
387
387
|
---
|
|
388
388
|
|
|
389
|
+
## See also
|
|
390
|
+
|
|
391
|
+
- [`architecture.md`](./architecture.md) — `StoragePort` interface definition and dependency rules.
|
|
392
|
+
- [`plugin-kv-api.md`](./plugin-kv-api.md) — `ctx.store` accessor for mode A / mode B persistence.
|
|
393
|
+
- [`job-lifecycle.md`](./job-lifecycle.md) — atomic claim and TTL/reap semantics that drive `state_jobs`.
|
|
394
|
+
- [`cli-contract.md`](./cli-contract.md) — `sm db` verb surface (reset, backup, restore, migrate).
|
|
395
|
+
|
|
396
|
+
---
|
|
397
|
+
|
|
389
398
|
## Stability
|
|
390
399
|
|
|
391
400
|
The **three-zone model** and the **naming conventions** are stable as of spec v1.0.0. Adding a fourth zone is a major bump.
|
package/index.json
CHANGED
|
@@ -190,30 +190,30 @@
|
|
|
190
190
|
}
|
|
191
191
|
]
|
|
192
192
|
},
|
|
193
|
-
"specPackageVersion": "0.5.
|
|
193
|
+
"specPackageVersion": "0.5.1",
|
|
194
194
|
"integrity": {
|
|
195
195
|
"algorithm": "sha256",
|
|
196
196
|
"files": {
|
|
197
|
-
"CHANGELOG.md": "
|
|
198
|
-
"README.md": "
|
|
199
|
-
"architecture.md": "
|
|
200
|
-
"cli-contract.md": "
|
|
201
|
-
"conformance/README.md": "
|
|
197
|
+
"CHANGELOG.md": "b810067bdba655d066242db3159a157880250257c6cff03e96acc614758b8d1d",
|
|
198
|
+
"README.md": "8bd57e02d9a9d3f0a4efd18c0f0bd1f4bbe13eb206add0317659e48eab435e7e",
|
|
199
|
+
"architecture.md": "99f9d6a1a90e6c96d3c8a6f36c2650da4a1af0a1bc21173ea8eb2c492008539a",
|
|
200
|
+
"cli-contract.md": "4f01df640f39eacbb2192d543288e670de9ce2b89bf3931bc09f8488eb3baaea",
|
|
201
|
+
"conformance/README.md": "79c5e63f18a368951dc9f3e31e9bf9574de3f8b97150b2d75365d4febd8eb6dc",
|
|
202
202
|
"conformance/cases/basic-scan.json": "24623da0cad8c8c54b3ff9b09820ea1276fe8b8f0fc680bf6e8abeb4edb8e424",
|
|
203
203
|
"conformance/cases/kernel-empty-boot.json": "175524674b14d993d29f10080d7697074b3a2eee25b359ff903344d73c6acc98",
|
|
204
|
-
"conformance/coverage.md": "
|
|
204
|
+
"conformance/coverage.md": "db9518f5a560b3df01093107de5c09ff38d478ae07c0476eea92644677fb1d83",
|
|
205
205
|
"conformance/fixtures/minimal-claude/agents/reviewer.md": "d0dd681ba63838301e480116aa09825329f01832b0116de5c5476fdd8a5dcf54",
|
|
206
206
|
"conformance/fixtures/minimal-claude/commands/status.md": "3f36e053fd1c059ffd902f84a55be8a458c26072f97cb37dd7e97314ae2a9bf5",
|
|
207
207
|
"conformance/fixtures/minimal-claude/hooks/pre-commit.md": "ec9cec8ac4ce34d40ec055ffd90e8f06ea3e5764d6ec3ee84e0d97de71b930c7",
|
|
208
208
|
"conformance/fixtures/minimal-claude/notes/architecture.md": "5a7e6fdbb1556733dacebad63758057dc1e19090b5a983292c0c65e90b98bcf1",
|
|
209
209
|
"conformance/fixtures/minimal-claude/skills/hello.md": "8598074020430f294ff1eac39876302448f004b6c48446d453092159319bcbee",
|
|
210
210
|
"conformance/fixtures/preamble-v1.txt": "1e0aeef224b64477bdc13a949c3ad402e68249caf499ecdba1302371677c068b",
|
|
211
|
-
"db-schema.md": "
|
|
212
|
-
"interfaces/security-scanner.md": "
|
|
213
|
-
"job-events.md": "
|
|
214
|
-
"job-lifecycle.md": "
|
|
215
|
-
"plugin-kv-api.md": "
|
|
216
|
-
"prompt-preamble.md": "
|
|
211
|
+
"db-schema.md": "ce4f9ddf84fa2aad746b44d6d9142b29b23c339e4915f97928489e035100fa55",
|
|
212
|
+
"interfaces/security-scanner.md": "81dc3dc2c439a75f4603b6d52e714f44ac564032c8aa424385ebbf4502adae3e",
|
|
213
|
+
"job-events.md": "08796b7fbeb55e5b03cf3bc394224e70a23438a4d15a46ad1d70121c2c68b967",
|
|
214
|
+
"job-lifecycle.md": "1fe88b1a2ed204e41bb41ac172fbb3e912dccd0dd8a1f8ea8e21a681b336d6ee",
|
|
215
|
+
"plugin-kv-api.md": "04b2178f46fb88adeae9240df9c9e1761b660396072001dac32cd402e11a2d7d",
|
|
216
|
+
"prompt-preamble.md": "23a8eff0477fbbc46192a27781bc781bda4202bb9c669b7a7a002b0d668146b0",
|
|
217
217
|
"schemas/conformance-case.schema.json": "2740874e00269de6d8121300339401d0283197b6d97dcd77538ec5d108b14de2",
|
|
218
218
|
"schemas/execution-record.schema.json": "ec0f3acf1d0ce099c059d73eb434936bfd1bcf12023693bd572efb2a7352faa6",
|
|
219
219
|
"schemas/extensions/action.schema.json": "c7520d3cefecf75d27d3e04473821fd6e5dc5a7924eede147f74275ba6caccad",
|
|
@@ -243,7 +243,7 @@
|
|
|
243
243
|
"schemas/summaries/hook.schema.json": "36f876f3b1a60d45be97a0848c79fd18744b434dfdcefc366f033b253d56268c",
|
|
244
244
|
"schemas/summaries/note.schema.json": "ae510f3ee1b6092c1061625e425c9bb7de9c9caa3f3774770c148f658d505753",
|
|
245
245
|
"schemas/summaries/skill.schema.json": "f01bab92c51d64ee23e61587e42cf0dc5b37a2f518f5b12b3d1d456390338aa8",
|
|
246
|
-
"versioning.md": "
|
|
246
|
+
"versioning.md": "996e62006423edc01151a6f7869605f76c5e1454cc30b38d9f616925b5bcfb64"
|
|
247
247
|
}
|
|
248
248
|
}
|
|
249
249
|
}
|
|
@@ -10,7 +10,7 @@ Normative contract for third-party security-scanning plugins (Snyk, Socket, cust
|
|
|
10
10
|
|
|
11
11
|
## Why a convention, not a new kind
|
|
12
12
|
|
|
13
|
-
The six extension kinds are locked (`architecture.md`). Adding a seventh for "security" would conflate concerns: scanners are really actions that produce a specialized report. A convention lets any Action opt into the scanner surface without kernel changes.
|
|
13
|
+
The six extension kinds are locked ([`architecture.md`](../architecture.md)). Adding a seventh for "security" would conflate concerns: scanners are really actions that produce a specialized report. A convention lets any Action opt into the scanner surface without kernel changes.
|
|
14
14
|
|
|
15
15
|
---
|
|
16
16
|
|
|
@@ -55,7 +55,7 @@ Scanners are **local-mode** Actions by default: no LLM involvement. The Action r
|
|
|
55
55
|
|
|
56
56
|
## Output: the `SecurityReport` shape
|
|
57
57
|
|
|
58
|
-
Every scanner MUST produce a report conforming to this shape. It extends `report-base.schema.json` with scanner-specific fields.
|
|
58
|
+
Every scanner MUST produce a report conforming to this shape. It extends [`report-base.schema.json`](../schemas/report-base.schema.json) with scanner-specific fields.
|
|
59
59
|
|
|
60
60
|
```jsonc
|
|
61
61
|
{
|
|
@@ -156,7 +156,7 @@ Vendors MAY introduce their own category with the prefix `vendor:<slug>` (e.g. `
|
|
|
156
156
|
## Runtime model
|
|
157
157
|
|
|
158
158
|
- Scanners are invoked through the standard job system: `sm job submit security-snyk -n <node.path>` or `sm job submit security-snyk --all`.
|
|
159
|
-
- The report is persisted through the normal action report mechanism (`state_executions.report_path` points to the JSON file).
|
|
159
|
+
- The report is persisted through the normal action report mechanism ([`state_executions`](../db-schema.md)`.report_path` points to the JSON file).
|
|
160
160
|
- `sm findings --security` aggregates findings from reports whose action id starts with `security-`, merging across scanners, deduplicating by `finding.id`.
|
|
161
161
|
- Implementations MAY also surface findings at scan time via a companion Rule (e.g. `security-findings-stale` flags nodes whose last security scan is older than a threshold). This is recommended but not normative.
|
|
162
162
|
|
|
@@ -202,7 +202,7 @@ The Web UI's Security panel:
|
|
|
202
202
|
|
|
203
203
|
## Schema file location
|
|
204
204
|
|
|
205
|
-
The JSON Schema for `SecurityReport` lives at `spec/schemas/summaries/security.schema.json` once Step
|
|
205
|
+
The JSON Schema for `SecurityReport` lives at `spec/schemas/summaries/security.schema.json` once Step 4 of the spec bootstrap completes. Until then, this document is the normative source and vendors SHOULD derive their own validator from it.
|
|
206
206
|
|
|
207
207
|
This is the only `summaries/*` schema that does NOT correspond to a node kind; it corresponds to an action category instead.
|
|
208
208
|
|
|
@@ -216,6 +216,15 @@ A scanner that produces a report NOT conforming to `SecurityReport` is still a v
|
|
|
216
216
|
|
|
217
217
|
---
|
|
218
218
|
|
|
219
|
+
## See also
|
|
220
|
+
|
|
221
|
+
- [`../architecture.md`](../architecture.md) — extension kinds (Action) and the kernel contract.
|
|
222
|
+
- [`../job-lifecycle.md`](../job-lifecycle.md) — job submit/claim/record flow for scanner invocations.
|
|
223
|
+
- [`../prompt-preamble.md`](../prompt-preamble.md) — `report-base` shape (safety + confidence) that scanner reports extend.
|
|
224
|
+
- [`../db-schema.md`](../db-schema.md) — `state_executions` where scanner reports are persisted.
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
219
228
|
## Stability
|
|
220
229
|
|
|
221
230
|
**Stability: experimental** as of spec v0.x. Field names and conventions MAY tighten before v1.0 once real scanner implementations (Snyk, Socket, custom) ship and reveal shape needs.
|
package/job-events.md
CHANGED
|
@@ -8,7 +8,7 @@ This document is **normative**. The set of event types, their payload shapes, an
|
|
|
8
8
|
|
|
9
9
|
## Transport
|
|
10
10
|
|
|
11
|
-
Events are records produced by the kernel through `ProgressEmitterPort` (see `architecture.md`). An implementation MUST provide three output adapters:
|
|
11
|
+
Events are records produced by the kernel through `ProgressEmitterPort` (see [`architecture.md`](./architecture.md)). An implementation MUST provide three output adapters:
|
|
12
12
|
|
|
13
13
|
| Adapter | Purpose | Format |
|
|
14
14
|
|---|---|---|
|
|
@@ -254,7 +254,7 @@ Emitted when a job transitions to `failed` by any path.
|
|
|
254
254
|
}
|
|
255
255
|
```
|
|
256
256
|
|
|
257
|
-
`reason` enum matches `execution-record.failureReason`. `message` is human-readable free-form; MAY be truncated for display.
|
|
257
|
+
`reason` enum matches [`execution-record.schema.json`](./schemas/execution-record.schema.json) `failureReason`. `message` is human-readable free-form; MAY be truncated for display.
|
|
258
258
|
|
|
259
259
|
### `run.summary`
|
|
260
260
|
|
|
@@ -308,7 +308,7 @@ A parallel implementation MAY interleave per-job sequences across different `job
|
|
|
308
308
|
|
|
309
309
|
These event families cover kernel activity other than job execution. They share the common envelope (`type`, `timestamp`, `runId`, `jobId`, `data`). For non-job events `jobId` is always `null`; `runId` identifies the invocation that produced the event — a scan gets an `r-scan-YYYYMMDD-HHMMSS-XXXX` id, an issue recomputation outside a scan gets an `r-check-...` id, following the same `r-<mode>-...` shape as the external-Skill synthetic envelope (`r-ext-...`).
|
|
310
310
|
|
|
311
|
-
The **shapes below are experimental through spec v0.x**. The reference impl starts emitting them at Step
|
|
311
|
+
The **shapes below are experimental through spec v0.x**. The reference impl starts emitting them at Step 13 alongside the WebSocket broadcaster; once real consumers exercise the stream, the fields lock. Bumping them to `stable` is a minor spec bump; changes to field shapes before `stable` are allowed without a major bump (per [`versioning.md`](./versioning.md) §Pre-1.0).
|
|
312
312
|
|
|
313
313
|
### Scan events
|
|
314
314
|
|
|
@@ -429,6 +429,14 @@ Consumers MAY treat `emitter.error` as a soft failure (log and continue). Implem
|
|
|
429
429
|
|
|
430
430
|
---
|
|
431
431
|
|
|
432
|
+
## See also
|
|
433
|
+
|
|
434
|
+
- [`architecture.md`](./architecture.md) — `ProgressEmitterPort` definition.
|
|
435
|
+
- [`job-lifecycle.md`](./job-lifecycle.md) — state machine that drives these events.
|
|
436
|
+
- [`cli-contract.md`](./cli-contract.md) — `--json` and `--stream-output` flag semantics.
|
|
437
|
+
|
|
438
|
+
---
|
|
439
|
+
|
|
432
440
|
## Stability
|
|
433
441
|
|
|
434
442
|
The **job event type list** (`run.*`, `job.*`, `model.delta`, `emitter.error`) is stable as of spec v1.0.0. Adding a new event type is a minor bump. Removing or renaming one is a major bump.
|
|
@@ -439,4 +447,4 @@ Consumers MUST ignore unknown fields (forward compatibility).
|
|
|
439
447
|
|
|
440
448
|
The envelope (`type`, `timestamp`, `runId`, `jobId`, `data`) is stable. Adding an envelope field is a major bump because every consumer would need to handle it.
|
|
441
449
|
|
|
442
|
-
The **non-job event families** (`scan.*`, `issue.*`) are marked **experimental** across spec v0.x. They ship alongside the WebSocket broadcaster at Step
|
|
450
|
+
The **non-job event families** (`scan.*`, `issue.*`) are marked **experimental** across spec v0.x. They ship alongside the WebSocket broadcaster at Step 13 of the reference impl; shapes may tighten before a stable tag lands. Once promoted to `stable` (a minor spec bump), the same add/remove/rename semantics as the job events apply.
|
package/job-lifecycle.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Job lifecycle
|
|
2
2
|
|
|
3
|
-
Normative state machine for jobs. A `Job` (see `schemas/job.schema.json`) is the runtime instance of an `Action` applied to one or more `Node`s. Every job moves through this lifecycle exactly once.
|
|
3
|
+
Normative state machine for jobs. A `Job` (see [`schemas/job.schema.json`](./schemas/job.schema.json)) is the runtime instance of an `Action` applied to one or more `Node`s. Every job moves through this lifecycle exactly once.
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -56,7 +56,7 @@ Any other transition attempt MUST be rejected and MUST NOT mutate state. Impleme
|
|
|
56
56
|
5. Compute `ttlSeconds` per §TTL resolution below. Frozen on `state_jobs.ttlSeconds` for the life of this job.
|
|
57
57
|
6. Resolve `priority` (integer, default `0`). Precedence (lowest → highest): action manifest `defaultPriority` → user config `jobs.perActionPriority.<actionId>` → flag `--priority <n>`. Higher runs first; ties broken by `createdAt ASC`. Negative values are permitted and run after the default bucket. The resolved value is frozen on `state_jobs.priority` at submit time and is immutable for the life of the job.
|
|
58
58
|
7. Generate `nonce` (implementation-chosen; MUST be cryptographically random, ≥ 128 bits of entropy).
|
|
59
|
-
8. Render the job file at `.skill-map/jobs/<id>.md`, applying the canonical preamble (see `prompt-preamble.md`).
|
|
59
|
+
8. Render the job file at `.skill-map/jobs/<id>.md`, applying the canonical preamble (see [`prompt-preamble.md`](./prompt-preamble.md)).
|
|
60
60
|
9. Insert a row in `state_jobs` with `status = 'queued'`, `createdAt = now`.
|
|
61
61
|
10. Return the job id.
|
|
62
62
|
|
|
@@ -166,9 +166,9 @@ Negative or zero values MUST be rejected with exit 2 at submit time.
|
|
|
166
166
|
2. Compare the supplied nonce against `state_jobs.nonce`. Mismatch → exit 4 without mutation.
|
|
167
167
|
3. If `state_jobs.status != 'running'` → exit 2 with message "job not in running state". This catches late callbacks after a reap.
|
|
168
168
|
4. If `--status completed`: validate the report file against the action's declared report schema. On validation failure → transition to `failed` with reason `report-invalid`; DO NOT stay `running`.
|
|
169
|
-
5. Write the execution record (see `schemas/execution-record.schema.json`) with the full metrics.
|
|
169
|
+
5. Write the execution record (see [`schemas/execution-record.schema.json`](./schemas/execution-record.schema.json)) with the full metrics.
|
|
170
170
|
6. Transition the job to the terminal state.
|
|
171
|
-
7. Emit `job.callback.received` followed by `job.completed` or `job.failed
|
|
171
|
+
7. Emit `job.callback.received` followed by `job.completed` or `job.failed` (see [`job-events.md`](./job-events.md)).
|
|
172
172
|
|
|
173
173
|
The nonce is the sole authentication factor. A compromised nonce allows forged callbacks for that single job. Nonces MUST be generated per-job; never reused; never logged at info level or above.
|
|
174
174
|
|
|
@@ -236,6 +236,16 @@ Config controls (`jobs.retention.completed`, `jobs.retention.failed`):
|
|
|
236
236
|
|
|
237
237
|
---
|
|
238
238
|
|
|
239
|
+
## See also
|
|
240
|
+
|
|
241
|
+
- [`architecture.md`](./architecture.md) — `RunnerPort` definition; driving-adapter peer rule for Skill agents.
|
|
242
|
+
- [`job-events.md`](./job-events.md) — canonical event stream emitted during job execution.
|
|
243
|
+
- [`prompt-preamble.md`](./prompt-preamble.md) — verbatim preamble prepended to every rendered job file.
|
|
244
|
+
- [`db-schema.md`](./db-schema.md) — `state_jobs` and `state_executions` table catalogs.
|
|
245
|
+
- [`cli-contract.md`](./cli-contract.md) — `sm job` verb surface and exit codes.
|
|
246
|
+
|
|
247
|
+
---
|
|
248
|
+
|
|
239
249
|
## Stability
|
|
240
250
|
|
|
241
251
|
The state machine diagram above is **stable** as of spec v1.0.0. Adding a new state is a major bump. Adding a new terminal reason (`failureReason` enum value) is a minor bump.
|
package/package.json
CHANGED
package/plugin-kv-api.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Plugin KV API
|
|
2
2
|
|
|
3
|
-
Normative contract for plugin-accessible persistence. Two modes exist (see `db-schema.md` for the catalog entries):
|
|
3
|
+
Normative contract for plugin-accessible persistence. Two modes exist (see [`db-schema.md`](./db-schema.md) for the catalog entries):
|
|
4
4
|
|
|
5
5
|
- **Mode A — KV**: plugin uses the kernel-provided `ctx.store.*` accessor. Backed by the shared `state_plugin_kvs` table.
|
|
6
6
|
- **Mode B — Dedicated**: plugin owns its own tables with the `plugin_<normalizedId>_` prefix, migrated by the kernel.
|
|
@@ -54,7 +54,7 @@ Operations MAY be additionally scoped by `nodePath`:
|
|
|
54
54
|
- **Global KV (no `nodePath`)**: `{pluginId, nodePath: null, key}`. One row per plugin + key.
|
|
55
55
|
- **Node-scoped KV (with `nodePath`)**: `{pluginId, nodePath: "<path>", key}`. One row per plugin + node + key.
|
|
56
56
|
|
|
57
|
-
Both scopes share the same underlying `state_plugin_kvs` table (see `db-schema.md`). The `nodePath` column is nullable; implementations MUST use a sentinel empty string internally when the backing engine rejects NULL in composite primary keys.
|
|
57
|
+
Both scopes share the same underlying `state_plugin_kvs` table (see [`db-schema.md`](./db-schema.md)). The `nodePath` column is nullable; implementations MUST use a sentinel empty string internally when the backing engine rejects NULL in composite primary keys.
|
|
58
58
|
|
|
59
59
|
### Semantics
|
|
60
60
|
|
|
@@ -102,7 +102,7 @@ Errors MUST NOT leak backend-specific details (SQL strings, file paths) to plugi
|
|
|
102
102
|
|
|
103
103
|
## Mode B: dedicated tables
|
|
104
104
|
|
|
105
|
-
Mode B is governed by `db-schema.md` (catalog rules + triple protection). This section restates the API surface.
|
|
105
|
+
Mode B is governed by [`db-schema.md`](./db-schema.md) (catalog rules + triple protection). This section restates the API surface.
|
|
106
106
|
|
|
107
107
|
### Declaration
|
|
108
108
|
|
|
@@ -147,7 +147,7 @@ Mode B plugins MAY call `db.transaction(async (tx) => { ... })`. The kernel prov
|
|
|
147
147
|
- Index and constraint prefixes are similarly injected.
|
|
148
148
|
- A failing plugin migration disables only that plugin (`status: load-error`); other plugins and the kernel continue.
|
|
149
149
|
|
|
150
|
-
See `db-schema.md` for the normative migration rules.
|
|
150
|
+
See [`db-schema.md`](./db-schema.md) for the normative migration rules.
|
|
151
151
|
|
|
152
152
|
---
|
|
153
153
|
|
|
@@ -168,7 +168,7 @@ Non-normative; descriptive guidance for plugin authors.
|
|
|
168
168
|
- Your data model is actually tabular (cache with TTL, observation log, provider registry).
|
|
169
169
|
- You are willing to own migrations forever.
|
|
170
170
|
|
|
171
|
-
A plugin MUST declare **exactly one** storage mode. Mixing modes in the same plugin is forbidden. The `plugins-registry.schema.json` enforces this at the manifest level (`storage` is a `oneOf` between `kv` and `dedicated`), and at runtime `ctx.store` exposes either the `KvStore` or the `DedicatedStore` shape — never both. A plugin that needs both KV-like and relational access MUST use mode B and implement KV-style rows as a dedicated table.
|
|
171
|
+
A plugin MUST declare **exactly one** storage mode. Mixing modes in the same plugin is forbidden. The [`plugins-registry.schema.json`](./schemas/plugins-registry.schema.json) enforces this at the manifest level (`storage` is a `oneOf` between `kv` and `dedicated`), and at runtime `ctx.store` exposes either the `KvStore` or the `DedicatedStore` shape — never both. A plugin that needs both KV-like and relational access MUST use mode B and implement KV-style rows as a dedicated table.
|
|
172
172
|
|
|
173
173
|
---
|
|
174
174
|
|
|
@@ -201,6 +201,13 @@ Post-v1.0 work: signed manifest, sandboxed worker-thread isolation, per-plugin D
|
|
|
201
201
|
|
|
202
202
|
---
|
|
203
203
|
|
|
204
|
+
## See also
|
|
205
|
+
|
|
206
|
+
- [`db-schema.md`](./db-schema.md) — table catalog, migration rules, triple protection for mode B.
|
|
207
|
+
- [`architecture.md`](./architecture.md) — extension contract rules and `ctx.store` injection via the kernel.
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
204
211
|
## Stability
|
|
205
212
|
|
|
206
213
|
- The `KvStore` interface (method names, options, return shapes) is **stable** as of spec v1.0.0.
|
package/prompt-preamble.md
CHANGED
|
@@ -99,10 +99,10 @@ The preamble establishes a promise from the model:
|
|
|
99
99
|
|
|
100
100
|
- Every report MUST be valid JSON.
|
|
101
101
|
- Every report MUST contain `safety` and `confidence` at the top level.
|
|
102
|
-
- `safety` MUST conform to `schemas/report-base.schema.json
|
|
102
|
+
- `safety` MUST conform to [`schemas/report-base.schema.json`](./schemas/report-base.schema.json)`#/properties/safety`.
|
|
103
103
|
- `confidence` MUST be a number in `[0.0, 1.0]`.
|
|
104
104
|
|
|
105
|
-
The kernel validates every report against the action's declared schema (which MUST extend `report-base.schema.json`). A report that lacks `safety` or `confidence`, or whose values are of the wrong shape, is rejected; the job transitions to `failed` with reason `report-invalid` (see `job-lifecycle.md`).
|
|
105
|
+
The kernel validates every report against the action's declared schema (which MUST extend [`report-base.schema.json`](./schemas/report-base.schema.json)). A report that lacks `safety` or `confidence`, or whose values are of the wrong shape, is rejected; the job transitions to `failed` with reason `report-invalid` (see [`job-lifecycle.md`](./job-lifecycle.md)).
|
|
106
106
|
|
|
107
107
|
Implementations MUST NOT tolerate the absence of `safety`. If a model returns a report without it, the failure is the runner's problem to surface, not the kernel's to tolerate.
|
|
108
108
|
|
|
@@ -125,13 +125,13 @@ Implementations MUST NOT modify the preamble text at runtime (e.g., based on loc
|
|
|
125
125
|
|
|
126
126
|
## Versioning the preamble
|
|
127
127
|
|
|
128
|
-
The preamble text is a **normative artifact** of the spec. Any change follows `versioning.md
|
|
128
|
+
The preamble text is a **normative artifact** of the spec. Any change follows [`versioning.md`](./versioning.md):
|
|
129
129
|
|
|
130
130
|
- Editorial fixes to examples (none exist today, keep it that way) — patch bump.
|
|
131
131
|
- Tightening the instructions (e.g., adding a new refusal clause) — minor bump.
|
|
132
|
-
- Changing the shape the model must emit (`safety` structure) — major bump, because it propagates to `report-base.schema.json
|
|
132
|
+
- Changing the shape the model must emit (`safety` structure) — major bump, because it propagates to [`report-base.schema.json`](./schemas/report-base.schema.json).
|
|
133
133
|
|
|
134
|
-
Every spec release that modifies the preamble MUST record the rationale in `CHANGELOG.md
|
|
134
|
+
Every spec release that modifies the preamble MUST record the rationale in [`CHANGELOG.md`](./CHANGELOG.md).
|
|
135
135
|
|
|
136
136
|
---
|
|
137
137
|
|
|
@@ -147,6 +147,15 @@ Defense-in-depth: the deterministic rule `injection-pattern` (shipped as a built
|
|
|
147
147
|
|
|
148
148
|
---
|
|
149
149
|
|
|
150
|
+
## See also
|
|
151
|
+
|
|
152
|
+
- [`job-lifecycle.md`](./job-lifecycle.md) — submit flow that renders job files with the preamble.
|
|
153
|
+
- [`architecture.md`](./architecture.md) — kernel's role in applying the preamble.
|
|
154
|
+
- [`interfaces/security-scanner.md`](./interfaces/security-scanner.md) — `SecurityReport` convention that extends `report-base`.
|
|
155
|
+
- [`conformance/`](./conformance/README.md) — `preamble-bitwise-match` case (deferred to Step 10).
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
150
159
|
## Stability
|
|
151
160
|
|
|
152
|
-
The verbatim text above is **stable** as of spec v1.0.0. It is reproduced in the conformance suite as `conformance/fixtures/preamble-v1.txt
|
|
161
|
+
The verbatim text above is **stable** as of spec v1.0.0. It is reproduced in the conformance suite as [`conformance/fixtures/preamble-v1.txt`](./conformance/fixtures/preamble-v1.txt). Any implementation whose rendered job files do not contain this text verbatim fails the conformance check `preamble-bitwise-match`.
|
package/versioning.md
CHANGED
|
@@ -28,7 +28,7 @@ Rule of thumb: if a strict v1 implementation could fail a v1.X conformance run,
|
|
|
28
28
|
All of the following are normative and governed by this policy:
|
|
29
29
|
|
|
30
30
|
- Every JSON Schema in `schemas/` (fields, types, required, enums, defaults, `additionalProperties`).
|
|
31
|
-
- Every MUST / SHOULD / MAY statement in prose documents (`architecture.md
|
|
31
|
+
- Every MUST / SHOULD / MAY statement in prose documents ([`architecture.md`](./architecture.md), [`cli-contract.md`](./cli-contract.md), [`job-events.md`](./job-events.md), [`prompt-preamble.md`](./prompt-preamble.md), [`db-schema.md`](./db-schema.md), [`plugin-kv-api.md`](./plugin-kv-api.md), [`job-lifecycle.md`](./job-lifecycle.md)).
|
|
32
32
|
- Exit codes, verb names, required flags, canonical error messages marked "normative".
|
|
33
33
|
- Conformance fixtures and cases — removing or tightening a case is major.
|
|
34
34
|
|
|
@@ -77,9 +77,9 @@ The first stable commitment is `spec-v1.0.0`. In the current reference roadmap,
|
|
|
77
77
|
## Change process
|
|
78
78
|
|
|
79
79
|
1. PR proposes a spec change. Include rationale and classification (patch/minor/major).
|
|
80
|
-
2. If major, PR includes a migration note draft for `CHANGELOG.md
|
|
80
|
+
2. If major, PR includes a migration note draft for [`CHANGELOG.md`](./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 `AGENTS.md
|
|
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`](../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
|