@blamejs/exceptd-skills 0.9.5 → 0.10.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.
@@ -0,0 +1,657 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://exceptd.com/schemas/playbook.schema.json",
4
+ "title": "exceptd investigation playbook",
5
+ "description": "A seven-phase investigation protocol. exceptd owns govern/direct/analyze/validate/close (knowledge + GRC layer); the host AI owns look/detect (execution). Each directive walks the agent through one focused investigation while keeping the GRC loop closed.",
6
+ "type": "object",
7
+ "required": ["_meta", "domain", "phases", "directives"],
8
+ "additionalProperties": false,
9
+ "properties": {
10
+
11
+ "_meta": {
12
+ "type": "object",
13
+ "required": ["id", "version", "last_threat_review", "threat_currency_score", "changelog", "owner", "air_gap_mode"],
14
+ "additionalProperties": false,
15
+ "properties": {
16
+ "id": { "type": "string", "pattern": "^[a-z0-9-]+$", "description": "Unique playbook id, kebab-case, matches filename." },
17
+ "version": { "type": "string", "pattern": "^\\d+\\.\\d+\\.\\d+$", "description": "Semver, independent of package version." },
18
+ "last_threat_review": { "type": "string", "format": "date", "description": "ISO 8601 date the threat model was last validated against current attacker behavior." },
19
+ "threat_currency_score": { "type": "number", "minimum": 0, "maximum": 100, "description": "Currency 0-100. Below 70 warns; below 50 blocks execution unless --force-stale is set." },
20
+ "changelog": {
21
+ "type": "array",
22
+ "minItems": 1,
23
+ "items": {
24
+ "type": "object",
25
+ "required": ["version", "date", "summary"],
26
+ "additionalProperties": false,
27
+ "properties": {
28
+ "version": { "type": "string" },
29
+ "date": { "type": "string", "format": "date" },
30
+ "summary": { "type": "string" },
31
+ "cves_added": { "type": "array", "items": { "type": "string" } },
32
+ "cves_removed": { "type": "array", "items": { "type": "string" } },
33
+ "framework_gaps_updated": { "type": "array", "items": { "type": "string" } }
34
+ }
35
+ }
36
+ },
37
+ "owner": { "type": "string", "description": "GitHub handle or team responsible for currency." },
38
+ "air_gap_mode": { "type": "boolean", "description": "When true, all artifact collection and lookups use offline fallbacks. No network." },
39
+ "scope": {
40
+ "type": "string",
41
+ "description": "Primary investigation scope. Drives CLI auto-detect + --scope filtering. system = host/kernel/packages/sysctl; code = repo walk / lockfiles / IaC; service = network APIs / MCP / AI providers; cross-cutting = pure-analyze correlation layer.",
42
+ "enum": ["system", "code", "service", "cross-cutting"]
43
+ },
44
+ "preconditions": {
45
+ "type": "array",
46
+ "description": "Must hold before the playbook runs.",
47
+ "items": {
48
+ "type": "object",
49
+ "required": ["id", "description", "check", "on_fail"],
50
+ "additionalProperties": false,
51
+ "properties": {
52
+ "id": { "type": "string" },
53
+ "description": { "type": "string" },
54
+ "check": { "type": "string", "examples": ["kernel_version >= 5.4", "siem_accessible == true", "agent_has_filesystem_read == true"] },
55
+ "on_fail": { "type": "string", "enum": ["halt", "warn", "skip_phase"] }
56
+ }
57
+ }
58
+ },
59
+ "mutex": { "type": "array", "items": { "type": "string" }, "description": "Playbook IDs that must not run concurrently with this one." },
60
+ "feeds_into": {
61
+ "type": "array",
62
+ "items": {
63
+ "type": "object",
64
+ "required": ["playbook_id", "condition"],
65
+ "additionalProperties": false,
66
+ "properties": {
67
+ "playbook_id": { "type": "string" },
68
+ "condition": { "type": "string", "examples": ["finding.severity == 'critical'", "theater_score < 60", "always"] }
69
+ }
70
+ }
71
+ }
72
+ }
73
+ },
74
+
75
+ "domain": {
76
+ "type": "object",
77
+ "required": ["name", "attack_class", "atlas_refs", "attack_refs", "cve_refs", "frameworks_in_scope"],
78
+ "additionalProperties": false,
79
+ "properties": {
80
+ "name": { "type": "string" },
81
+ "attack_class": {
82
+ "type": "string",
83
+ "description": "Attack class — every value backed by a shipped exceptd skill. Speculative classes without a skill are excluded to keep the enum truthful.",
84
+ "enum": [
85
+ "kernel-lpe", "container-escape",
86
+ "ai-attack-surface", "prompt-injection", "rag-exfiltration",
87
+ "ai-c2", "mlops-poisoning", "mcp-supply-chain",
88
+ "identity-abuse", "supply-chain",
89
+ "cloud-misconfig", "webapp-exploit", "api-abuse",
90
+ "email-phishing", "dlp-exfiltration",
91
+ "ot-ics", "pqc-exposure", "compliance-theater"
92
+ ]
93
+ },
94
+ "atlas_refs": { "type": "array", "items": { "type": "string", "pattern": "^AML\\.T\\d{4}(\\.\\d{3})?$" } },
95
+ "attack_refs": { "type": "array", "items": { "type": "string", "pattern": "^T\\d{4}(\\.\\d{3})?$" } },
96
+ "cve_refs": { "type": "array", "items": { "type": "string", "pattern": "^CVE-\\d{4}-\\d{4,}$" }, "description": "All CVEs must exist in data/cve-catalog.json." },
97
+ "cwe_refs": { "type": "array", "items": { "type": "string", "pattern": "^CWE-\\d+$" } },
98
+ "d3fend_refs": { "type": "array", "items": { "type": "string" } },
99
+ "frameworks_in_scope": {
100
+ "type": "array",
101
+ "items": {
102
+ "type": "string",
103
+ "enum": [
104
+ "nist-800-53", "nist-800-82", "nist-csf-2", "iso-27001-2022",
105
+ "soc2", "pci-dss-4", "nis2", "dora", "eu-ai-act", "eu-cra",
106
+ "uk-caf", "au-ism", "au-essential-8", "sg-mas-trm",
107
+ "jp-nisc", "in-cert", "ca-osfi-b10", "hipaa", "nerc-cip", "cmmc"
108
+ ]
109
+ }
110
+ }
111
+ }
112
+ },
113
+
114
+ "phases": {
115
+ "type": "object",
116
+ "required": ["govern", "direct", "look", "detect", "analyze", "validate", "close"],
117
+ "additionalProperties": false,
118
+ "properties": {
119
+
120
+ "govern": {
121
+ "type": "object",
122
+ "description": "Phase 1 — exceptd. Loads GRC context, jurisdiction obligations, theater fingerprints. Sets the compliance lens before investigation.",
123
+ "required": ["jurisdiction_obligations", "theater_fingerprints", "framework_context", "skill_preload"],
124
+ "additionalProperties": false,
125
+ "properties": {
126
+ "jurisdiction_obligations": {
127
+ "type": "array",
128
+ "items": {
129
+ "type": "object",
130
+ "required": ["jurisdiction", "regulation", "obligation", "window_hours", "clock_starts"],
131
+ "additionalProperties": false,
132
+ "properties": {
133
+ "jurisdiction": { "type": "string", "examples": ["EU", "UK", "AU", "US-CA", "SG", "JP"] },
134
+ "regulation": { "type": "string", "examples": ["NIS2", "GDPR Art.33", "APRA CPS 234", "DORA Art.19"] },
135
+ "obligation": { "type": "string", "examples": ["notify_regulator", "notify_affected_individuals", "patch_critical"] },
136
+ "window_hours": { "type": "integer" },
137
+ "clock_starts": { "type": "string", "enum": ["detect_confirmed", "analyze_complete", "validate_complete", "manual"] },
138
+ "evidence_required": { "type": "array", "items": { "type": "string" } }
139
+ }
140
+ }
141
+ },
142
+ "theater_fingerprints": {
143
+ "type": "array",
144
+ "description": "References data/_indexes/theater-fingerprints.json.",
145
+ "items": {
146
+ "type": "object",
147
+ "required": ["pattern_id", "claim", "fast_detection_test"],
148
+ "additionalProperties": false,
149
+ "properties": {
150
+ "pattern_id": { "type": "string" },
151
+ "claim": { "type": "string" },
152
+ "fast_detection_test": { "type": "string" },
153
+ "implicated_controls": { "type": "array", "items": { "type": "string" } }
154
+ }
155
+ }
156
+ },
157
+ "framework_context": {
158
+ "type": "object",
159
+ "required": ["gap_summary", "lag_score"],
160
+ "additionalProperties": false,
161
+ "properties": {
162
+ "gap_summary": { "type": "string", "description": "One-paragraph summary of coverage gaps for this domain, written for the host AI to load as context." },
163
+ "lag_score": { "type": "integer", "minimum": 0, "description": "Days the most relevant framework lags behind current attacker capability." },
164
+ "per_framework_gaps": {
165
+ "type": "array",
166
+ "items": {
167
+ "type": "object",
168
+ "required": ["framework", "control_id", "designed_for", "insufficient_because"],
169
+ "additionalProperties": false,
170
+ "properties": {
171
+ "framework": { "type": "string" },
172
+ "control_id": { "type": "string" },
173
+ "designed_for": { "type": "string" },
174
+ "insufficient_because": { "type": "string" }
175
+ }
176
+ }
177
+ }
178
+ }
179
+ },
180
+ "skill_preload": { "type": "array", "items": { "type": "string" }, "description": "Skills to load into context before investigation starts." }
181
+ }
182
+ },
183
+
184
+ "direct": {
185
+ "type": "object",
186
+ "description": "Phase 2 — exceptd. Scopes the investigation, sets RWEP thresholds, declares framework lag, sequences the skill chain.",
187
+ "required": ["threat_context", "rwep_threshold", "framework_lag_declaration", "skill_chain", "token_budget"],
188
+ "additionalProperties": false,
189
+ "properties": {
190
+ "threat_context": { "type": "string", "description": "What is happening in the wild right now. Cite current CVEs, TTPs, threat actor activity with dates. Not generic background." },
191
+ "rwep_threshold": {
192
+ "type": "object",
193
+ "required": ["escalate", "monitor", "close"],
194
+ "additionalProperties": false,
195
+ "properties": {
196
+ "escalate": { "type": "integer", "minimum": 0, "maximum": 100 },
197
+ "monitor": { "type": "integer", "minimum": 0, "maximum": 100 },
198
+ "close": { "type": "integer", "minimum": 0, "maximum": 100, "description": "RWEP below this after remediation allows closing." }
199
+ }
200
+ },
201
+ "framework_lag_declaration": { "type": "string", "description": "Explicit statement of which framework controls are structurally insufficient for this domain and why." },
202
+ "skill_chain": {
203
+ "type": "array",
204
+ "items": {
205
+ "type": "object",
206
+ "required": ["skill", "purpose"],
207
+ "additionalProperties": false,
208
+ "properties": {
209
+ "skill": { "type": "string" },
210
+ "purpose": { "type": "string" },
211
+ "skip_if": { "type": "string" },
212
+ "required": { "type": "boolean", "default": true }
213
+ }
214
+ }
215
+ },
216
+ "token_budget": {
217
+ "type": "object",
218
+ "required": ["estimated_total", "breakdown"],
219
+ "additionalProperties": false,
220
+ "properties": {
221
+ "estimated_total": { "type": "integer" },
222
+ "breakdown": {
223
+ "type": "object",
224
+ "properties": {
225
+ "govern": { "type": "integer" },
226
+ "direct": { "type": "integer" },
227
+ "look": { "type": "integer" },
228
+ "detect": { "type": "integer" },
229
+ "analyze": { "type": "integer" },
230
+ "validate": { "type": "integer" },
231
+ "close": { "type": "integer" }
232
+ }
233
+ }
234
+ }
235
+ }
236
+ }
237
+ },
238
+
239
+ "look": {
240
+ "type": "object",
241
+ "description": "Phase 3 — host AI. Collects typed artifacts from the environment.",
242
+ "required": ["artifacts", "collection_scope", "environment_assumptions", "fallback_if_unavailable"],
243
+ "additionalProperties": false,
244
+ "properties": {
245
+ "artifacts": {
246
+ "type": "array",
247
+ "items": {
248
+ "type": "object",
249
+ "required": ["id", "type", "source", "description", "required"],
250
+ "additionalProperties": false,
251
+ "properties": {
252
+ "id": { "type": "string" },
253
+ "type": {
254
+ "type": "string",
255
+ "enum": ["log", "file", "process_list", "network_capture", "api_response", "registry_key", "memory_dump", "config_file", "audit_trail", "model_output", "embedding_store", "mcp_manifest", "kernel_module_list", "syscall_trace"]
256
+ },
257
+ "source": { "type": "string" },
258
+ "description": { "type": "string" },
259
+ "required": { "type": "boolean" },
260
+ "air_gap_alternative": { "type": "string" }
261
+ }
262
+ }
263
+ },
264
+ "collection_scope": {
265
+ "type": "object",
266
+ "required": ["time_window", "asset_scope"],
267
+ "additionalProperties": false,
268
+ "properties": {
269
+ "time_window": { "type": "string", "examples": ["72h", "30d", "since_last_patch"] },
270
+ "asset_scope": { "type": "string", "examples": ["all_linux_hosts", "ai_inference_nodes", "mcp_server_fleet"] },
271
+ "depth": { "type": "string", "enum": ["surface", "standard", "deep"], "default": "standard" },
272
+ "sampling": { "type": "string" }
273
+ }
274
+ },
275
+ "environment_assumptions": {
276
+ "type": "array",
277
+ "items": {
278
+ "type": "object",
279
+ "required": ["assumption", "if_false"],
280
+ "additionalProperties": false,
281
+ "properties": {
282
+ "assumption": { "type": "string", "examples": ["linux_kernel >= 5.4", "ai_pipelines_present", "mcp_servers_deployed", "ephemeral_compute == true"] },
283
+ "if_false": { "type": "string" }
284
+ }
285
+ }
286
+ },
287
+ "fallback_if_unavailable": {
288
+ "type": "array",
289
+ "items": {
290
+ "type": "object",
291
+ "required": ["artifact_id", "fallback_action", "confidence_impact"],
292
+ "additionalProperties": false,
293
+ "properties": {
294
+ "artifact_id": { "type": "string" },
295
+ "fallback_action": { "type": "string", "examples": ["use_compensating_artifact", "mark_inconclusive", "escalate_to_human"] },
296
+ "confidence_impact": { "type": "string", "enum": ["none", "low", "medium", "high"] }
297
+ }
298
+ }
299
+ }
300
+ }
301
+ },
302
+
303
+ "detect": {
304
+ "type": "object",
305
+ "description": "Phase 4 — host AI. Evaluates collected artifacts against typed indicators.",
306
+ "required": ["indicators", "false_positive_profile", "minimum_signal"],
307
+ "additionalProperties": false,
308
+ "properties": {
309
+ "indicators": {
310
+ "type": "array",
311
+ "items": {
312
+ "type": "object",
313
+ "required": ["id", "type", "value", "confidence", "deterministic"],
314
+ "additionalProperties": false,
315
+ "properties": {
316
+ "id": { "type": "string" },
317
+ "type": {
318
+ "type": "string",
319
+ "enum": ["file_hash", "file_path", "network_pattern", "behavioral_signal", "log_pattern", "process_name", "syscall_sequence", "prompt_pattern", "embedding_anomaly", "api_call_sequence", "kernel_module", "memory_signature"]
320
+ },
321
+ "value": { "type": "string" },
322
+ "description": { "type": "string" },
323
+ "confidence": { "type": "string", "enum": ["low", "medium", "high", "deterministic"] },
324
+ "deterministic": { "type": "boolean", "description": "True if presence is definitive proof, not probabilistic." },
325
+ "atlas_ref": { "type": "string" },
326
+ "attack_ref": { "type": "string" }
327
+ }
328
+ }
329
+ },
330
+ "false_positive_profile": {
331
+ "type": "array",
332
+ "items": {
333
+ "type": "object",
334
+ "required": ["indicator_id", "benign_pattern", "distinguishing_test"],
335
+ "additionalProperties": false,
336
+ "properties": {
337
+ "indicator_id": { "type": "string" },
338
+ "benign_pattern": { "type": "string" },
339
+ "distinguishing_test": { "type": "string" }
340
+ }
341
+ }
342
+ },
343
+ "minimum_signal": {
344
+ "type": "object",
345
+ "required": ["detected", "inconclusive", "not_detected"],
346
+ "additionalProperties": false,
347
+ "properties": {
348
+ "detected": { "type": "string", "description": "Specific conditions constituting confirmed detection." },
349
+ "inconclusive": { "type": "string", "description": "Conditions meaning the investigation cannot confirm or deny. Triggers human escalation." },
350
+ "not_detected": { "type": "string", "description": "Conditions allowing closure as not detected with documented confidence." }
351
+ }
352
+ }
353
+ }
354
+ },
355
+
356
+ "analyze": {
357
+ "type": "object",
358
+ "description": "Phase 5 — exceptd. Scores findings, maps framework gaps, assesses blast radius, runs compliance theater check.",
359
+ "required": ["rwep_inputs", "blast_radius_model", "compliance_theater_check", "framework_gap_mapping", "escalation_criteria"],
360
+ "additionalProperties": false,
361
+ "properties": {
362
+ "rwep_inputs": {
363
+ "type": "array",
364
+ "items": {
365
+ "type": "object",
366
+ "required": ["signal_id", "rwep_factor", "weight"],
367
+ "additionalProperties": false,
368
+ "properties": {
369
+ "signal_id": { "type": "string" },
370
+ "rwep_factor": { "type": "string", "enum": ["cisa_kev", "public_poc", "ai_weaponization", "active_exploitation", "patch_available", "live_patch_available", "blast_radius"] },
371
+ "weight": { "type": "number", "description": "Must match lib/scoring.js formula." },
372
+ "notes": { "type": "string" }
373
+ }
374
+ }
375
+ },
376
+ "blast_radius_model": {
377
+ "type": "object",
378
+ "required": ["scope_question", "scoring_rubric"],
379
+ "additionalProperties": false,
380
+ "properties": {
381
+ "scope_question": { "type": "string" },
382
+ "scoring_rubric": {
383
+ "type": "array",
384
+ "items": {
385
+ "type": "object",
386
+ "required": ["condition", "blast_radius_score", "description"],
387
+ "additionalProperties": false,
388
+ "properties": {
389
+ "condition": { "type": "string" },
390
+ "blast_radius_score": { "type": "integer", "minimum": 1, "maximum": 5 },
391
+ "description": { "type": "string" }
392
+ }
393
+ }
394
+ }
395
+ }
396
+ },
397
+ "compliance_theater_check": {
398
+ "type": "object",
399
+ "required": ["claim", "audit_evidence", "reality_test", "theater_verdict_if_gap"],
400
+ "additionalProperties": false,
401
+ "properties": {
402
+ "claim": { "type": "string", "description": "The paper-compliance claim being tested." },
403
+ "audit_evidence": { "type": "string", "description": "What an auditor would accept as proof of compliance." },
404
+ "reality_test": { "type": "string", "description": "The specific test that distinguishes paper compliance from actual exposure." },
405
+ "theater_verdict_if_gap": { "type": "string", "description": "What to say in the finding when paper passes but reality fails." }
406
+ }
407
+ },
408
+ "framework_gap_mapping": {
409
+ "type": "array",
410
+ "items": {
411
+ "type": "object",
412
+ "required": ["finding_id", "framework", "claimed_control", "actual_gap"],
413
+ "additionalProperties": false,
414
+ "properties": {
415
+ "finding_id": { "type": "string" },
416
+ "framework": { "type": "string" },
417
+ "claimed_control": { "type": "string" },
418
+ "actual_gap": { "type": "string" },
419
+ "required_control": { "type": "string", "description": "What a real control would require to actually address this finding." }
420
+ }
421
+ }
422
+ },
423
+ "escalation_criteria": {
424
+ "type": "array",
425
+ "items": {
426
+ "type": "object",
427
+ "required": ["condition", "action"],
428
+ "additionalProperties": false,
429
+ "properties": {
430
+ "condition": { "type": "string", "examples": ["rwep >= 90 AND patch_available == false", "blast_radius_score >= 4"] },
431
+ "action": { "type": "string", "enum": ["raise_severity", "trigger_playbook", "page_on_call", "notify_legal"] },
432
+ "target_playbook": { "type": "string", "description": "If action is trigger_playbook, which one." }
433
+ }
434
+ }
435
+ }
436
+ }
437
+ },
438
+
439
+ "validate": {
440
+ "type": "object",
441
+ "description": "Phase 6 — exceptd. Picks remediation path, confirms it actually worked, records residual risk.",
442
+ "required": ["remediation_paths", "validation_tests", "residual_risk_statement", "evidence_requirements", "regression_trigger"],
443
+ "additionalProperties": false,
444
+ "properties": {
445
+ "remediation_paths": {
446
+ "type": "array",
447
+ "items": {
448
+ "type": "object",
449
+ "required": ["id", "description", "preconditions", "priority"],
450
+ "additionalProperties": false,
451
+ "properties": {
452
+ "id": { "type": "string" },
453
+ "description": { "type": "string" },
454
+ "preconditions": {
455
+ "type": "array",
456
+ "items": { "type": "string" },
457
+ "examples": [["live_patch_available == true"], ["reboot_window_within_4h == true"], ["compensating_control_deployed == true"]]
458
+ },
459
+ "priority": { "type": "integer", "minimum": 1, "description": "Lower number is preferred. 1 is the recommended path when its preconditions hold." },
460
+ "compensating_controls": { "type": "array", "items": { "type": "string" } },
461
+ "estimated_time_hours": { "type": "number" }
462
+ }
463
+ }
464
+ },
465
+ "validation_tests": {
466
+ "type": "array",
467
+ "description": "How to confirm remediation actually worked. Not just 'the patch was applied'.",
468
+ "items": {
469
+ "type": "object",
470
+ "required": ["id", "test", "expected_result", "test_type"],
471
+ "additionalProperties": false,
472
+ "properties": {
473
+ "id": { "type": "string" },
474
+ "test": { "type": "string", "description": "Specific test the host AI runs to verify the fix." },
475
+ "expected_result": { "type": "string" },
476
+ "test_type": { "type": "string", "enum": ["functional", "negative", "regression", "exploit_replay"] }
477
+ }
478
+ }
479
+ },
480
+ "residual_risk_statement": {
481
+ "type": "object",
482
+ "required": ["risk", "why_remains", "acceptance_level"],
483
+ "additionalProperties": false,
484
+ "properties": {
485
+ "risk": { "type": "string" },
486
+ "why_remains": { "type": "string" },
487
+ "acceptance_level": { "type": "string", "enum": ["operator", "manager", "ciso", "board"], "description": "Who must accept this residual risk." },
488
+ "compensating_controls_in_place": { "type": "array", "items": { "type": "string" } }
489
+ }
490
+ },
491
+ "evidence_requirements": {
492
+ "type": "array",
493
+ "description": "What an auditor would need to see to accept this finding as closed.",
494
+ "items": {
495
+ "type": "object",
496
+ "required": ["evidence_type", "description", "retention_period"],
497
+ "additionalProperties": false,
498
+ "properties": {
499
+ "evidence_type": { "type": "string", "enum": ["log_excerpt", "config_diff", "screenshot", "scan_report", "exploit_replay_negative", "attestation", "patch_record", "ticket_reference"] },
500
+ "description": { "type": "string" },
501
+ "retention_period": { "type": "string", "examples": ["1_year", "7_years", "audit_cycle"] },
502
+ "framework_satisfied": { "type": "array", "items": { "type": "string" } }
503
+ }
504
+ }
505
+ },
506
+ "regression_trigger": {
507
+ "type": "array",
508
+ "description": "Conditions under which this playbook should re-run automatically.",
509
+ "items": {
510
+ "type": "object",
511
+ "required": ["condition", "interval"],
512
+ "additionalProperties": false,
513
+ "properties": {
514
+ "condition": { "type": "string", "examples": ["new_cve_in_class == true", "kernel_upgrade == true", "monthly", "post_major_deploy"] },
515
+ "interval": { "type": "string", "examples": ["7d", "30d", "on_event"] }
516
+ }
517
+ }
518
+ }
519
+ }
520
+ },
521
+
522
+ "close": {
523
+ "type": "object",
524
+ "description": "Phase 7 — exceptd. Closes the GRC loop. Generates auditor evidence package, triggers learning loop, files policy exceptions, fires notification clocks, sets regression schedule.",
525
+ "required": ["evidence_package", "learning_loop", "notification_actions", "exception_generation", "regression_schedule"],
526
+ "additionalProperties": false,
527
+ "properties": {
528
+ "evidence_package": {
529
+ "type": "object",
530
+ "required": ["bundle_format", "contents", "destination"],
531
+ "additionalProperties": false,
532
+ "properties": {
533
+ "bundle_format": { "type": "string", "enum": ["json", "csaf-2.0", "stix-2.1", "markdown", "pdf"] },
534
+ "contents": {
535
+ "type": "array",
536
+ "items": { "type": "string" },
537
+ "description": "References to evidence_requirements collected in validate phase.",
538
+ "examples": [["all_validation_tests_passed", "patch_records", "exploit_replay_negative", "residual_risk_statement"]]
539
+ },
540
+ "destination": { "type": "string", "examples": ["s3://audit-evidence/", "grc_platform_api", "local_only"] },
541
+ "signed": { "type": "boolean", "default": true, "description": "Ed25519-sign the evidence bundle for tamper-evident audit trail." }
542
+ }
543
+ },
544
+ "learning_loop": {
545
+ "type": "object",
546
+ "description": "Run the zero-day learning loop. Writes back to data/zeroday-lessons.json.",
547
+ "required": ["enabled", "lesson_template"],
548
+ "additionalProperties": false,
549
+ "properties": {
550
+ "enabled": { "type": "boolean" },
551
+ "lesson_template": {
552
+ "type": "object",
553
+ "required": ["attack_vector", "control_gap", "framework_gap", "new_control_requirement"],
554
+ "additionalProperties": false,
555
+ "properties": {
556
+ "attack_vector": { "type": "string", "description": "Extracted from the finding." },
557
+ "control_gap": { "type": "string", "description": "Which control should have caught this and why it didn't." },
558
+ "framework_gap": { "type": "string", "description": "Which framework owns that control and where it falls short." },
559
+ "new_control_requirement": { "type": "string", "description": "What a real control would require. Feeds into framework-gap-analysis skill." }
560
+ }
561
+ },
562
+ "feeds_back_to_skills": { "type": "array", "items": { "type": "string" }, "description": "Skills whose context should be refreshed after this lesson is recorded." }
563
+ }
564
+ },
565
+ "notification_actions": {
566
+ "type": "array",
567
+ "description": "Jurisdiction-aware notification triggers. References govern.jurisdiction_obligations.",
568
+ "items": {
569
+ "type": "object",
570
+ "required": ["obligation_ref", "deadline", "recipient", "evidence_attached"],
571
+ "additionalProperties": false,
572
+ "properties": {
573
+ "obligation_ref": { "type": "string", "description": "Refers to a jurisdiction_obligations entry from govern phase." },
574
+ "deadline": { "type": "string", "description": "ISO 8601 datetime computed from clock_starts + window_hours." },
575
+ "recipient": { "type": "string", "examples": ["regulator_email", "internal_legal", "data_subjects"] },
576
+ "evidence_attached": { "type": "array", "items": { "type": "string" } },
577
+ "draft_notification": { "type": "string", "description": "Pre-drafted notification text the operator reviews before sending." }
578
+ }
579
+ }
580
+ },
581
+ "exception_generation": {
582
+ "type": "object",
583
+ "description": "If the finding cannot be remediated within compliance windows, generate a defensible policy exception via the policy-exception-gen skill.",
584
+ "required": ["trigger_condition", "exception_template"],
585
+ "additionalProperties": false,
586
+ "properties": {
587
+ "trigger_condition": { "type": "string", "examples": ["remediation_blocked == true", "vendor_patch_pending == true", "architectural_impossibility == true"] },
588
+ "exception_template": {
589
+ "type": "object",
590
+ "required": ["scope", "duration", "compensating_controls", "risk_acceptance_owner"],
591
+ "additionalProperties": false,
592
+ "properties": {
593
+ "scope": { "type": "string" },
594
+ "duration": { "type": "string", "examples": ["30d", "until_vendor_patch", "until_next_audit"] },
595
+ "compensating_controls": { "type": "array", "items": { "type": "string" } },
596
+ "risk_acceptance_owner": { "type": "string", "enum": ["operator", "manager", "ciso", "board"] },
597
+ "auditor_ready_language": { "type": "string", "description": "Pre-drafted exception text formatted for SOC 2 / ISO 27001 / framework-appropriate audit." }
598
+ }
599
+ }
600
+ }
601
+ },
602
+ "regression_schedule": {
603
+ "type": "object",
604
+ "required": ["next_run", "trigger"],
605
+ "additionalProperties": false,
606
+ "properties": {
607
+ "next_run": { "type": "string", "description": "ISO 8601 datetime computed from validate.regression_trigger." },
608
+ "trigger": { "type": "string", "examples": ["interval", "event", "both"] },
609
+ "notify_on_skip": { "type": "boolean", "default": true }
610
+ }
611
+ }
612
+ }
613
+ }
614
+ }
615
+ },
616
+
617
+ "directives": {
618
+ "type": "array",
619
+ "minItems": 1,
620
+ "description": "Concrete investigation directives. Each directive is one focused investigation through the seven phases. A playbook can have multiple directives (e.g. one per CVE in scope).",
621
+ "items": {
622
+ "type": "object",
623
+ "required": ["id", "title", "applies_to"],
624
+ "additionalProperties": false,
625
+ "properties": {
626
+ "id": { "type": "string", "pattern": "^[a-z0-9-]+$" },
627
+ "title": { "type": "string" },
628
+ "applies_to": {
629
+ "type": "object",
630
+ "description": "When this directive should run. Lets a single playbook handle multiple related conditions.",
631
+ "additionalProperties": false,
632
+ "properties": {
633
+ "cve": { "type": "string" },
634
+ "atlas_ttp": { "type": "string" },
635
+ "attack_technique": { "type": "string" },
636
+ "always": { "type": "boolean" }
637
+ }
638
+ },
639
+ "phase_overrides": {
640
+ "type": "object",
641
+ "description": "Directive-level overrides for any of the seven phases. Inherits from the playbook-level phases unless overridden.",
642
+ "additionalProperties": false,
643
+ "properties": {
644
+ "govern": { "type": "object" },
645
+ "direct": { "type": "object" },
646
+ "look": { "type": "object" },
647
+ "detect": { "type": "object" },
648
+ "analyze": { "type": "object" },
649
+ "validate": { "type": "object" },
650
+ "close": { "type": "object" }
651
+ }
652
+ }
653
+ }
654
+ }
655
+ }
656
+ }
657
+ }