@skill-map/spec 0.2.1 → 0.3.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 +272 -1
- package/README.md +68 -39
- package/architecture.md +45 -4
- package/cli-contract.md +54 -10
- package/conformance/coverage.md +66 -0
- package/db-schema.md +47 -11
- package/index.json +22 -12
- package/job-events.md +123 -3
- package/job-lifecycle.md +48 -14
- package/package.json +1 -1
- package/plugin-kv-api.md +7 -5
- package/schemas/extensions/action.schema.json +81 -0
- package/schemas/extensions/adapter.schema.json +40 -0
- package/schemas/extensions/audit.schema.json +47 -0
- package/schemas/extensions/base.schema.json +44 -0
- package/schemas/extensions/detector.schema.json +35 -0
- package/schemas/extensions/renderer.schema.json +29 -0
- package/schemas/extensions/rule.schema.json +37 -0
- package/schemas/frontmatter/agent.schema.json +1 -6
- package/schemas/frontmatter/base.schema.json +10 -0
- package/schemas/history-stats.schema.json +172 -0
- package/schemas/plugins-registry.schema.json +1 -1
- package/schemas/project-config.schema.json +42 -7
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://skill-map.dev/spec/v0/history-stats.schema.json",
|
|
4
|
+
"title": "HistoryStats",
|
|
5
|
+
"description": "Machine-readable output of `sm history stats --json`. Aggregates over `state_executions` within a time window. camelCase keys throughout. The `elapsedMs` top-level field is the command's own wall-clock (see `cli-contract.md` §Elapsed time) — distinct from `totals.durationMsTotal`, which is the sum of every execution record's duration.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": [
|
|
8
|
+
"schemaVersion",
|
|
9
|
+
"range",
|
|
10
|
+
"totals",
|
|
11
|
+
"tokensPerAction",
|
|
12
|
+
"executionsPerPeriod",
|
|
13
|
+
"topNodes",
|
|
14
|
+
"errorRates",
|
|
15
|
+
"elapsedMs"
|
|
16
|
+
],
|
|
17
|
+
"additionalProperties": false,
|
|
18
|
+
"properties": {
|
|
19
|
+
"schemaVersion": {
|
|
20
|
+
"type": "integer",
|
|
21
|
+
"const": 1
|
|
22
|
+
},
|
|
23
|
+
"range": {
|
|
24
|
+
"type": "object",
|
|
25
|
+
"required": ["since", "until"],
|
|
26
|
+
"additionalProperties": false,
|
|
27
|
+
"properties": {
|
|
28
|
+
"since": {
|
|
29
|
+
"type": ["string", "null"],
|
|
30
|
+
"format": "date-time",
|
|
31
|
+
"description": "Inclusive lower bound (ISO-8601). `null` means all-time — the earliest execution record is used."
|
|
32
|
+
},
|
|
33
|
+
"until": {
|
|
34
|
+
"type": "string",
|
|
35
|
+
"format": "date-time",
|
|
36
|
+
"description": "Exclusive upper bound (ISO-8601). Defaults to `now()` at command invocation."
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
"totals": {
|
|
41
|
+
"type": "object",
|
|
42
|
+
"required": [
|
|
43
|
+
"executionsCount",
|
|
44
|
+
"completedCount",
|
|
45
|
+
"failedCount",
|
|
46
|
+
"tokensIn",
|
|
47
|
+
"tokensOut",
|
|
48
|
+
"durationMsTotal"
|
|
49
|
+
],
|
|
50
|
+
"additionalProperties": false,
|
|
51
|
+
"properties": {
|
|
52
|
+
"executionsCount": { "type": "integer", "minimum": 0 },
|
|
53
|
+
"completedCount": { "type": "integer", "minimum": 0 },
|
|
54
|
+
"failedCount": { "type": "integer", "minimum": 0 },
|
|
55
|
+
"tokensIn": { "type": "integer", "minimum": 0, "description": "Sum of `state_executions.tokens_in`. `null` values in the source are treated as 0." },
|
|
56
|
+
"tokensOut": { "type": "integer", "minimum": 0 },
|
|
57
|
+
"durationMsTotal": { "type": "integer", "minimum": 0, "description": "Sum of every execution's `duration_ms`. NOT the command's wall-clock — see `elapsedMs`." }
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
"tokensPerAction": {
|
|
61
|
+
"type": "array",
|
|
62
|
+
"description": "One row per distinct `(actionId, actionVersion)` pair in the window. Sorted by `tokensIn + tokensOut` descending.",
|
|
63
|
+
"items": {
|
|
64
|
+
"type": "object",
|
|
65
|
+
"required": ["actionId", "actionVersion", "executionsCount", "tokensIn", "tokensOut"],
|
|
66
|
+
"additionalProperties": false,
|
|
67
|
+
"properties": {
|
|
68
|
+
"actionId": { "type": "string" },
|
|
69
|
+
"actionVersion": { "type": "string" },
|
|
70
|
+
"executionsCount": { "type": "integer", "minimum": 0 },
|
|
71
|
+
"tokensIn": { "type": "integer", "minimum": 0 },
|
|
72
|
+
"tokensOut": { "type": "integer", "minimum": 0 },
|
|
73
|
+
"durationMsMean": { "type": ["integer", "null"], "minimum": 0, "description": "Rounded mean duration over the action's executions. `null` when `executionsCount == 0`." },
|
|
74
|
+
"durationMsMedian": { "type": ["integer", "null"], "minimum": 0, "description": "Median duration. `null` when `executionsCount == 0`." }
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
"executionsPerPeriod": {
|
|
79
|
+
"type": "array",
|
|
80
|
+
"description": "Time-bucketed counts. Bucket granularity follows the `--period` flag (`day` | `week` | `month`). `periodStart` always ISO-8601; `periodUnit` present so consumers can group without parsing the date shape.",
|
|
81
|
+
"items": {
|
|
82
|
+
"type": "object",
|
|
83
|
+
"required": ["periodStart", "periodUnit", "executionsCount", "tokensIn", "tokensOut"],
|
|
84
|
+
"additionalProperties": false,
|
|
85
|
+
"properties": {
|
|
86
|
+
"periodStart": {
|
|
87
|
+
"type": "string",
|
|
88
|
+
"format": "date-time",
|
|
89
|
+
"description": "Start of the bucket (UTC). For `day`: `YYYY-MM-DDT00:00:00.000Z`. For `week`: Monday 00:00 UTC. For `month`: day-1 00:00 UTC."
|
|
90
|
+
},
|
|
91
|
+
"periodUnit": {
|
|
92
|
+
"type": "string",
|
|
93
|
+
"enum": ["day", "week", "month"]
|
|
94
|
+
},
|
|
95
|
+
"executionsCount": { "type": "integer", "minimum": 0 },
|
|
96
|
+
"tokensIn": { "type": "integer", "minimum": 0 },
|
|
97
|
+
"tokensOut": { "type": "integer", "minimum": 0 }
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
"topNodes": {
|
|
102
|
+
"type": "array",
|
|
103
|
+
"description": "Most-frequently-executed nodes in the window. Sorted by `executionsCount` descending, tie-broken by `lastExecutedAt` descending. Length controlled by `--top N` (default 10).",
|
|
104
|
+
"items": {
|
|
105
|
+
"type": "object",
|
|
106
|
+
"required": ["nodePath", "executionsCount", "lastExecutedAt"],
|
|
107
|
+
"additionalProperties": false,
|
|
108
|
+
"properties": {
|
|
109
|
+
"nodePath": {
|
|
110
|
+
"type": "string",
|
|
111
|
+
"description": "Canonical node identifier (relative path from scope root). MAY point to a node that no longer exists (orphan in history)."
|
|
112
|
+
},
|
|
113
|
+
"executionsCount": { "type": "integer", "minimum": 1 },
|
|
114
|
+
"lastExecutedAt": { "type": "integer", "minimum": 0, "description": "Unix ms of the most recent execution against this node within the window." }
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
"errorRates": {
|
|
119
|
+
"type": "object",
|
|
120
|
+
"required": ["global", "perAction", "perFailureReason"],
|
|
121
|
+
"additionalProperties": false,
|
|
122
|
+
"properties": {
|
|
123
|
+
"global": {
|
|
124
|
+
"type": "number",
|
|
125
|
+
"minimum": 0,
|
|
126
|
+
"maximum": 1,
|
|
127
|
+
"description": "`failedCount / executionsCount` across the window. `0` when `executionsCount == 0`."
|
|
128
|
+
},
|
|
129
|
+
"perAction": {
|
|
130
|
+
"type": "array",
|
|
131
|
+
"items": {
|
|
132
|
+
"type": "object",
|
|
133
|
+
"required": ["actionId", "rate", "executionsCount", "failedCount"],
|
|
134
|
+
"additionalProperties": false,
|
|
135
|
+
"properties": {
|
|
136
|
+
"actionId": { "type": "string" },
|
|
137
|
+
"rate": { "type": "number", "minimum": 0, "maximum": 1 },
|
|
138
|
+
"executionsCount": { "type": "integer", "minimum": 0 },
|
|
139
|
+
"failedCount": { "type": "integer", "minimum": 0 }
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
},
|
|
143
|
+
"perFailureReason": {
|
|
144
|
+
"type": "object",
|
|
145
|
+
"description": "Counts (not ratios) per failure reason. Every enum value of `state_executions.failure_reason` appears, with `0` when no occurrences — predictable shape for dashboards.",
|
|
146
|
+
"required": [
|
|
147
|
+
"runner-error",
|
|
148
|
+
"report-invalid",
|
|
149
|
+
"timeout",
|
|
150
|
+
"abandoned",
|
|
151
|
+
"job-file-missing",
|
|
152
|
+
"user-cancelled"
|
|
153
|
+
],
|
|
154
|
+
"additionalProperties": false,
|
|
155
|
+
"properties": {
|
|
156
|
+
"runner-error": { "type": "integer", "minimum": 0 },
|
|
157
|
+
"report-invalid": { "type": "integer", "minimum": 0 },
|
|
158
|
+
"timeout": { "type": "integer", "minimum": 0 },
|
|
159
|
+
"abandoned": { "type": "integer", "minimum": 0 },
|
|
160
|
+
"job-file-missing": { "type": "integer", "minimum": 0 },
|
|
161
|
+
"user-cancelled": { "type": "integer", "minimum": 0 }
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
},
|
|
166
|
+
"elapsedMs": {
|
|
167
|
+
"type": "integer",
|
|
168
|
+
"minimum": 0,
|
|
169
|
+
"description": "Command's own wall-clock in milliseconds, from invocation to emission. Per `cli-contract.md` §Elapsed time: reported on stdout whenever the shape is an object (like this one), and always on stderr as `done in <formatted>`."
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"required": ["mode"],
|
|
45
45
|
"additionalProperties": false,
|
|
46
46
|
"properties": {
|
|
47
|
-
"mode": { "const": "kv", "description": "Shared `
|
|
47
|
+
"mode": { "const": "kv", "description": "Shared `state_plugin_kvs` table, scoped by plugin id." }
|
|
48
48
|
}
|
|
49
49
|
},
|
|
50
50
|
{
|
|
@@ -11,6 +11,14 @@
|
|
|
11
11
|
"const": 1,
|
|
12
12
|
"description": "Config file shape version. Bumped on breaking changes to this schema."
|
|
13
13
|
},
|
|
14
|
+
"autoMigrate": {
|
|
15
|
+
"type": "boolean",
|
|
16
|
+
"description": "Apply pending kernel and plugin migrations automatically at startup, after auto-backing-up the DB. Default true. When false, startup fails with exit 2 if migrations are pending; the user runs `sm db migrate` manually."
|
|
17
|
+
},
|
|
18
|
+
"tokenizer": {
|
|
19
|
+
"type": "string",
|
|
20
|
+
"description": "Name of the offline tokenizer used to compute per-node token counts during scan. Default `cl100k_base`. Stored alongside each token count in `scan_nodes` so consumers know which encoder produced the numbers. Changing this invalidates prior counts on next scan."
|
|
21
|
+
},
|
|
14
22
|
"adapters": {
|
|
15
23
|
"type": "array",
|
|
16
24
|
"description": "Adapter ids to enable, in priority order when multiple match. Empty/absent = use all registered.",
|
|
@@ -32,7 +40,12 @@
|
|
|
32
40
|
"properties": {
|
|
33
41
|
"tokenize": { "type": "boolean", "description": "Whether to compute token counts. Default true." },
|
|
34
42
|
"strict": { "type": "boolean", "description": "Promote frontmatter warnings to errors. Default false." },
|
|
35
|
-
"followSymlinks": { "type": "boolean", "description": "Default false." }
|
|
43
|
+
"followSymlinks": { "type": "boolean", "description": "Default false." },
|
|
44
|
+
"maxFileSizeBytes": {
|
|
45
|
+
"type": "integer",
|
|
46
|
+
"minimum": 1,
|
|
47
|
+
"description": "Files larger than this are skipped with an `info`-level log entry. Default 1048576 (1 MiB). Protects against scanning accidental binary drops or generated artefacts."
|
|
48
|
+
}
|
|
36
49
|
}
|
|
37
50
|
},
|
|
38
51
|
"plugins": {
|
|
@@ -53,12 +66,7 @@
|
|
|
53
66
|
"properties": {
|
|
54
67
|
"share": {
|
|
55
68
|
"type": "boolean",
|
|
56
|
-
"description": "When true, `./.skill-map/
|
|
57
|
-
},
|
|
58
|
-
"retentionDays": {
|
|
59
|
-
"type": "integer",
|
|
60
|
-
"minimum": 1,
|
|
61
|
-
"description": "How long to keep execution records before GC."
|
|
69
|
+
"description": "When true, `./.skill-map/skill-map.db` is expected to be committed — teams remove it from `.gitignore` so the execution log becomes a shared artefact. Stability: experimental. Default false."
|
|
62
70
|
}
|
|
63
71
|
}
|
|
64
72
|
},
|
|
@@ -66,12 +74,39 @@
|
|
|
66
74
|
"type": "object",
|
|
67
75
|
"additionalProperties": false,
|
|
68
76
|
"properties": {
|
|
77
|
+
"ttlSeconds": {
|
|
78
|
+
"type": "integer",
|
|
79
|
+
"minimum": 1,
|
|
80
|
+
"description": "Global fallback TTL (seconds) used when an action manifest omits `expectedDurationSeconds` — typically `mode: local` actions where the field is advisory. Default 3600. The submit-time resolution still applies `graceMultiplier` and `minimumTtlSeconds`."
|
|
81
|
+
},
|
|
69
82
|
"graceMultiplier": { "type": "number", "minimum": 1, "description": "Default grace multiplier applied to `expectedDurationSeconds`. Default 3." },
|
|
70
83
|
"minimumTtlSeconds": { "type": "integer", "minimum": 1, "description": "Floor for computed TTL. Default 60." },
|
|
71
84
|
"perActionTtl": {
|
|
72
85
|
"type": "object",
|
|
73
86
|
"description": "Per-action TTL overrides (seconds). Keys are action ids.",
|
|
74
87
|
"additionalProperties": { "type": "integer", "minimum": 1 }
|
|
88
|
+
},
|
|
89
|
+
"perActionPriority": {
|
|
90
|
+
"type": "object",
|
|
91
|
+
"description": "Per-action priority overrides. Keys are action ids, values are integers (higher runs first, negatives allowed). Frozen on `state_jobs.priority` at submit time. Overrides `defaultPriority` from the action manifest; `--priority` on `sm job submit` overrides both.",
|
|
92
|
+
"additionalProperties": { "type": "integer" }
|
|
93
|
+
},
|
|
94
|
+
"retention": {
|
|
95
|
+
"type": "object",
|
|
96
|
+
"additionalProperties": false,
|
|
97
|
+
"description": "Garbage-collection policy for `state_jobs` rows and their job files. `sm job prune` reads this; no implicit pruning during normal verbs.",
|
|
98
|
+
"properties": {
|
|
99
|
+
"completed": {
|
|
100
|
+
"type": ["integer", "null"],
|
|
101
|
+
"minimum": 1,
|
|
102
|
+
"description": "Seconds after `finishedAt` before a `completed` job is eligible for pruning. `null` = never auto-prune. Default 2592000 (30 days)."
|
|
103
|
+
},
|
|
104
|
+
"failed": {
|
|
105
|
+
"type": ["integer", "null"],
|
|
106
|
+
"minimum": 1,
|
|
107
|
+
"description": "Seconds after `finishedAt` before a `failed` job is eligible for pruning. `null` = never auto-prune. Default `null` — failed jobs are kept for post-mortem."
|
|
108
|
+
}
|
|
109
|
+
}
|
|
75
110
|
}
|
|
76
111
|
}
|
|
77
112
|
},
|