agent-security-lens 0.1.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.
Files changed (81) hide show
  1. package/.env.example +10 -0
  2. package/.mcp/server.json +42 -0
  3. package/CHANGELOG.md +17 -0
  4. package/LICENSE +17 -0
  5. package/PRIVACY.md +37 -0
  6. package/README.md +150 -0
  7. package/RELEASE-MANIFEST.json +449 -0
  8. package/SECURITY.md +24 -0
  9. package/apps/mcp-server/agent-security-lens-mcp.mjs +441 -0
  10. package/bin/agent-security-lens.mjs +117 -0
  11. package/data/ecosystems/agent-candidates.json +230 -0
  12. package/data/intelligence/components.json +22989 -0
  13. package/data/intelligence/security-evaluation-standard.json +221 -0
  14. package/data/recommendations/core/recommendations.json +256 -0
  15. package/data/trust/signal-taxonomy.json +107 -0
  16. package/docs/asl-agent-component-safety-standard-v0.2.md +56 -0
  17. package/examples/dot-hermes/.hermes/config.json +17 -0
  18. package/examples/dot-openclaw/.openclaw/openclaw.json +17 -0
  19. package/examples/hermes-like/.env.example +2 -0
  20. package/examples/hermes-like/config.json +37 -0
  21. package/examples/hermes-like/optional-mcps/github-tools.json +8 -0
  22. package/examples/hermes-like/skills/openclaw-imports/browser-skill/SKILL.md +8 -0
  23. package/examples/openclaw-like/.env.example +2 -0
  24. package/examples/openclaw-like/AGENTS.md +7 -0
  25. package/examples/openclaw-like/openclaw.json +28 -0
  26. package/examples/openclaw-like/workspace/skills/browser-control/SKILL.md +8 -0
  27. package/llms.txt +25 -0
  28. package/package.json +50 -0
  29. package/profiles/generic-agent/profile.json +19 -0
  30. package/profiles/hermes-like/profile.json +23 -0
  31. package/profiles/mcp-server/profile.json +18 -0
  32. package/profiles/openclaw-like/profile.json +22 -0
  33. package/profiles/skill-runtime/profile.json +19 -0
  34. package/rule-packs/core/rules.json +82 -0
  35. package/rule-packs/hermes/rules.json +44 -0
  36. package/rule-packs/mcp/rules.json +65 -0
  37. package/rule-packs/openclaw/rules.json +46 -0
  38. package/rule-packs/skills/rules.json +45 -0
  39. package/schemas/agent-install-decision.schema.json +432 -0
  40. package/schemas/agent-usage-event.schema.json +45 -0
  41. package/schemas/assessment-result.schema.json +361 -0
  42. package/schemas/comparison-result.schema.json +113 -0
  43. package/schemas/component-alternative-graph.schema.json +187 -0
  44. package/schemas/component-intelligence.schema.json +93 -0
  45. package/schemas/decision-feedback.schema.json +49 -0
  46. package/schemas/ecosystem-candidate-registry.schema.json +98 -0
  47. package/schemas/profile.schema.json +65 -0
  48. package/schemas/recommendation-pack.schema.json +114 -0
  49. package/schemas/rule-pack.schema.json +113 -0
  50. package/schemas/trust-signal-taxonomy.schema.json +68 -0
  51. package/scripts/verify-examples.mjs +121 -0
  52. package/scripts/verify-mcp-server.mjs +278 -0
  53. package/scripts/verify-registry.mjs +264 -0
  54. package/server.json +42 -0
  55. package/src/assessment/assess.mjs +108 -0
  56. package/src/assessment/discover-targets.mjs +127 -0
  57. package/src/assessment/risk-domains.mjs +83 -0
  58. package/src/assessment/summarize.mjs +57 -0
  59. package/src/core/files.mjs +74 -0
  60. package/src/intelligence/cloud-client.mjs +260 -0
  61. package/src/intelligence/component-intelligence.mjs +358 -0
  62. package/src/intelligence/decision-engine.mjs +772 -0
  63. package/src/intelligence/finding-context.mjs +180 -0
  64. package/src/intelligence/safety-score-v0.2.mjs +294 -0
  65. package/src/observations/json-observations.mjs +211 -0
  66. package/src/observations/observation-rules.mjs +157 -0
  67. package/src/profiles/load-profiles.mjs +130 -0
  68. package/src/recommendations/component-alternative-graph.mjs +94 -0
  69. package/src/recommendations/load-recommendations.mjs +17 -0
  70. package/src/recommendations/match-recommendations.mjs +79 -0
  71. package/src/report/comparison-console.mjs +71 -0
  72. package/src/report/console.mjs +103 -0
  73. package/src/report/markdown.mjs +145 -0
  74. package/src/results/compare-results.mjs +106 -0
  75. package/src/results/save-result.mjs +29 -0
  76. package/src/rules/load-rules.mjs +22 -0
  77. package/src/rules/match-rules.mjs +99 -0
  78. package/src/rules/supersedes.mjs +39 -0
  79. package/src/store/assessment-store.mjs +78 -0
  80. package/src/trust/derive-trust-signals.mjs +73 -0
  81. package/src/trust/load-trust-signals.mjs +17 -0
@@ -0,0 +1,361 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://agentsecuritylens.dev/schemas/assessment-result.schema.json",
4
+ "title": "AgentSecurityLens Assessment Result",
5
+ "type": "object",
6
+ "required": [
7
+ "schema_version",
8
+ "tool",
9
+ "assessment",
10
+ "lineage",
11
+ "profiles",
12
+ "rule_packs",
13
+ "recommendation_packs",
14
+ "trust_signal_taxonomies",
15
+ "trust_signals",
16
+ "summary",
17
+ "findings"
18
+ ],
19
+ "properties": {
20
+ "schema_version": {
21
+ "type": "string"
22
+ },
23
+ "tool": {
24
+ "type": "object",
25
+ "required": ["name", "version"],
26
+ "properties": {
27
+ "name": { "type": "string" },
28
+ "version": { "type": "string" }
29
+ },
30
+ "additionalProperties": false
31
+ },
32
+ "assessment": {
33
+ "type": "object",
34
+ "required": ["id", "target_path", "target_url", "started_at", "completed_at"],
35
+ "properties": {
36
+ "id": { "type": "string" },
37
+ "target_path": { "type": "string" },
38
+ "target_url": { "type": "string" },
39
+ "started_at": { "type": "string" },
40
+ "completed_at": { "type": "string" }
41
+ },
42
+ "additionalProperties": false
43
+ },
44
+ "lineage": {
45
+ "type": "object",
46
+ "required": ["profile_selection", "algorithms"],
47
+ "properties": {
48
+ "profile_selection": {
49
+ "type": "object",
50
+ "required": ["mode", "requested_profile", "selected_profile", "detection_signals"],
51
+ "properties": {
52
+ "mode": { "type": "string", "enum": ["requested", "autodetected"] },
53
+ "requested_profile": { "type": ["string", "null"] },
54
+ "selected_profile": { "type": "string" },
55
+ "detection_signals": {
56
+ "type": "array",
57
+ "items": {
58
+ "type": "object",
59
+ "required": ["type", "value"],
60
+ "properties": {
61
+ "type": { "type": "string" },
62
+ "value": { "type": "string" }
63
+ },
64
+ "additionalProperties": false
65
+ }
66
+ }
67
+ },
68
+ "additionalProperties": false
69
+ },
70
+ "algorithms": {
71
+ "type": "array",
72
+ "items": {
73
+ "type": "object",
74
+ "required": ["id", "version"],
75
+ "properties": {
76
+ "id": { "type": "string" },
77
+ "version": { "type": "string" }
78
+ },
79
+ "additionalProperties": false
80
+ }
81
+ }
82
+ },
83
+ "additionalProperties": false
84
+ },
85
+ "profiles": {
86
+ "type": "array",
87
+ "items": {
88
+ "type": "object",
89
+ "required": ["id", "version", "status", "confidence", "coverage", "known_limitations"],
90
+ "properties": {
91
+ "id": { "type": "string" },
92
+ "version": { "type": "string" },
93
+ "status": { "type": "string" },
94
+ "confidence": { "type": "number" },
95
+ "coverage": { "type": "number" },
96
+ "known_limitations": {
97
+ "type": "array",
98
+ "items": { "type": "string" }
99
+ }
100
+ },
101
+ "additionalProperties": false
102
+ }
103
+ },
104
+ "rule_packs": {
105
+ "type": "array",
106
+ "items": {
107
+ "type": "object",
108
+ "required": ["id", "version", "rule_count"],
109
+ "properties": {
110
+ "id": { "type": "string" },
111
+ "version": { "type": "string" },
112
+ "rule_count": { "type": "integer" }
113
+ },
114
+ "additionalProperties": false
115
+ }
116
+ },
117
+ "recommendation_packs": {
118
+ "type": "array",
119
+ "items": {
120
+ "type": "object",
121
+ "required": ["id", "version", "status", "recommendation_count"],
122
+ "properties": {
123
+ "id": { "type": "string" },
124
+ "version": { "type": "string" },
125
+ "status": { "type": "string" },
126
+ "recommendation_count": { "type": "integer" }
127
+ },
128
+ "additionalProperties": false
129
+ }
130
+ },
131
+ "trust_signal_taxonomies": {
132
+ "type": "array",
133
+ "items": {
134
+ "type": "object",
135
+ "required": ["id", "version", "status", "signal_count"],
136
+ "properties": {
137
+ "id": { "type": "string" },
138
+ "version": { "type": "string" },
139
+ "status": { "type": "string" },
140
+ "signal_count": { "type": "integer" }
141
+ },
142
+ "additionalProperties": false
143
+ }
144
+ },
145
+ "trust_signals": {
146
+ "type": "array",
147
+ "items": {
148
+ "type": "object",
149
+ "required": [
150
+ "id",
151
+ "signal_id",
152
+ "title",
153
+ "direction",
154
+ "weight",
155
+ "source_type",
156
+ "applies_to",
157
+ "description",
158
+ "evidence"
159
+ ],
160
+ "properties": {
161
+ "id": { "type": "string" },
162
+ "signal_id": { "type": "string" },
163
+ "title": { "type": "string" },
164
+ "direction": { "type": "string" },
165
+ "weight": { "type": "integer" },
166
+ "source_type": { "type": "string" },
167
+ "applies_to": {
168
+ "type": "array",
169
+ "items": { "type": "string" }
170
+ },
171
+ "description": { "type": "string" },
172
+ "evidence": {
173
+ "type": "object",
174
+ "required": ["finding_id", "rule_id", "path", "line", "preview"],
175
+ "properties": {
176
+ "finding_id": { "type": "string" },
177
+ "rule_id": { "type": "string" },
178
+ "path": { "type": "string" },
179
+ "line": { "type": "integer" },
180
+ "preview": { "type": "string" }
181
+ },
182
+ "additionalProperties": false
183
+ }
184
+ },
185
+ "additionalProperties": false
186
+ }
187
+ },
188
+ "summary": {
189
+ "type": "object",
190
+ "required": ["total_findings", "by_severity", "by_category", "trust_score", "scoring_model"],
191
+ "properties": {
192
+ "total_findings": { "type": "integer" },
193
+ "by_severity": { "type": "object" },
194
+ "by_category": { "type": "object" },
195
+ "trust_score": { "type": "integer" },
196
+ "scoring_model": { "type": "string" }
197
+ },
198
+ "additionalProperties": true
199
+ },
200
+ "observations": {
201
+ "type": "array",
202
+ "items": {
203
+ "type": "object",
204
+ "required": ["type", "path", "json_path", "line", "severity_hint"],
205
+ "properties": {
206
+ "type": { "type": "string" },
207
+ "path": { "type": "string" },
208
+ "json_path": { "type": "string" },
209
+ "line": { "type": "integer" },
210
+ "value": {},
211
+ "severity_hint": { "type": "string" }
212
+ },
213
+ "additionalProperties": false
214
+ }
215
+ },
216
+ "risk_domains": {
217
+ "type": "array",
218
+ "items": {
219
+ "type": "object",
220
+ "required": ["id", "title", "count", "highest_severity", "findings"],
221
+ "properties": {
222
+ "id": { "type": "string" },
223
+ "title": { "type": "string" },
224
+ "count": { "type": "integer" },
225
+ "highest_severity": { "type": ["string", "null"] },
226
+ "findings": {
227
+ "type": "array",
228
+ "items": { "type": "string" }
229
+ }
230
+ },
231
+ "additionalProperties": false
232
+ }
233
+ },
234
+ "findings": {
235
+ "type": "array",
236
+ "items": {
237
+ "type": "object",
238
+ "required": [
239
+ "id",
240
+ "rule_id",
241
+ "title",
242
+ "category",
243
+ "severity",
244
+ "confidence",
245
+ "permissions",
246
+ "profile_ids",
247
+ "why_it_matters",
248
+ "recommended_actions",
249
+ "recommended_alternatives",
250
+ "migration_instruction",
251
+ "evidence"
252
+ ],
253
+ "properties": {
254
+ "id": { "type": "string" },
255
+ "rule_id": { "type": "string" },
256
+ "title": { "type": "string" },
257
+ "category": { "type": "string" },
258
+ "severity": { "type": "string" },
259
+ "confidence": { "type": "number" },
260
+ "permissions": {
261
+ "type": "array",
262
+ "items": { "type": "string" }
263
+ },
264
+ "profile_ids": {
265
+ "type": "array",
266
+ "items": { "type": "string" }
267
+ },
268
+ "why_it_matters": { "type": "string" },
269
+ "recommended_actions": {
270
+ "type": "array",
271
+ "items": { "type": "string" }
272
+ },
273
+ "recommended_alternatives": {
274
+ "type": "array",
275
+ "items": { "type": "string" }
276
+ },
277
+ "migration_instruction": { "type": "string" },
278
+ "recommendations": {
279
+ "type": "array",
280
+ "items": {
281
+ "type": "object",
282
+ "required": [
283
+ "id",
284
+ "title",
285
+ "type",
286
+ "status",
287
+ "source",
288
+ "confidence",
289
+ "rank",
290
+ "recommended_actions",
291
+ "recommended_alternatives",
292
+ "agent_instruction",
293
+ "one_step_commands",
294
+ "rollback_note"
295
+ ],
296
+ "properties": {
297
+ "id": { "type": "string" },
298
+ "title": { "type": "string" },
299
+ "type": { "type": "string" },
300
+ "status": { "type": "string" },
301
+ "source": { "type": "string" },
302
+ "confidence": { "type": "number" },
303
+ "rank": { "type": "integer" },
304
+ "recommended_actions": {
305
+ "type": "array",
306
+ "items": { "type": "string" }
307
+ },
308
+ "recommended_alternatives": {
309
+ "type": "array",
310
+ "items": { "type": "string" }
311
+ },
312
+ "agent_instruction": { "type": "string" },
313
+ "one_step_commands": {
314
+ "type": "array",
315
+ "items": {
316
+ "type": "object",
317
+ "required": ["title", "command", "platform", "requires_confirmation"],
318
+ "properties": {
319
+ "title": { "type": "string" },
320
+ "command": { "type": "string" },
321
+ "platform": { "type": "string" },
322
+ "requires_confirmation": { "type": "boolean" }
323
+ },
324
+ "additionalProperties": false
325
+ }
326
+ },
327
+ "rollback_note": { "type": "string" }
328
+ },
329
+ "additionalProperties": false
330
+ }
331
+ },
332
+ "evidence": {
333
+ "type": "object",
334
+ "required": ["path", "line", "preview"],
335
+ "properties": {
336
+ "path": { "type": "string" },
337
+ "line": { "type": "integer" },
338
+ "preview": { "type": "string" }
339
+ },
340
+ "additionalProperties": false
341
+ },
342
+ "evidence_items": {
343
+ "type": "array",
344
+ "items": {
345
+ "type": "object",
346
+ "required": ["path", "line", "preview"],
347
+ "properties": {
348
+ "path": { "type": "string" },
349
+ "line": { "type": "integer" },
350
+ "preview": { "type": "string" }
351
+ },
352
+ "additionalProperties": false
353
+ }
354
+ }
355
+ },
356
+ "additionalProperties": false
357
+ }
358
+ }
359
+ },
360
+ "additionalProperties": false
361
+ }
@@ -0,0 +1,113 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://agentsecuritylens.dev/schemas/comparison-result.schema.json",
4
+ "title": "AgentSecurityLens Comparison Result",
5
+ "type": "object",
6
+ "required": [
7
+ "schema_version",
8
+ "comparison",
9
+ "score",
10
+ "finding_counts",
11
+ "profiles",
12
+ "rule_packs",
13
+ "recommendation_packs",
14
+ "findings"
15
+ ],
16
+ "properties": {
17
+ "schema_version": { "type": "string" },
18
+ "comparison": {
19
+ "type": "object",
20
+ "required": [
21
+ "previous_assessment_id",
22
+ "current_assessment_id",
23
+ "previous_completed_at",
24
+ "current_completed_at",
25
+ "compared_at"
26
+ ],
27
+ "properties": {
28
+ "previous_assessment_id": { "type": "string" },
29
+ "current_assessment_id": { "type": "string" },
30
+ "previous_completed_at": { "type": "string" },
31
+ "current_completed_at": { "type": "string" },
32
+ "compared_at": { "type": "string" }
33
+ },
34
+ "additionalProperties": false
35
+ },
36
+ "score": {
37
+ "type": "object",
38
+ "required": ["previous", "current", "delta"],
39
+ "properties": {
40
+ "previous": { "type": "integer" },
41
+ "current": { "type": "integer" },
42
+ "delta": { "type": "integer" }
43
+ },
44
+ "additionalProperties": false
45
+ },
46
+ "finding_counts": {
47
+ "type": "object",
48
+ "required": ["previous", "current", "added", "resolved", "persistent"],
49
+ "properties": {
50
+ "previous": { "type": "integer" },
51
+ "current": { "type": "integer" },
52
+ "added": { "type": "integer" },
53
+ "resolved": { "type": "integer" },
54
+ "persistent": { "type": "integer" }
55
+ },
56
+ "additionalProperties": false
57
+ },
58
+ "profiles": { "$ref": "#/$defs/versioned_diff" },
59
+ "rule_packs": { "$ref": "#/$defs/versioned_diff" },
60
+ "recommendation_packs": { "$ref": "#/$defs/versioned_diff" },
61
+ "findings": {
62
+ "type": "object",
63
+ "required": ["added", "resolved", "persistent"],
64
+ "properties": {
65
+ "added": { "$ref": "#/$defs/finding_list" },
66
+ "resolved": { "$ref": "#/$defs/finding_list" },
67
+ "persistent": { "$ref": "#/$defs/finding_list" }
68
+ },
69
+ "additionalProperties": false
70
+ }
71
+ },
72
+ "$defs": {
73
+ "versioned_diff": {
74
+ "type": "object",
75
+ "required": ["added", "removed", "changed"],
76
+ "properties": {
77
+ "added": { "type": "array", "items": { "type": "object" } },
78
+ "removed": { "type": "array", "items": { "type": "object" } },
79
+ "changed": {
80
+ "type": "array",
81
+ "items": {
82
+ "type": "object",
83
+ "required": ["id", "previous_version", "current_version"],
84
+ "properties": {
85
+ "id": { "type": "string" },
86
+ "previous_version": { "type": "string" },
87
+ "current_version": { "type": "string" }
88
+ },
89
+ "additionalProperties": false
90
+ }
91
+ }
92
+ },
93
+ "additionalProperties": false
94
+ },
95
+ "finding_list": {
96
+ "type": "array",
97
+ "items": {
98
+ "type": "object",
99
+ "required": ["id", "rule_id", "title", "severity", "category", "evidence"],
100
+ "properties": {
101
+ "id": { "type": "string" },
102
+ "rule_id": { "type": "string" },
103
+ "title": { "type": "string" },
104
+ "severity": { "type": "string" },
105
+ "category": { "type": "string" },
106
+ "evidence": { "type": "object" }
107
+ },
108
+ "additionalProperties": false
109
+ }
110
+ }
111
+ },
112
+ "additionalProperties": false
113
+ }
@@ -0,0 +1,187 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://agentsecuritylens.dev/schemas/component-alternative-graph.schema.json",
4
+ "title": "AgentSecurityLens Component Alternative Graph",
5
+ "type": "object",
6
+ "required": [
7
+ "schema_version",
8
+ "graph_id",
9
+ "version",
10
+ "generated_at",
11
+ "policy",
12
+ "component_capabilities",
13
+ "edges",
14
+ "coverage_gaps"
15
+ ],
16
+ "properties": {
17
+ "schema_version": { "const": "0.1.0" },
18
+ "graph_id": { "type": "string", "minLength": 1 },
19
+ "version": { "type": "string", "minLength": 1 },
20
+ "generated_at": { "type": "string", "format": "date-time" },
21
+ "policy": {
22
+ "type": "object",
23
+ "required": ["agent_facing_relationships", "minimum_confidence", "minimum_safety_delta"],
24
+ "properties": {
25
+ "agent_facing_relationships": {
26
+ "type": "array",
27
+ "items": { "enum": ["verified_alternative", "conditional_alternative"] }
28
+ },
29
+ "minimum_confidence": { "type": "number", "minimum": 0, "maximum": 1 },
30
+ "minimum_safety_delta": { "type": "integer" }
31
+ },
32
+ "additionalProperties": false
33
+ },
34
+ "component_capabilities": {
35
+ "type": "array",
36
+ "items": {
37
+ "type": "object",
38
+ "required": [
39
+ "component_id",
40
+ "component_type",
41
+ "primary_capability",
42
+ "capabilities",
43
+ "constraints",
44
+ "evidence"
45
+ ],
46
+ "properties": {
47
+ "component_id": { "type": "string", "minLength": 1 },
48
+ "component_type": { "enum": ["mcp", "skill", "agent-framework"] },
49
+ "primary_capability": { "type": "string", "minLength": 1 },
50
+ "capabilities": {
51
+ "type": "array",
52
+ "minItems": 1,
53
+ "items": { "type": "string", "minLength": 1 },
54
+ "uniqueItems": true
55
+ },
56
+ "constraints": {
57
+ "type": "array",
58
+ "items": { "type": "string", "minLength": 1 },
59
+ "uniqueItems": true
60
+ },
61
+ "evidence": {
62
+ "type": "array",
63
+ "minItems": 1,
64
+ "items": { "$ref": "#/$defs/evidence" }
65
+ }
66
+ },
67
+ "additionalProperties": false
68
+ }
69
+ },
70
+ "edges": {
71
+ "type": "array",
72
+ "items": {
73
+ "type": "object",
74
+ "required": [
75
+ "id",
76
+ "source_component_id",
77
+ "target_component_id",
78
+ "relationship_type",
79
+ "status",
80
+ "confidence",
81
+ "safety_delta",
82
+ "shared_capabilities",
83
+ "unsupported_source_capabilities",
84
+ "conditions",
85
+ "migration",
86
+ "reason",
87
+ "evidence",
88
+ "reviewed_by",
89
+ "valid_from"
90
+ ],
91
+ "properties": {
92
+ "id": { "type": "string", "pattern": "^[a-z0-9][a-z0-9-]*$" },
93
+ "source_component_id": { "type": "string", "minLength": 1 },
94
+ "target_component_id": { "type": "string", "minLength": 1 },
95
+ "relationship_type": {
96
+ "enum": [
97
+ "verified_alternative",
98
+ "conditional_alternative",
99
+ "functional_peer",
100
+ "adjacent_capability"
101
+ ]
102
+ },
103
+ "status": { "enum": ["candidate", "active", "deprecated", "archived"] },
104
+ "confidence": { "type": "number", "minimum": 0, "maximum": 1 },
105
+ "safety_delta": { "type": "integer", "minimum": -100, "maximum": 100 },
106
+ "shared_capabilities": {
107
+ "type": "array",
108
+ "minItems": 1,
109
+ "items": { "type": "string", "minLength": 1 },
110
+ "uniqueItems": true
111
+ },
112
+ "unsupported_source_capabilities": {
113
+ "type": "array",
114
+ "items": { "type": "string", "minLength": 1 },
115
+ "uniqueItems": true
116
+ },
117
+ "conditions": {
118
+ "type": "array",
119
+ "items": { "type": "string", "minLength": 1 }
120
+ },
121
+ "migration": {
122
+ "type": "object",
123
+ "required": ["complexity", "user_confirmation_required", "steps"],
124
+ "properties": {
125
+ "complexity": { "enum": ["low", "medium", "high"] },
126
+ "user_confirmation_required": { "type": "boolean" },
127
+ "steps": {
128
+ "type": "array",
129
+ "minItems": 1,
130
+ "items": { "type": "string", "minLength": 1 }
131
+ }
132
+ },
133
+ "additionalProperties": false
134
+ },
135
+ "reason": { "type": "string", "minLength": 1 },
136
+ "evidence": {
137
+ "type": "array",
138
+ "minItems": 2,
139
+ "items": { "$ref": "#/$defs/evidence" }
140
+ },
141
+ "reviewed_by": { "type": "string", "minLength": 1 },
142
+ "valid_from": { "type": "string", "format": "date-time" },
143
+ "valid_until": { "type": ["string", "null"], "format": "date-time" }
144
+ },
145
+ "additionalProperties": false
146
+ }
147
+ },
148
+ "coverage_gaps": {
149
+ "type": "array",
150
+ "items": {
151
+ "type": "object",
152
+ "required": [
153
+ "component_id",
154
+ "primary_capability",
155
+ "status",
156
+ "reason",
157
+ "target_research_queries"
158
+ ],
159
+ "properties": {
160
+ "component_id": { "type": "string", "minLength": 1 },
161
+ "primary_capability": { "type": "string", "minLength": 1 },
162
+ "status": { "const": "research_required" },
163
+ "reason": { "type": "string", "minLength": 1 },
164
+ "target_research_queries": {
165
+ "type": "array",
166
+ "minItems": 1,
167
+ "items": { "type": "string", "minLength": 1 }
168
+ }
169
+ },
170
+ "additionalProperties": false
171
+ }
172
+ }
173
+ },
174
+ "$defs": {
175
+ "evidence": {
176
+ "type": "object",
177
+ "required": ["source_url", "claim", "accessed_at"],
178
+ "properties": {
179
+ "source_url": { "type": "string", "format": "uri" },
180
+ "claim": { "type": "string", "minLength": 1 },
181
+ "accessed_at": { "type": "string", "format": "date-time" }
182
+ },
183
+ "additionalProperties": false
184
+ }
185
+ },
186
+ "additionalProperties": false
187
+ }