@blamejs/exceptd-skills 0.12.11 → 0.12.15
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 +243 -0
- package/bin/exceptd.js +299 -48
- package/data/_indexes/_meta.json +49 -48
- package/data/_indexes/activity-feed.json +13 -5
- package/data/_indexes/catalog-summaries.json +51 -29
- package/data/_indexes/chains.json +3238 -3210
- package/data/_indexes/frequency.json +3 -0
- package/data/_indexes/jurisdiction-map.json +5 -3
- package/data/_indexes/section-offsets.json +712 -685
- package/data/_indexes/theater-fingerprints.json +1 -1
- package/data/_indexes/token-budget.json +355 -340
- package/data/atlas-ttps.json +144 -129
- package/data/attack-techniques.json +339 -0
- package/data/cve-catalog.json +515 -475
- package/data/cwe-catalog.json +1081 -759
- package/data/exploit-availability.json +63 -15
- package/data/framework-control-gaps.json +867 -843
- package/data/rfc-references.json +276 -276
- package/keys/EXPECTED_FINGERPRINT +1 -0
- package/lib/auto-discovery.js +21 -4
- package/lib/cross-ref-api.js +39 -6
- package/lib/cve-curation.js +505 -47
- package/lib/lint-skills.js +217 -15
- package/lib/playbook-runner.js +1224 -183
- package/lib/prefetch.js +121 -8
- package/lib/refresh-external.js +261 -95
- package/lib/refresh-network.js +208 -18
- package/lib/schemas/manifest.schema.json +16 -0
- package/lib/scoring.js +83 -7
- package/lib/sign.js +112 -3
- package/lib/source-ghsa.js +219 -37
- package/lib/source-osv.js +381 -122
- package/lib/validate-catalog-meta.js +64 -9
- package/lib/validate-cve-catalog.js +213 -7
- package/lib/validate-indexes.js +88 -37
- package/lib/validate-playbooks.js +469 -0
- package/lib/verify.js +313 -16
- package/manifest-snapshot.json +1 -1
- package/manifest-snapshot.sha256 +1 -0
- package/manifest.json +73 -73
- package/orchestrator/dispatcher.js +21 -1
- package/orchestrator/event-bus.js +52 -8
- package/orchestrator/index.js +279 -20
- package/orchestrator/pipeline.js +63 -2
- package/orchestrator/scanner.js +32 -10
- package/orchestrator/scheduler.js +196 -20
- package/package.json +3 -1
- package/sbom.cdx.json +9 -9
- package/scripts/check-manifest-snapshot.js +32 -0
- package/scripts/check-sbom-currency.js +65 -3
- package/scripts/check-test-coverage.js +142 -19
- package/scripts/predeploy.js +110 -40
- package/scripts/refresh-manifest-snapshot.js +55 -4
- package/scripts/validate-vendor-online.js +169 -0
- package/scripts/verify-shipped-tarball.js +106 -3
- package/skills/ai-attack-surface/skill.md +18 -10
- package/skills/ai-c2-detection/skill.md +7 -2
- package/skills/ai-risk-management/skill.md +5 -4
- package/skills/api-security/skill.md +3 -3
- package/skills/attack-surface-pentest/skill.md +5 -5
- package/skills/cloud-security/skill.md +1 -1
- package/skills/compliance-theater/skill.md +8 -8
- package/skills/container-runtime-security/skill.md +1 -1
- package/skills/dlp-gap-analysis/skill.md +5 -1
- package/skills/email-security-anti-phishing/skill.md +1 -1
- package/skills/exploit-scoring/skill.md +18 -18
- package/skills/framework-gap-analysis/skill.md +6 -6
- package/skills/global-grc/skill.md +3 -2
- package/skills/identity-assurance/skill.md +2 -2
- package/skills/incident-response-playbook/skill.md +4 -4
- package/skills/kernel-lpe-triage/skill.md +21 -2
- package/skills/mcp-agent-trust/skill.md +17 -10
- package/skills/mlops-security/skill.md +2 -1
- package/skills/ot-ics-security/skill.md +1 -1
- package/skills/policy-exception-gen/skill.md +3 -3
- package/skills/pqc-first/skill.md +1 -1
- package/skills/rag-pipeline-security/skill.md +7 -3
- package/skills/researcher/skill.md +20 -3
- package/skills/sector-energy/skill.md +1 -1
- package/skills/sector-federal-government/skill.md +1 -1
- package/skills/sector-financial/skill.md +3 -3
- package/skills/sector-healthcare/skill.md +2 -2
- package/skills/security-maturity-tiers/skill.md +7 -7
- package/skills/skill-update-loop/skill.md +19 -3
- package/skills/supply-chain-integrity/skill.md +1 -1
- package/skills/threat-model-currency/skill.md +11 -11
- package/skills/threat-modeling-methodology/skill.md +3 -3
- package/skills/webapp-security/skill.md +1 -1
- package/skills/zeroday-gap-learn/skill.md +51 -7
- package/vendor/blamejs/_PROVENANCE.json +4 -1
- package/vendor/blamejs/worker-pool.js +38 -0
package/manifest.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "exceptd-security",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.15",
|
|
4
4
|
"description": "AI security skills grounded in mid-2026 threat reality, not stale framework documentation",
|
|
5
5
|
"homepage": "https://exceptd.com",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -51,8 +51,8 @@
|
|
|
51
51
|
"RFC-7296"
|
|
52
52
|
],
|
|
53
53
|
"last_threat_review": "2026-05-01",
|
|
54
|
-
"signature": "
|
|
55
|
-
"signed_at": "2026-05-
|
|
54
|
+
"signature": "GedX81xfe2Y/oIVTEvakZUcSPFccqsDjBibE+KbiiHezAx2EvCS4AOjlx4TO7F0iuC47G/wvOc12kMYe9iHtDw==",
|
|
55
|
+
"signed_at": "2026-05-14T16:47:03.242Z",
|
|
56
56
|
"cwe_refs": [
|
|
57
57
|
"CWE-125",
|
|
58
58
|
"CWE-362",
|
|
@@ -115,8 +115,8 @@
|
|
|
115
115
|
"SOC2-CC6-logical-access"
|
|
116
116
|
],
|
|
117
117
|
"last_threat_review": "2026-05-01",
|
|
118
|
-
"signature": "
|
|
119
|
-
"signed_at": "2026-05-
|
|
118
|
+
"signature": "Rz5jS554rDryT6FPVZy0PwHMCYoJQQhhNDNI9rvOptjDbsnnKtZkpVXlKke5OKmLu5fHEBaNPg856qMIZFq+Ag==",
|
|
119
|
+
"signed_at": "2026-05-14T16:47:03.244Z",
|
|
120
120
|
"cwe_refs": [
|
|
121
121
|
"CWE-1039",
|
|
122
122
|
"CWE-1426",
|
|
@@ -178,8 +178,8 @@
|
|
|
178
178
|
"RFC-9700"
|
|
179
179
|
],
|
|
180
180
|
"last_threat_review": "2026-05-01",
|
|
181
|
-
"signature": "
|
|
182
|
-
"signed_at": "2026-05-
|
|
181
|
+
"signature": "goSMEVE6QbfcdqCEgq324TNy6rZ2mWwPA28gMPvojy8ZzGFng87hLdyvKhDMo4S3KTK1D6CaTBksAzZw4Go8Cg==",
|
|
182
|
+
"signed_at": "2026-05-14T16:47:03.245Z",
|
|
183
183
|
"cwe_refs": [
|
|
184
184
|
"CWE-22",
|
|
185
185
|
"CWE-345",
|
|
@@ -224,8 +224,8 @@
|
|
|
224
224
|
"attack_refs": [],
|
|
225
225
|
"framework_gaps": [],
|
|
226
226
|
"last_threat_review": "2026-05-01",
|
|
227
|
-
"signature": "
|
|
228
|
-
"signed_at": "2026-05-
|
|
227
|
+
"signature": "XFQO+fdOb388MLxMLoTqjOHhmV/PBOPKH0nZTp5NY4uzk5iUTo6G2T/IrgZGV7/CvsuvOvaXWP8+BDllXzOpDw==",
|
|
228
|
+
"signed_at": "2026-05-14T16:47:03.245Z"
|
|
229
229
|
},
|
|
230
230
|
{
|
|
231
231
|
"name": "compliance-theater",
|
|
@@ -255,8 +255,8 @@
|
|
|
255
255
|
"CMMC-2.0-Level-2"
|
|
256
256
|
],
|
|
257
257
|
"last_threat_review": "2026-05-01",
|
|
258
|
-
"signature": "
|
|
259
|
-
"signed_at": "2026-05-
|
|
258
|
+
"signature": "1UD9hHv44RWc1GSvN99pmxk26xaHLC74EbJ1ndn5Sptgd7w2rU9QznqCKf7Qc18uRyNEFhqW3jHvEs9c/XgrAw==",
|
|
259
|
+
"signed_at": "2026-05-14T16:47:03.245Z"
|
|
260
260
|
},
|
|
261
261
|
{
|
|
262
262
|
"name": "exploit-scoring",
|
|
@@ -284,8 +284,8 @@
|
|
|
284
284
|
"CIS-Controls-v8-Control7"
|
|
285
285
|
],
|
|
286
286
|
"last_threat_review": "2026-05-01",
|
|
287
|
-
"signature": "
|
|
288
|
-
"signed_at": "2026-05-
|
|
287
|
+
"signature": "4tt6UuIkq/Mi8zMhO5cydYlXyG7jKxF2MFBC34Q6Q5l3FHPhhqrL5HLOB4WFgVmq27wBbD6AgUu2czVnKa5MDQ==",
|
|
288
|
+
"signed_at": "2026-05-14T16:47:03.245Z"
|
|
289
289
|
},
|
|
290
290
|
{
|
|
291
291
|
"name": "rag-pipeline-security",
|
|
@@ -321,8 +321,8 @@
|
|
|
321
321
|
"OWASP-LLM-Top-10-2025-LLM08"
|
|
322
322
|
],
|
|
323
323
|
"last_threat_review": "2026-05-01",
|
|
324
|
-
"signature": "
|
|
325
|
-
"signed_at": "2026-05-
|
|
324
|
+
"signature": "4mstnPFMNhiorB7iEwqb7Jh+OCG79Mhqt2h/RwL5JbnAIPBi0Fcv0JBhQ5msEaHO4gNnpcBrdMfiDxLDwetZCw==",
|
|
325
|
+
"signed_at": "2026-05-14T16:47:03.246Z",
|
|
326
326
|
"cwe_refs": [
|
|
327
327
|
"CWE-1395",
|
|
328
328
|
"CWE-1426"
|
|
@@ -378,8 +378,8 @@
|
|
|
378
378
|
"RFC-9000"
|
|
379
379
|
],
|
|
380
380
|
"last_threat_review": "2026-05-01",
|
|
381
|
-
"signature": "
|
|
382
|
-
"signed_at": "2026-05-
|
|
381
|
+
"signature": "FjdIy9NqQpSSMhIbyv5WhnJKrVLhO98iBfQ0AHqXw6yqXdVoWucyr729Jwhelq40oAkiBzbXi9RoVo63DHJwDw==",
|
|
382
|
+
"signed_at": "2026-05-14T16:47:03.246Z",
|
|
383
383
|
"d3fend_refs": [
|
|
384
384
|
"D3-CA",
|
|
385
385
|
"D3-CSPP",
|
|
@@ -413,8 +413,8 @@
|
|
|
413
413
|
"attack_refs": [],
|
|
414
414
|
"framework_gaps": [],
|
|
415
415
|
"last_threat_review": "2026-05-01",
|
|
416
|
-
"signature": "
|
|
417
|
-
"signed_at": "2026-05-
|
|
416
|
+
"signature": "DxfXhSyoAGUo1emHh0uIIcg324ZreBYxmFdBDVAKOOuPmMlfN4RqNc/JGDSfVmMv5CjgYCUcSmkcYB0A5lk0Cg==",
|
|
417
|
+
"signed_at": "2026-05-14T16:47:03.246Z",
|
|
418
418
|
"cwe_refs": [
|
|
419
419
|
"CWE-1188"
|
|
420
420
|
]
|
|
@@ -441,8 +441,8 @@
|
|
|
441
441
|
"attack_refs": [],
|
|
442
442
|
"framework_gaps": [],
|
|
443
443
|
"last_threat_review": "2026-05-01",
|
|
444
|
-
"signature": "
|
|
445
|
-
"signed_at": "2026-05-
|
|
444
|
+
"signature": "xwlad/p5XlICc76KqrdWpEpBgwx1D87oM5qlccRQ5LKC/o0pr8vQ8LN3WLiiziBChplwNbruiIN6UETniZpjCg==",
|
|
445
|
+
"signed_at": "2026-05-14T16:47:03.247Z"
|
|
446
446
|
},
|
|
447
447
|
{
|
|
448
448
|
"name": "global-grc",
|
|
@@ -473,8 +473,8 @@
|
|
|
473
473
|
"attack_refs": [],
|
|
474
474
|
"framework_gaps": [],
|
|
475
475
|
"last_threat_review": "2026-05-01",
|
|
476
|
-
"signature": "
|
|
477
|
-
"signed_at": "2026-05-
|
|
476
|
+
"signature": "7yVjZkanFMKDQqXdX4B/7oLc2Rz72xHC1zscYd8F/+e5UAbR7ikK8Bn5EKZt3aBEOhHPAviSQNCMxpZD9U00CA==",
|
|
477
|
+
"signed_at": "2026-05-14T16:47:03.247Z"
|
|
478
478
|
},
|
|
479
479
|
{
|
|
480
480
|
"name": "zeroday-gap-learn",
|
|
@@ -500,8 +500,8 @@
|
|
|
500
500
|
"attack_refs": [],
|
|
501
501
|
"framework_gaps": [],
|
|
502
502
|
"last_threat_review": "2026-05-01",
|
|
503
|
-
"signature": "
|
|
504
|
-
"signed_at": "2026-05-
|
|
503
|
+
"signature": "pKv1b8JAj1ldwR2KGccvjUKqlor2KNXXzxkKypkv+4O8WbqY7v8fWlbFe1F36OJrL2xYJdnZL5mJzqjYVHLRCg==",
|
|
504
|
+
"signed_at": "2026-05-14T16:47:03.248Z"
|
|
505
505
|
},
|
|
506
506
|
{
|
|
507
507
|
"name": "pqc-first",
|
|
@@ -552,8 +552,8 @@
|
|
|
552
552
|
"CRQC timeline estimate changes"
|
|
553
553
|
],
|
|
554
554
|
"last_threat_review": "2026-05-01",
|
|
555
|
-
"signature": "
|
|
556
|
-
"signed_at": "2026-05-
|
|
555
|
+
"signature": "V+qn5FqUlETfsEjvvi6jZGuQdqLFtFejfgPA6KSYxSlBXBTbOBXP3BGk5S+ba9akIzgbKh1j9VGB1MqsIt56DA==",
|
|
556
|
+
"signed_at": "2026-05-14T16:47:03.248Z",
|
|
557
557
|
"cwe_refs": [
|
|
558
558
|
"CWE-327"
|
|
559
559
|
],
|
|
@@ -599,8 +599,8 @@
|
|
|
599
599
|
"Framework publication updates"
|
|
600
600
|
],
|
|
601
601
|
"last_threat_review": "2026-05-01",
|
|
602
|
-
"signature": "
|
|
603
|
-
"signed_at": "2026-05-
|
|
602
|
+
"signature": "UayHLLWXAkhnLPaPRsgDpAyE8FGk1tuG1/DYyhw84Uv4tfCKXMamsAhXHOyMIosQfsJq5ZHYVXZz0bYNpnlvDw==",
|
|
603
|
+
"signed_at": "2026-05-14T16:47:03.248Z"
|
|
604
604
|
},
|
|
605
605
|
{
|
|
606
606
|
"name": "security-maturity-tiers",
|
|
@@ -636,8 +636,8 @@
|
|
|
636
636
|
"PQC tooling maturity shifting overkill to practical"
|
|
637
637
|
],
|
|
638
638
|
"last_threat_review": "2026-05-01",
|
|
639
|
-
"signature": "
|
|
640
|
-
"signed_at": "2026-05-
|
|
639
|
+
"signature": "zjq6ACAHD46xvhvQJKlrCPh5xDCuBuIWBI+QJB8RxcudpC7p7I1pqv+BY8DZdsAgU4tquCU8KC+xlduMIk3/DQ==",
|
|
640
|
+
"signed_at": "2026-05-14T16:47:03.248Z",
|
|
641
641
|
"cwe_refs": [
|
|
642
642
|
"CWE-1188"
|
|
643
643
|
]
|
|
@@ -671,8 +671,8 @@
|
|
|
671
671
|
"attack_refs": [],
|
|
672
672
|
"framework_gaps": [],
|
|
673
673
|
"last_threat_review": "2026-05-11",
|
|
674
|
-
"signature": "
|
|
675
|
-
"signed_at": "2026-05-
|
|
674
|
+
"signature": "/lGgWehCMQUXjI6w4FUa+5wrbyRnct+txvVcXA+D2/ZEkoJKh+J/psO3j5HPf7Hpv+Y5SmkH71CoO+9qilyVDQ==",
|
|
675
|
+
"signed_at": "2026-05-14T16:47:03.249Z"
|
|
676
676
|
},
|
|
677
677
|
{
|
|
678
678
|
"name": "attack-surface-pentest",
|
|
@@ -742,8 +742,8 @@
|
|
|
742
742
|
"OWASP WSTG v5.x AI/MCP test cases (currently in working-group draft)",
|
|
743
743
|
"PTES revision incorporating AI-surface enumeration"
|
|
744
744
|
],
|
|
745
|
-
"signature": "
|
|
746
|
-
"signed_at": "2026-05-
|
|
745
|
+
"signature": "rh+/cr+wTcEmBwrGscBni/jXpxjjYP91pUKDFIGkahZpw+nghCM/3aLKFf5RFRnl3JKTyBRywIrYhUH1YuSlDw==",
|
|
746
|
+
"signed_at": "2026-05-14T16:47:03.249Z"
|
|
747
747
|
},
|
|
748
748
|
{
|
|
749
749
|
"name": "fuzz-testing-strategy",
|
|
@@ -803,7 +803,7 @@
|
|
|
803
803
|
"OSS-Fuzz-Gen / AI-assisted harness generation becoming the default expectation for OSS maintainers"
|
|
804
804
|
],
|
|
805
805
|
"signature": "+ELdD+1AY5DymBitH7wU65CS60NY1nDoLowJAFn7cE5Gr/5jy9BTkyxsm7PEXaSlXWMOkTf/HQ+uyzyxUVD/Bw==",
|
|
806
|
-
"signed_at": "2026-05-
|
|
806
|
+
"signed_at": "2026-05-14T16:47:03.249Z"
|
|
807
807
|
},
|
|
808
808
|
{
|
|
809
809
|
"name": "dlp-gap-analysis",
|
|
@@ -877,8 +877,8 @@
|
|
|
877
877
|
"MCP gateway / proxy standardisation (Anthropic enterprise MCP gateway, Portkey MCP) — tool-call argument inspection is the missing primary control",
|
|
878
878
|
"Quebec Law 25, India DPDPA, KSA PDPL enforcement actions naming AI-tool prompt data as in-scope personal information"
|
|
879
879
|
],
|
|
880
|
-
"signature": "
|
|
881
|
-
"signed_at": "2026-05-
|
|
880
|
+
"signature": "/BCBGUVjGs1RZzqXfElxBWB8UoD4+MY2G1YekdWsTDbMcHvt3NZJf0/JcqdYHOsEhFQ21NEz3w3+6tmQ8htKDw==",
|
|
881
|
+
"signed_at": "2026-05-14T16:47:03.249Z"
|
|
882
882
|
},
|
|
883
883
|
{
|
|
884
884
|
"name": "supply-chain-integrity",
|
|
@@ -954,8 +954,8 @@
|
|
|
954
954
|
"EU CRA (Regulation 2024/2847) — implementing acts for technical documentation and SBOM submission expected through 2027",
|
|
955
955
|
"OpenSSF model-signing — emerging Sigstore-based signing standard for ML model weights; track for production adoption"
|
|
956
956
|
],
|
|
957
|
-
"signature": "
|
|
958
|
-
"signed_at": "2026-05-
|
|
957
|
+
"signature": "mySOkGScsNPtEZcHg42EKcvUSBzADIB9mSlNe0L1yPllrB/83ypBj6cCERRw9ql+rtrNxapyc6Do+nCz7E5rDg==",
|
|
958
|
+
"signed_at": "2026-05-14T16:47:03.250Z"
|
|
959
959
|
},
|
|
960
960
|
{
|
|
961
961
|
"name": "defensive-countermeasure-mapping",
|
|
@@ -1012,7 +1012,7 @@
|
|
|
1012
1012
|
],
|
|
1013
1013
|
"last_threat_review": "2026-05-11",
|
|
1014
1014
|
"signature": "XZigwq8X/csfrdG10O6Q1V5q0zUqSQGd3QrjRKkZ4fkaodG4mZahYuIQqxc8rU9jjtGAm9LtBXYB+I5csqj9Bw==",
|
|
1015
|
-
"signed_at": "2026-05-
|
|
1015
|
+
"signed_at": "2026-05-14T16:47:03.250Z"
|
|
1016
1016
|
},
|
|
1017
1017
|
{
|
|
1018
1018
|
"name": "identity-assurance",
|
|
@@ -1078,8 +1078,8 @@
|
|
|
1078
1078
|
],
|
|
1079
1079
|
"d3fend_refs": [],
|
|
1080
1080
|
"last_threat_review": "2026-05-11",
|
|
1081
|
-
"signature": "
|
|
1082
|
-
"signed_at": "2026-05-
|
|
1081
|
+
"signature": "k0HrsZMBxiPWB1jl4dRwhv/R5IsqbZ+SLDv1Jx3/sRl51JyXjtm8vyogTNhSwsl5/IkaRakqIPJFRFRl5h/9CQ==",
|
|
1082
|
+
"signed_at": "2026-05-14T16:47:03.250Z"
|
|
1083
1083
|
},
|
|
1084
1084
|
{
|
|
1085
1085
|
"name": "ot-ics-security",
|
|
@@ -1134,8 +1134,8 @@
|
|
|
1134
1134
|
],
|
|
1135
1135
|
"d3fend_refs": [],
|
|
1136
1136
|
"last_threat_review": "2026-05-11",
|
|
1137
|
-
"signature": "
|
|
1138
|
-
"signed_at": "2026-05-
|
|
1137
|
+
"signature": "oHxjumOhk8y86WcwhAX8sSWIlPzt60KfTMn4DCJLeRrrQd5+i54fVADKAdZ3vOqfDN+DexO0uX4f5dLPtacRCQ==",
|
|
1138
|
+
"signed_at": "2026-05-14T16:47:03.251Z"
|
|
1139
1139
|
},
|
|
1140
1140
|
{
|
|
1141
1141
|
"name": "coordinated-vuln-disclosure",
|
|
@@ -1187,7 +1187,7 @@
|
|
|
1187
1187
|
"NYDFS 23 NYCRR 500 amendments potentially adding explicit CVD program requirements"
|
|
1188
1188
|
],
|
|
1189
1189
|
"signature": "UCiNjncvhkZItmLQA/Sm1/NCsOiLMwdCjfUw+067v4NIxhaMMaqRrAeD3KgMyEtov7m2Hq2kfwYSt5+DQsYDCQ==",
|
|
1190
|
-
"signed_at": "2026-05-
|
|
1190
|
+
"signed_at": "2026-05-14T16:47:03.251Z"
|
|
1191
1191
|
},
|
|
1192
1192
|
{
|
|
1193
1193
|
"name": "threat-modeling-methodology",
|
|
@@ -1236,8 +1236,8 @@
|
|
|
1236
1236
|
"LINDDUN-GO and LINDDUN-PRO updates incorporating LLM privacy threats",
|
|
1237
1237
|
"PASTA v2 updates incorporating AI/ML application threats"
|
|
1238
1238
|
],
|
|
1239
|
-
"signature": "
|
|
1240
|
-
"signed_at": "2026-05-
|
|
1239
|
+
"signature": "V9kl8Cf8UMjNFyn3D/fSyhWHLeXWlx3WV/jT9jdF9SrjfDqymimuTt2o91cZ2FOEJndAH9V0JGXB13Ohz8K4CQ==",
|
|
1240
|
+
"signed_at": "2026-05-14T16:47:03.251Z"
|
|
1241
1241
|
},
|
|
1242
1242
|
{
|
|
1243
1243
|
"name": "webapp-security",
|
|
@@ -1310,8 +1310,8 @@
|
|
|
1310
1310
|
],
|
|
1311
1311
|
"d3fend_refs": [],
|
|
1312
1312
|
"last_threat_review": "2026-05-11",
|
|
1313
|
-
"signature": "
|
|
1314
|
-
"signed_at": "2026-05-
|
|
1313
|
+
"signature": "csC9KRA3ExCSK77+UF6gj0OFPPZzOvuPxQtKEoaUZmLvn3V37My4IpbUjXAN2ZavTHqyFG9yQNfq3ELZeSJ7Cg==",
|
|
1314
|
+
"signed_at": "2026-05-14T16:47:03.252Z"
|
|
1315
1315
|
},
|
|
1316
1316
|
{
|
|
1317
1317
|
"name": "ai-risk-management",
|
|
@@ -1360,8 +1360,8 @@
|
|
|
1360
1360
|
],
|
|
1361
1361
|
"d3fend_refs": [],
|
|
1362
1362
|
"last_threat_review": "2026-05-11",
|
|
1363
|
-
"signature": "
|
|
1364
|
-
"signed_at": "2026-05-
|
|
1363
|
+
"signature": "P2D++lB5hea3oi2vl9mf8C7N+E7zASoqt1v4tjKxtaTeb+U0UARgMOaZsoK/sO9TT/PG/au14Rl4EFxv+Xi1BA==",
|
|
1364
|
+
"signed_at": "2026-05-14T16:47:03.252Z"
|
|
1365
1365
|
},
|
|
1366
1366
|
{
|
|
1367
1367
|
"name": "sector-healthcare",
|
|
@@ -1420,8 +1420,8 @@
|
|
|
1420
1420
|
],
|
|
1421
1421
|
"d3fend_refs": [],
|
|
1422
1422
|
"last_threat_review": "2026-05-11",
|
|
1423
|
-
"signature": "
|
|
1424
|
-
"signed_at": "2026-05-
|
|
1423
|
+
"signature": "BDuLcpTeFp2BNSf1q4rYOhYKNhlgd3o5RZ0Uw9xW5olyYxPbZSgqekQ+6Ggaec09s7y6sqR37GS0vuAMdbrdDQ==",
|
|
1424
|
+
"signed_at": "2026-05-14T16:47:03.252Z"
|
|
1425
1425
|
},
|
|
1426
1426
|
{
|
|
1427
1427
|
"name": "sector-financial",
|
|
@@ -1501,8 +1501,8 @@
|
|
|
1501
1501
|
"OSFI B-13 (Technology and Cyber Risk Management) post-2024 examination findings",
|
|
1502
1502
|
"TIBER-EU framework v2.0 alignment with DORA TLPT RTS (JC 2024/40); cross-recognition with CBEST and iCAST"
|
|
1503
1503
|
],
|
|
1504
|
-
"signature": "
|
|
1505
|
-
"signed_at": "2026-05-
|
|
1504
|
+
"signature": "4IUJePr6XbE1Ns+cPvEFAVgrwdHLImuxdPYiilurxM2SmJym1itRC1prFMcuT6Kh6e1clYXwlzflcKm/eikyDA==",
|
|
1505
|
+
"signed_at": "2026-05-14T16:47:03.252Z"
|
|
1506
1506
|
},
|
|
1507
1507
|
{
|
|
1508
1508
|
"name": "sector-federal-government",
|
|
@@ -1570,8 +1570,8 @@
|
|
|
1570
1570
|
"EU Cybersecurity Certification Scheme on Common Criteria (EUCC) operational — first certificates issued 2024; high-assurance level for government use cases ramping",
|
|
1571
1571
|
"Australia PSPF 2024 revision and ISM quarterly updates — track for Essential Eight Maturity Level requirements for federal entities"
|
|
1572
1572
|
],
|
|
1573
|
-
"signature": "
|
|
1574
|
-
"signed_at": "2026-05-
|
|
1573
|
+
"signature": "nMsyJ+rp5fM8/VjC7zsZyDjOC4hpxB+noT1VX7W0HBlq5t3SY56cwOGApwES/kBcCuf4qexKY376OxUr93zvCQ==",
|
|
1574
|
+
"signed_at": "2026-05-14T16:47:03.253Z"
|
|
1575
1575
|
},
|
|
1576
1576
|
{
|
|
1577
1577
|
"name": "sector-energy",
|
|
@@ -1635,8 +1635,8 @@
|
|
|
1635
1635
|
"MadIoT-class research on consumer-IoT-driven grid frequency manipulation moving from proof-of-concept to attributed campaigns",
|
|
1636
1636
|
"ICS-CERT advisory feed (https://www.cisa.gov/news-events/cybersecurity-advisories/ics-advisories) for vendor CVEs in Siemens, Rockwell, Schneider Electric, ABB, GE Vernova, Hitachi Energy, AVEVA / OSIsoft PI"
|
|
1637
1637
|
],
|
|
1638
|
-
"signature": "
|
|
1639
|
-
"signed_at": "2026-05-
|
|
1638
|
+
"signature": "L1moEqEGkBkqY/3ohJcfqrlJn40UurDCyb2MOP/IwTAeZD+QbVZ17/drdsydkJ6qSXPiyiE6u8HDfZsDS13NBQ==",
|
|
1639
|
+
"signed_at": "2026-05-14T16:47:03.253Z"
|
|
1640
1640
|
},
|
|
1641
1641
|
{
|
|
1642
1642
|
"name": "api-security",
|
|
@@ -1704,8 +1704,8 @@
|
|
|
1704
1704
|
],
|
|
1705
1705
|
"d3fend_refs": [],
|
|
1706
1706
|
"last_threat_review": "2026-05-11",
|
|
1707
|
-
"signature": "
|
|
1708
|
-
"signed_at": "2026-05-
|
|
1707
|
+
"signature": "ad1pHD4QQ8uXkhrzqLuWgnDpESOapzx3qGFchU9rxiX1aeLQkYKwpDzqIItFq82B5xjNsW7g5jXlF1sgK2HmCA==",
|
|
1708
|
+
"signed_at": "2026-05-14T16:47:03.253Z"
|
|
1709
1709
|
},
|
|
1710
1710
|
{
|
|
1711
1711
|
"name": "cloud-security",
|
|
@@ -1785,8 +1785,8 @@
|
|
|
1785
1785
|
"eBPF-based runtime detection coverage of confidential-computing enclaves (AWS Nitro Enclaves, Azure Confidential VMs, GCP Confidential Space) — partial visibility is a tracked detection gap",
|
|
1786
1786
|
"CISA KEV additions for cloud-control-plane CVEs (IMDSv1 abuses, federation token mishandling, cross-tenant boundary failures); CISA Cybersecurity Advisories for cross-cloud advisories"
|
|
1787
1787
|
],
|
|
1788
|
-
"signature": "
|
|
1789
|
-
"signed_at": "2026-05-
|
|
1788
|
+
"signature": "UEn0305KAEqIfYOdzadLBdPG/PJ+3sJ/8ubvPFNcXfqXp2uOWTfqGUqY65PApA992VEEa1RBQt5R7Nyhd/OjDQ==",
|
|
1789
|
+
"signed_at": "2026-05-14T16:47:03.254Z"
|
|
1790
1790
|
},
|
|
1791
1791
|
{
|
|
1792
1792
|
"name": "container-runtime-security",
|
|
@@ -1847,8 +1847,8 @@
|
|
|
1847
1847
|
],
|
|
1848
1848
|
"d3fend_refs": [],
|
|
1849
1849
|
"last_threat_review": "2026-05-11",
|
|
1850
|
-
"signature": "/
|
|
1851
|
-
"signed_at": "2026-05-
|
|
1850
|
+
"signature": "4easZDYn25XK4E9MRnwnZohG3xdYMmOLlPznNVmr1ykNfB+343+ooj+R0quG8uEV/IqbTQpR1ink35K6jCghCg==",
|
|
1851
|
+
"signed_at": "2026-05-14T16:47:03.254Z"
|
|
1852
1852
|
},
|
|
1853
1853
|
{
|
|
1854
1854
|
"name": "mlops-security",
|
|
@@ -1918,8 +1918,8 @@
|
|
|
1918
1918
|
"EU AI Act high-risk technical-file implementing acts (2026-2027) — operational requirements for Article 10 / 13 / 15 documentation may pin ML-BOM or model-signing",
|
|
1919
1919
|
"MITRE ATLAS v5.2 — track AML.T0010 sub-technique expansion and any new MLOps-pipeline-specific TTPs"
|
|
1920
1920
|
],
|
|
1921
|
-
"signature": "
|
|
1922
|
-
"signed_at": "2026-05-
|
|
1921
|
+
"signature": "chbPWzjfx92OjEAwMIm+J4GObxy8uwTahNBvbhMfYL7vTAJe/lf2BaW8wUpchpMIwYL0985A/+WykH8zmk/DBA==",
|
|
1922
|
+
"signed_at": "2026-05-14T16:47:03.255Z"
|
|
1923
1923
|
},
|
|
1924
1924
|
{
|
|
1925
1925
|
"name": "incident-response-playbook",
|
|
@@ -1980,8 +1980,8 @@
|
|
|
1980
1980
|
"IL INCD Incident Response Process v4 (slated for 2026-2027) consolidating AI-incident sub-class",
|
|
1981
1981
|
"NYDFS 23 NYCRR 500.17 amendments tightening ransom-payment 24h disclosure operationalization"
|
|
1982
1982
|
],
|
|
1983
|
-
"signature": "
|
|
1984
|
-
"signed_at": "2026-05-
|
|
1983
|
+
"signature": "3V7kvM5cxXdCBoMnjvOoTvT3zD+/yZEBHYgiunYQe8tBm+vVnS4jCz1Nzv/ymePIfbYDo/PlzKeGTWStSsGiAg==",
|
|
1984
|
+
"signed_at": "2026-05-14T16:47:03.255Z"
|
|
1985
1985
|
},
|
|
1986
1986
|
{
|
|
1987
1987
|
"name": "email-security-anti-phishing",
|
|
@@ -2033,8 +2033,8 @@
|
|
|
2033
2033
|
"cwe_refs": [],
|
|
2034
2034
|
"d3fend_refs": [],
|
|
2035
2035
|
"last_threat_review": "2026-05-11",
|
|
2036
|
-
"signature": "
|
|
2037
|
-
"signed_at": "2026-05-
|
|
2036
|
+
"signature": "RiCryJEd66T2NNcSo/mZTd3sGWDycE3C37guLJanLdVL5co35DrPFmIl8qy3ZM/y+Wzg5vpny8VKgr1//1/bCA==",
|
|
2037
|
+
"signed_at": "2026-05-14T16:47:03.255Z"
|
|
2038
2038
|
},
|
|
2039
2039
|
{
|
|
2040
2040
|
"name": "age-gates-child-safety",
|
|
@@ -2102,7 +2102,7 @@
|
|
|
2102
2102
|
"US state adult-site age-verification laws — 19+ states by mid-2026 (TX HB 18 upheld by SCOTUS June 2025 in Free Speech Coalition v. Paxton); track ongoing challenges in remaining states"
|
|
2103
2103
|
],
|
|
2104
2104
|
"signature": "MMWvg3lIf5ygm31zyf1E43t3W9MfRbMBBPrqlj1wOa8AxVJL8LICnAXfmyJ/TNJXwpF+rfZeDdoxXkql8wmtBA==",
|
|
2105
|
-
"signed_at": "2026-05-
|
|
2105
|
+
"signed_at": "2026-05-14T16:47:03.256Z"
|
|
2106
2106
|
}
|
|
2107
2107
|
]
|
|
2108
2108
|
}
|
|
@@ -20,6 +20,14 @@ const SKILLS_DIR = process.env.EXCEPTD_SKILLS_DIR || path.join(__dirname, '..',
|
|
|
20
20
|
* @returns {{ plan: object[], unmatched: object[], summary: object }}
|
|
21
21
|
*/
|
|
22
22
|
function dispatch(findings) {
|
|
23
|
+
// Type-check up front. A string argument would iterate character-by-
|
|
24
|
+
// character (since `for...of` on a string yields code points), producing
|
|
25
|
+
// nonsense "findings" with no domain/signal. Refuse loudly rather than
|
|
26
|
+
// silently process garbage; downstream consumers depend on plan entries
|
|
27
|
+
// being shaped by real findings.
|
|
28
|
+
if (!Array.isArray(findings)) {
|
|
29
|
+
throw new TypeError('dispatch: findings must be an array');
|
|
30
|
+
}
|
|
23
31
|
const manifest = loadManifest();
|
|
24
32
|
const plan = [];
|
|
25
33
|
const unmatched = [];
|
|
@@ -85,10 +93,22 @@ function dispatch(findings) {
|
|
|
85
93
|
*/
|
|
86
94
|
function routeQuery(query) {
|
|
87
95
|
const manifest = loadManifest();
|
|
88
|
-
|
|
96
|
+
if (typeof query !== 'string') return [];
|
|
97
|
+
const q = query.trim().toLowerCase();
|
|
98
|
+
// Reject empty + very short queries. The legacy substring match treats
|
|
99
|
+
// any trigger string as containing the empty string, so a bare empty
|
|
100
|
+
// query matched every skill — useless and misleading for callers.
|
|
101
|
+
// Short queries (1-2 chars) only match when they are an explicit
|
|
102
|
+
// prefix of a trigger; that prevents single letters from matching
|
|
103
|
+
// every trigger that contains them (e.g. "a" would match anything).
|
|
104
|
+
if (q.length === 0) return [];
|
|
89
105
|
|
|
90
106
|
return manifest.skills.filter(skill => {
|
|
91
107
|
const triggers = skill.triggers || [];
|
|
108
|
+
if (q.length < 3) {
|
|
109
|
+
// Trigger-prefix match only for short queries.
|
|
110
|
+
return triggers.some(t => t.toLowerCase().startsWith(q));
|
|
111
|
+
}
|
|
92
112
|
return triggers.some(t => q.includes(t.toLowerCase()) || t.toLowerCase().includes(q));
|
|
93
113
|
});
|
|
94
114
|
}
|
|
@@ -3,14 +3,36 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* Event bus for trigger-driven skill updates.
|
|
5
5
|
*
|
|
6
|
-
* Events are typed and carry structured payloads. Handlers are registered per
|
|
7
|
-
* This is
|
|
8
|
-
*
|
|
9
|
-
*
|
|
6
|
+
* Events are typed and carry structured payloads. Handlers are registered per
|
|
7
|
+
* event type. This bus is in-process only; the event log is held in a bounded
|
|
8
|
+
* ring buffer in memory and is NOT persisted across process restarts. For
|
|
9
|
+
* production deployments where event history must survive restarts, swap the
|
|
10
|
+
* internal emitter for a durable queue (Redis Streams, SQS, NATS JetStream,
|
|
11
|
+
* etc.) without changing the event schema.
|
|
12
|
+
*
|
|
13
|
+
* Bounded log policy:
|
|
14
|
+
* - The in-memory log is capped at EVENT_LOG_MAX_SIZE entries to prevent
|
|
15
|
+
* unbounded memory growth on long-running `watch` processes.
|
|
16
|
+
* - Default cap is 1000 entries; override at process start via the
|
|
17
|
+
* EXCEPTD_EVENT_LOG_MAX_SIZE env var (positive integer).
|
|
18
|
+
* - When the cap is reached, the oldest entry is shifted off on each new
|
|
19
|
+
* emit (FIFO ring buffer semantics).
|
|
10
20
|
*/
|
|
11
21
|
|
|
12
22
|
const { EventEmitter } = require('events');
|
|
13
23
|
|
|
24
|
+
const DEFAULT_EVENT_LOG_MAX_SIZE = 1000;
|
|
25
|
+
|
|
26
|
+
function _resolveLogMaxSize() {
|
|
27
|
+
const raw = process.env.EXCEPTD_EVENT_LOG_MAX_SIZE;
|
|
28
|
+
if (raw === undefined || raw === null || raw === '') return DEFAULT_EVENT_LOG_MAX_SIZE;
|
|
29
|
+
const n = Number(raw);
|
|
30
|
+
if (!Number.isFinite(n) || !Number.isInteger(n) || n <= 0) return DEFAULT_EVENT_LOG_MAX_SIZE;
|
|
31
|
+
return n;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const EVENT_LOG_MAX_SIZE = _resolveLogMaxSize();
|
|
35
|
+
|
|
14
36
|
const EVENT_TYPES = {
|
|
15
37
|
CISA_KEV_ADDED: 'cisa.kev.added',
|
|
16
38
|
ATLAS_VERSION_RELEASED: 'atlas.version.released',
|
|
@@ -20,7 +42,8 @@ const EVENT_TYPES = {
|
|
|
20
42
|
PQC_STANDARD_UPDATE: 'pqc.standard.update',
|
|
21
43
|
EXPLOIT_STATUS_CHANGE: 'exploit.status.change',
|
|
22
44
|
NEW_ATTACK_CLASS: 'attack_class.new',
|
|
23
|
-
SKILL_CURRENCY_LOW: 'skill.currency.low'
|
|
45
|
+
SKILL_CURRENCY_LOW: 'skill.currency.low',
|
|
46
|
+
SKILL_CURRENCY_LOW_AGGREGATE: 'skill.currency.low.aggregate'
|
|
24
47
|
};
|
|
25
48
|
|
|
26
49
|
// Maps event types to the skills they should trigger for review
|
|
@@ -33,13 +56,18 @@ const EVENT_SKILL_MAP = {
|
|
|
33
56
|
[EVENT_TYPES.PQC_STANDARD_UPDATE]: ['pqc-first', 'framework-gap-analysis'],
|
|
34
57
|
[EVENT_TYPES.EXPLOIT_STATUS_CHANGE]: ['exploit-scoring', 'kernel-lpe-triage', 'compliance-theater'],
|
|
35
58
|
[EVENT_TYPES.NEW_ATTACK_CLASS]: ['threat-model-currency', 'ai-attack-surface', 'skill-update-loop'],
|
|
36
|
-
[EVENT_TYPES.SKILL_CURRENCY_LOW]: ['skill-update-loop']
|
|
59
|
+
[EVENT_TYPES.SKILL_CURRENCY_LOW]: ['skill-update-loop'],
|
|
60
|
+
[EVENT_TYPES.SKILL_CURRENCY_LOW_AGGREGATE]: ['skill-update-loop']
|
|
37
61
|
};
|
|
38
62
|
|
|
39
63
|
class ExceptdEventBus extends EventEmitter {
|
|
40
|
-
constructor() {
|
|
64
|
+
constructor(opts) {
|
|
41
65
|
super();
|
|
66
|
+
const cap = opts && Number.isInteger(opts.maxLogSize) && opts.maxLogSize > 0
|
|
67
|
+
? opts.maxLogSize
|
|
68
|
+
: EVENT_LOG_MAX_SIZE;
|
|
42
69
|
this.eventLog = [];
|
|
70
|
+
this.maxLogSize = cap;
|
|
43
71
|
}
|
|
44
72
|
|
|
45
73
|
/**
|
|
@@ -58,6 +86,12 @@ class ExceptdEventBus extends EventEmitter {
|
|
|
58
86
|
};
|
|
59
87
|
|
|
60
88
|
this.eventLog.push(event);
|
|
89
|
+
// Bounded ring buffer — shift the oldest entry off when over cap. Loop
|
|
90
|
+
// rather than `if` so a runtime mutation of maxLogSize (or a burst that
|
|
91
|
+
// exceeds the cap in a single tick) still leaves the buffer at-cap.
|
|
92
|
+
while (this.eventLog.length > this.maxLogSize) {
|
|
93
|
+
this.eventLog.shift();
|
|
94
|
+
}
|
|
61
95
|
super.emit(eventType, event);
|
|
62
96
|
super.emit('*', event);
|
|
63
97
|
return event;
|
|
@@ -83,6 +117,16 @@ class ExceptdEventBus extends EventEmitter {
|
|
|
83
117
|
return this.on('*', handler);
|
|
84
118
|
}
|
|
85
119
|
|
|
120
|
+
/**
|
|
121
|
+
* Detach a handler previously registered via onAny().
|
|
122
|
+
*
|
|
123
|
+
* @param {function} handler
|
|
124
|
+
*/
|
|
125
|
+
offAny(handler) {
|
|
126
|
+
this.removeListener('*', handler);
|
|
127
|
+
return this;
|
|
128
|
+
}
|
|
129
|
+
|
|
86
130
|
/**
|
|
87
131
|
* Get all events that affected a specific skill.
|
|
88
132
|
*
|
|
@@ -143,4 +187,4 @@ class ExceptdEventBus extends EventEmitter {
|
|
|
143
187
|
|
|
144
188
|
const bus = new ExceptdEventBus();
|
|
145
189
|
|
|
146
|
-
module.exports = { bus, EVENT_TYPES, EVENT_SKILL_MAP };
|
|
190
|
+
module.exports = { bus, EVENT_TYPES, EVENT_SKILL_MAP, ExceptdEventBus, EVENT_LOG_MAX_SIZE, DEFAULT_EVENT_LOG_MAX_SIZE };
|