@blamejs/exceptd-skills 0.14.28 → 0.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ARCHITECTURE.md +2 -2
- package/CHANGELOG.md +22 -0
- package/README.md +5 -1
- package/bin/exceptd.js +0 -147
- package/data/_indexes/_meta.json +45 -45
- package/data/_indexes/section-offsets.json +804 -795
- package/data/_indexes/summary-cards.json +3 -3
- package/data/_indexes/token-budget.json +506 -501
- package/data/cve-catalog.json +154 -7
- package/data/zeroday-lessons.json +1 -1
- package/lib/gap-detectors.js +8 -2
- package/lib/lint-skills.js +13 -2
- package/lib/playbook-runner.js +0 -2
- package/lib/validate-cve-catalog.js +35 -12
- package/manifest.json +84 -84
- package/orchestrator/index.js +49 -5
- package/package.json +2 -2
- package/sbom.cdx.json +119 -119
- package/scripts/check-catalog-gap-budget.js +5 -1
- package/scripts/check-test-coverage.js +9 -0
- package/scripts/predeploy.js +8 -4
- package/skills/age-gates-child-safety/skill.md +7 -7
- package/skills/ai-attack-surface/skill.md +1 -1
- package/skills/ai-c2-detection/skill.md +3 -3
- package/skills/ai-risk-management/skill.md +9 -9
- package/skills/api-security/skill.md +4 -4
- package/skills/cloud-security/skill.md +7 -7
- package/skills/compliance-theater/skill.md +4 -4
- package/skills/container-runtime-security/skill.md +6 -6
- package/skills/coordinated-vuln-disclosure/skill.md +12 -12
- package/skills/defensive-countermeasure-mapping/skill.md +14 -10
- package/skills/dlp-gap-analysis/skill.md +3 -3
- package/skills/email-security-anti-phishing/skill.md +6 -6
- package/skills/exploit-scoring/skill.md +2 -2
- package/skills/framework-gap-analysis/skill.md +6 -6
- package/skills/fuzz-testing-strategy/skill.md +1 -1
- package/skills/global-grc/skill.md +2 -2
- package/skills/identity-assurance/skill.md +5 -5
- package/skills/idp-incident-response/skill.md +5 -5
- package/skills/incident-response-playbook/skill.md +8 -8
- package/skills/kernel-lpe-triage/skill.md +4 -4
- package/skills/mcp-agent-trust/skill.md +3 -3
- package/skills/mlops-security/skill.md +5 -5
- package/skills/ot-ics-security/skill.md +7 -7
- package/skills/policy-exception-gen/skill.md +2 -2
- package/skills/pqc-first/skill.md +2 -2
- package/skills/rag-pipeline-security/skill.md +2 -2
- package/skills/ransomware-response/skill.md +9 -9
- package/skills/researcher/skill.md +11 -11
- package/skills/sector-energy/skill.md +6 -6
- package/skills/sector-federal-government/skill.md +2 -2
- package/skills/sector-financial/skill.md +4 -4
- package/skills/sector-healthcare/skill.md +6 -6
- package/skills/sector-telecom/skill.md +1 -1
- package/skills/security-maturity-tiers/skill.md +4 -4
- package/skills/skill-update-loop/skill.md +6 -6
- package/skills/supply-chain-integrity/skill.md +1 -1
- package/skills/threat-model-currency/skill.md +3 -3
- package/skills/threat-modeling-methodology/skill.md +9 -9
- package/skills/webapp-security/skill.md +7 -7
- package/skills/zeroday-gap-learn/skill.md +8 -8
package/data/cve-catalog.json
CHANGED
|
@@ -2279,7 +2279,30 @@
|
|
|
2279
2279
|
],
|
|
2280
2280
|
"last_updated": "2026-05-15",
|
|
2281
2281
|
"discovery_attribution_note": "Discovered by Rory McNamara of Snyk Security Labs as part of the four-vulnerability Leaky Vessels disclosure (CVE-2024-21626 + CVE-2024-23651/23652/23653) published January 2024. Named human researcher; no AI-tool credited. Source: https://labs.snyk.io/resources/leaky-vessels-docker-runc-container-breakout-vulnerabilities/.",
|
|
2282
|
-
"rwep_correction_note": "v0.12.30: canonicalized rwep_factors AND rwep_score to satisfy Shape B invariant. The prior stored rwep_score was internally inconsistent with its rwep_factors block; both now derived from canonical RWEP_WEIGHTS + operational fields. Delta from prior stored: +5 (75 -> 80)."
|
|
2282
|
+
"rwep_correction_note": "v0.12.30: canonicalized rwep_factors AND rwep_score to satisfy Shape B invariant. The prior stored rwep_score was internally inconsistent with its rwep_factors block; both now derived from canonical RWEP_WEIGHTS + operational fields. Delta from prior stored: +5 (75 -> 80).",
|
|
2283
|
+
"vendor_advisories": [
|
|
2284
|
+
{
|
|
2285
|
+
"vendor": "NVD",
|
|
2286
|
+
"advisory_id": "CVE-2024-21626",
|
|
2287
|
+
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-21626",
|
|
2288
|
+
"severity": "high",
|
|
2289
|
+
"published_date": "2024-01-31"
|
|
2290
|
+
},
|
|
2291
|
+
{
|
|
2292
|
+
"vendor": "Snyk",
|
|
2293
|
+
"advisory_id": null,
|
|
2294
|
+
"url": "https://snyk.io/blog/leaky-vessels-docker-runc-container-breakout-vulnerabilities/",
|
|
2295
|
+
"severity": "high",
|
|
2296
|
+
"published_date": "2024-01-31"
|
|
2297
|
+
},
|
|
2298
|
+
{
|
|
2299
|
+
"vendor": "CISA KEV",
|
|
2300
|
+
"advisory_id": "CVE-2024-21626",
|
|
2301
|
+
"url": "https://www.cisa.gov/known-exploited-vulnerabilities-catalog",
|
|
2302
|
+
"severity": "high",
|
|
2303
|
+
"published_date": "2024-04-08"
|
|
2304
|
+
}
|
|
2305
|
+
]
|
|
2283
2306
|
},
|
|
2284
2307
|
"CVE-2024-3094": {
|
|
2285
2308
|
"ai_assisted_weaponization": false,
|
|
@@ -2349,7 +2372,30 @@
|
|
|
2349
2372
|
],
|
|
2350
2373
|
"last_updated": "2026-05-15",
|
|
2351
2374
|
"discovery_attribution_note": "Discovered by Andres Freund (Microsoft engineer, PostgreSQL developer) on 2024-03-28 via a 0.5-second SSH-login latency regression traced to liblzma symbol resolution; reported to oss-security. Named human researcher; no AI tooling involved. Source: https://en.wikipedia.org/wiki/XZ_Utils_backdoor.",
|
|
2352
|
-
"rwep_correction_note": "v0.12.30: canonicalized rwep_factors to satisfy Shape B invariant (Σ factors === rwep_score). Prior values used non-canonical weights and/or blast_radius > 30 (over-cap). Stored rwep_score unchanged; factor block now reproducible from canonical RWEP_WEIGHTS + operational fields."
|
|
2375
|
+
"rwep_correction_note": "v0.12.30: canonicalized rwep_factors to satisfy Shape B invariant (Σ factors === rwep_score). Prior values used non-canonical weights and/or blast_radius > 30 (over-cap). Stored rwep_score unchanged; factor block now reproducible from canonical RWEP_WEIGHTS + operational fields.",
|
|
2376
|
+
"vendor_advisories": [
|
|
2377
|
+
{
|
|
2378
|
+
"vendor": "NVD",
|
|
2379
|
+
"advisory_id": "CVE-2024-3094",
|
|
2380
|
+
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-3094",
|
|
2381
|
+
"severity": "critical",
|
|
2382
|
+
"published_date": "2024-03-29"
|
|
2383
|
+
},
|
|
2384
|
+
{
|
|
2385
|
+
"vendor": "openwall oss-security",
|
|
2386
|
+
"advisory_id": null,
|
|
2387
|
+
"url": "https://www.openwall.com/lists/oss-security/2024/03/29/4",
|
|
2388
|
+
"severity": "critical",
|
|
2389
|
+
"published_date": "2024-03-29"
|
|
2390
|
+
},
|
|
2391
|
+
{
|
|
2392
|
+
"vendor": "CISA KEV",
|
|
2393
|
+
"advisory_id": "CVE-2024-3094",
|
|
2394
|
+
"url": "https://www.cisa.gov/known-exploited-vulnerabilities-catalog",
|
|
2395
|
+
"severity": "critical",
|
|
2396
|
+
"published_date": "2024-04-03"
|
|
2397
|
+
}
|
|
2398
|
+
]
|
|
2353
2399
|
},
|
|
2354
2400
|
"CVE-2024-3154": {
|
|
2355
2401
|
"ai_assisted_weaponization": false,
|
|
@@ -2536,7 +2582,23 @@
|
|
|
2536
2582
|
"https://www.cisa.gov/news-events/cybersecurity-advisories/aa20-352a"
|
|
2537
2583
|
],
|
|
2538
2584
|
"last_updated": "2026-05-15",
|
|
2539
|
-
"discovery_attribution_note": "Discovered during the SUNBURST incident-response investigation by FireEye / Mandiant analysts (publicly attributed to the Mandiant team rather than a single researcher) and corroborated by SolarWinds engineering. Documented in CISA AA20-352A and the CERT/CC VU#843464. Named human teams; pre-AI-tooling era for vendor-side attribution. Source: https://kb.cert.org/vuls/id/843464."
|
|
2585
|
+
"discovery_attribution_note": "Discovered during the SUNBURST incident-response investigation by FireEye / Mandiant analysts (publicly attributed to the Mandiant team rather than a single researcher) and corroborated by SolarWinds engineering. Documented in CISA AA20-352A and the CERT/CC VU#843464. Named human teams; pre-AI-tooling era for vendor-side attribution. Source: https://kb.cert.org/vuls/id/843464.",
|
|
2586
|
+
"vendor_advisories": [
|
|
2587
|
+
{
|
|
2588
|
+
"vendor": "NVD",
|
|
2589
|
+
"advisory_id": "CVE-2020-10148",
|
|
2590
|
+
"url": "https://nvd.nist.gov/vuln/detail/CVE-2020-10148",
|
|
2591
|
+
"severity": "critical",
|
|
2592
|
+
"published_date": "2020-12-29"
|
|
2593
|
+
},
|
|
2594
|
+
{
|
|
2595
|
+
"vendor": "CISA",
|
|
2596
|
+
"advisory_id": "AA20-352A",
|
|
2597
|
+
"url": "https://www.cisa.gov/news-events/cybersecurity-advisories/aa20-352a",
|
|
2598
|
+
"severity": "critical",
|
|
2599
|
+
"published_date": "2020-12-17"
|
|
2600
|
+
}
|
|
2601
|
+
]
|
|
2540
2602
|
},
|
|
2541
2603
|
"CVE-2023-3519": {
|
|
2542
2604
|
"ai_assisted_weaponization": false,
|
|
@@ -2599,7 +2661,23 @@
|
|
|
2599
2661
|
],
|
|
2600
2662
|
"last_updated": "2026-05-15",
|
|
2601
2663
|
"discovery_attribution_note": "Independent security researchers via Citrix coordinated disclosure (CTX561482, 2023-07-18); no individual researcher named in the Citrix advisory. NSA/CISA AA23-201A documents in-wild exploitation by Chinese state-sponsored actors. No AI-tool credited. Source: https://support.citrix.com/article/CTX561482/ and https://www.cisa.gov/news-events/cybersecurity-advisories/aa23-201a.",
|
|
2602
|
-
"rwep_correction_note": "v0.12.30: canonicalized rwep_factors AND rwep_score to satisfy Shape B invariant. The prior stored rwep_score was internally inconsistent with its rwep_factors block; both now derived from canonical RWEP_WEIGHTS + operational fields. Delta from prior stored: +5 (75 -> 80)."
|
|
2664
|
+
"rwep_correction_note": "v0.12.30: canonicalized rwep_factors AND rwep_score to satisfy Shape B invariant. The prior stored rwep_score was internally inconsistent with its rwep_factors block; both now derived from canonical RWEP_WEIGHTS + operational fields. Delta from prior stored: +5 (75 -> 80).",
|
|
2665
|
+
"vendor_advisories": [
|
|
2666
|
+
{
|
|
2667
|
+
"vendor": "NVD",
|
|
2668
|
+
"advisory_id": "CVE-2023-3519",
|
|
2669
|
+
"url": "https://nvd.nist.gov/vuln/detail/CVE-2023-3519",
|
|
2670
|
+
"severity": "critical",
|
|
2671
|
+
"published_date": "2023-07-19"
|
|
2672
|
+
},
|
|
2673
|
+
{
|
|
2674
|
+
"vendor": "Citrix",
|
|
2675
|
+
"advisory_id": "CTX561482",
|
|
2676
|
+
"url": "https://support.citrix.com/article/CTX561482",
|
|
2677
|
+
"severity": "critical",
|
|
2678
|
+
"published_date": "2023-07-18"
|
|
2679
|
+
}
|
|
2680
|
+
]
|
|
2603
2681
|
},
|
|
2604
2682
|
"CVE-2024-1709": {
|
|
2605
2683
|
"ai_assisted_weaponization": false,
|
|
@@ -2659,7 +2737,30 @@
|
|
|
2659
2737
|
"https://www.connectwise.com/company/trust/security-bulletins/connectwise-screenconnect-23.9.8"
|
|
2660
2738
|
],
|
|
2661
2739
|
"last_updated": "2026-05-15",
|
|
2662
|
-
"discovery_attribution_note": "Discovered by ConnectWise security engineering and externally reported by Huntress + GreyNoise via in-wild exploitation telemetry within 24 hours of the 2024-02 Patch Tuesday. No individual researcher byline; vendor-internal discovery. No AI-tool credited. Source: https://www.upguard.com/blog/screenconnect-cve-2024."
|
|
2740
|
+
"discovery_attribution_note": "Discovered by ConnectWise security engineering and externally reported by Huntress + GreyNoise via in-wild exploitation telemetry within 24 hours of the 2024-02 Patch Tuesday. No individual researcher byline; vendor-internal discovery. No AI-tool credited. Source: https://www.upguard.com/blog/screenconnect-cve-2024.",
|
|
2741
|
+
"vendor_advisories": [
|
|
2742
|
+
{
|
|
2743
|
+
"vendor": "NVD",
|
|
2744
|
+
"advisory_id": "CVE-2024-1709",
|
|
2745
|
+
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-1709",
|
|
2746
|
+
"severity": "critical",
|
|
2747
|
+
"published_date": "2024-02-19"
|
|
2748
|
+
},
|
|
2749
|
+
{
|
|
2750
|
+
"vendor": "ConnectWise",
|
|
2751
|
+
"advisory_id": null,
|
|
2752
|
+
"url": "https://www.connectwise.com/company/trust/security-bulletins/connectwise-screenconnect-23.9.8",
|
|
2753
|
+
"severity": "critical",
|
|
2754
|
+
"published_date": "2024-02-19"
|
|
2755
|
+
},
|
|
2756
|
+
{
|
|
2757
|
+
"vendor": "CISA KEV",
|
|
2758
|
+
"advisory_id": "CVE-2024-1709",
|
|
2759
|
+
"url": "https://www.cisa.gov/known-exploited-vulnerabilities-catalog",
|
|
2760
|
+
"severity": "critical",
|
|
2761
|
+
"published_date": "2024-02-22"
|
|
2762
|
+
}
|
|
2763
|
+
]
|
|
2663
2764
|
},
|
|
2664
2765
|
"CVE-2026-20182": {
|
|
2665
2766
|
"ai_assisted_weaponization": false,
|
|
@@ -2721,7 +2822,30 @@
|
|
|
2721
2822
|
],
|
|
2722
2823
|
"last_updated": "2026-05-15",
|
|
2723
2824
|
"discovery_attribution_note": "Discovered by Stephen Fewer (Senior Principal Security Researcher) and Jonah Burgess (Senior Security Researcher), both at Rapid7, while researching the related CVE-2026-20127 vdaemon authentication-bypass. Named human researchers; no AI-tool credited. Source: https://www.rapid7.com/blog/post/ve-cve-2026-20182-critical-authentication-bypass-cisco-catalyst-sd-wan-controller-fixed/.",
|
|
2724
|
-
"rwep_correction_note": "v0.12.30: canonicalized rwep_factors AND rwep_score to satisfy Shape B invariant. The prior stored rwep_score was internally inconsistent with its rwep_factors block; both now derived from canonical RWEP_WEIGHTS + operational fields. Delta from prior stored: 0."
|
|
2825
|
+
"rwep_correction_note": "v0.12.30: canonicalized rwep_factors AND rwep_score to satisfy Shape B invariant. The prior stored rwep_score was internally inconsistent with its rwep_factors block; both now derived from canonical RWEP_WEIGHTS + operational fields. Delta from prior stored: 0.",
|
|
2826
|
+
"vendor_advisories": [
|
|
2827
|
+
{
|
|
2828
|
+
"vendor": "NVD",
|
|
2829
|
+
"advisory_id": "CVE-2026-20182",
|
|
2830
|
+
"url": "https://nvd.nist.gov/vuln/detail/CVE-2026-20182",
|
|
2831
|
+
"severity": "critical",
|
|
2832
|
+
"published_date": null
|
|
2833
|
+
},
|
|
2834
|
+
{
|
|
2835
|
+
"vendor": "Cisco",
|
|
2836
|
+
"advisory_id": null,
|
|
2837
|
+
"url": "https://sec.cloudapps.cisco.com/security/center/publicationListing.x",
|
|
2838
|
+
"severity": "critical",
|
|
2839
|
+
"published_date": null
|
|
2840
|
+
},
|
|
2841
|
+
{
|
|
2842
|
+
"vendor": "CISA KEV",
|
|
2843
|
+
"advisory_id": "CVE-2026-20182",
|
|
2844
|
+
"url": "https://www.cisa.gov/known-exploited-vulnerabilities-catalog",
|
|
2845
|
+
"severity": "critical",
|
|
2846
|
+
"published_date": "2026-05-14"
|
|
2847
|
+
}
|
|
2848
|
+
]
|
|
2725
2849
|
},
|
|
2726
2850
|
"CVE-2024-40635": {
|
|
2727
2851
|
"ai_assisted_weaponization": false,
|
|
@@ -4418,7 +4542,30 @@
|
|
|
4418
4542
|
],
|
|
4419
4543
|
"_draft": false,
|
|
4420
4544
|
"last_updated": "2026-05-17",
|
|
4421
|
-
"discovery_attribution_note": "Vendor-internal discovery by Fortinet PSIRT, disclosed 2024-02-08 via advisory FG-IR-24-015. No external researcher byline. CISA KEV-listed 2024-02-09 with a 7-day federal remediation deadline. Post-exploitation symlink-persistence technique documented in Fortinet's 2025-04-11 advisory after operators reported residual filesystem access on devices patched after compromise."
|
|
4545
|
+
"discovery_attribution_note": "Vendor-internal discovery by Fortinet PSIRT, disclosed 2024-02-08 via advisory FG-IR-24-015. No external researcher byline. CISA KEV-listed 2024-02-09 with a 7-day federal remediation deadline. Post-exploitation symlink-persistence technique documented in Fortinet's 2025-04-11 advisory after operators reported residual filesystem access on devices patched after compromise.",
|
|
4546
|
+
"vendor_advisories": [
|
|
4547
|
+
{
|
|
4548
|
+
"vendor": "NVD",
|
|
4549
|
+
"advisory_id": "CVE-2024-21762",
|
|
4550
|
+
"url": "https://nvd.nist.gov/vuln/detail/CVE-2024-21762",
|
|
4551
|
+
"severity": "critical",
|
|
4552
|
+
"published_date": "2024-02-08"
|
|
4553
|
+
},
|
|
4554
|
+
{
|
|
4555
|
+
"vendor": "Fortinet",
|
|
4556
|
+
"advisory_id": "FG-IR-24-015",
|
|
4557
|
+
"url": "https://www.fortiguard.com/psirt/FG-IR-24-015",
|
|
4558
|
+
"severity": "critical",
|
|
4559
|
+
"published_date": "2024-02-08"
|
|
4560
|
+
},
|
|
4561
|
+
{
|
|
4562
|
+
"vendor": "CISA KEV",
|
|
4563
|
+
"advisory_id": "CVE-2024-21762",
|
|
4564
|
+
"url": "https://www.cisa.gov/known-exploited-vulnerabilities-catalog",
|
|
4565
|
+
"severity": "critical",
|
|
4566
|
+
"published_date": "2024-02-09"
|
|
4567
|
+
}
|
|
4568
|
+
]
|
|
4422
4569
|
},
|
|
4423
4570
|
"CVE-2025-10585": {
|
|
4424
4571
|
"id": "CVE-2025-10585",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"rebuild_after_days": 365,
|
|
18
18
|
"note": "Per-entry last_verified governs decay. Skills depending on this catalog must check entry freshness before high-stakes use."
|
|
19
19
|
},
|
|
20
|
-
"entry_count":
|
|
20
|
+
"entry_count": 422
|
|
21
21
|
},
|
|
22
22
|
"CVE-2026-31431": {
|
|
23
23
|
"name": "Copy Fail",
|
package/lib/gap-detectors.js
CHANGED
|
@@ -158,8 +158,14 @@ function temporalStalenessFindings(loaded, opts = {}) {
|
|
|
158
158
|
}
|
|
159
159
|
|
|
160
160
|
// CISA KEV due-date passed without remediation status — surfaces
|
|
161
|
-
// operationally-stale entries the operator should re-verify.
|
|
162
|
-
|
|
161
|
+
// operationally-stale CURATED entries the operator should re-verify.
|
|
162
|
+
// Auto-imported drafts are excluded: a KEV due-date passing with wall-clock
|
|
163
|
+
// time on the un-curated bulk-import backlog is expected (and grows the
|
|
164
|
+
// count purely by calendar drift, which would mechanically breach the
|
|
165
|
+
// budget gate on a no-op release). The finding is actionable only once the
|
|
166
|
+
// entry is curated, so it is scoped to non-draft entries.
|
|
167
|
+
const isDraft = e._auto_imported === true || e._draft === true;
|
|
168
|
+
if (!isDraft && e.cisa_kev === true && typeof e.cisa_kev_due_date === "string") {
|
|
163
169
|
const sinceDue = daysSince(e.cisa_kev_due_date, now);
|
|
164
170
|
if (sinceDue !== null && sinceDue > 0) {
|
|
165
171
|
out.push({ class: "temporal-staleness", catalog: "cve-catalog", id,
|
package/lib/lint-skills.js
CHANGED
|
@@ -119,7 +119,7 @@ const KEBAB_RE = /^[a-z0-9][a-z0-9-]*[a-z0-9]$/;
|
|
|
119
119
|
const JSON_FILENAME_RE = /^[A-Za-z0-9._-]+\.json$/;
|
|
120
120
|
|
|
121
121
|
function parseArgs(argv) {
|
|
122
|
-
const opts = { skill: null, quiet: false };
|
|
122
|
+
const opts = { skill: null, quiet: false, strict: false };
|
|
123
123
|
for (let i = 2; i < argv.length; i++) {
|
|
124
124
|
const a = argv[i];
|
|
125
125
|
if (a === '--skill') {
|
|
@@ -128,6 +128,11 @@ function parseArgs(argv) {
|
|
|
128
128
|
opts.skill = a.slice('--skill='.length);
|
|
129
129
|
} else if (a === '--quiet' || a === '-q') {
|
|
130
130
|
opts.quiet = true;
|
|
131
|
+
} else if (a === '--strict') {
|
|
132
|
+
// Promote warnings (header-only sections, unresolved draft refs,
|
|
133
|
+
// playbook air-gap gaps) to release-blocking failures. Used by the
|
|
134
|
+
// predeploy gate so a warned regression cannot scroll past.
|
|
135
|
+
opts.strict = true;
|
|
131
136
|
} else if (a === '--help' || a === '-h') {
|
|
132
137
|
printHelp();
|
|
133
138
|
process.exit(0);
|
|
@@ -856,7 +861,13 @@ function main() {
|
|
|
856
861
|
console.log(
|
|
857
862
|
`\n${passed}/${total} skills passed${warnSummary}${failed ? `, ${failed} failed` : ''}${orphanSummary}${airGapSummary}.`,
|
|
858
863
|
);
|
|
859
|
-
|
|
864
|
+
// --strict treats any warning (per-skill or playbook air-gap) as a
|
|
865
|
+
// release-blocking failure so a warned regression cannot ship silently.
|
|
866
|
+
const strictFail = opts.strict && (warned > 0 || (airGapWarnings && airGapWarnings.length > 0));
|
|
867
|
+
if (strictFail) {
|
|
868
|
+
console.log(`[lint-skills] --strict: ${warned + (airGapWarnings ? airGapWarnings.length : 0)} warning(s) treated as failures.`);
|
|
869
|
+
}
|
|
870
|
+
process.exit(failed === 0 && orphans.length === 0 && !strictFail ? 0 : 1);
|
|
860
871
|
}
|
|
861
872
|
|
|
862
873
|
// Export the minimal frontmatter parser for downstream consumers
|
package/lib/playbook-runner.js
CHANGED
|
@@ -2912,8 +2912,6 @@ function buildEvidenceBundle(format, playbook, analyze, validate, agentSignals,
|
|
|
2912
2912
|
rwep_adjusted: analyze.rwep?.adjusted || 0,
|
|
2913
2913
|
rwep_threshold_escalate: analyze.rwep?.threshold?.escalate || null,
|
|
2914
2914
|
blast_radius_score: analyze.blast_radius_score || 0,
|
|
2915
|
-
feeds_into: null, // populated by close()
|
|
2916
|
-
jurisdiction_clocks_active: null, // populated by close()
|
|
2917
2915
|
remediation_recommended: validate.selected_remediation?.id || null,
|
|
2918
2916
|
}
|
|
2919
2917
|
};
|
|
@@ -272,6 +272,21 @@ function additionalChecks(key, entry, ctx) {
|
|
|
272
272
|
}
|
|
273
273
|
}
|
|
274
274
|
|
|
275
|
+
// V5 — KEV status must carry its date (AGENTS.md Hard Rule #1: a KEV flag
|
|
276
|
+
// without a date is an incomplete threat-intel claim; RWEP scoring and the
|
|
277
|
+
// jurisdiction-clock SLAs key off the KEV listing date). cisa_kev=true with a
|
|
278
|
+
// null/missing/invalid cisa_kev_date is flagged; promoted to a hard error
|
|
279
|
+
// under --strict (predeploy). 0 violations in the shipped catalog today.
|
|
280
|
+
if (entry.cisa_kev === true) {
|
|
281
|
+
const d = entry.cisa_kev_date;
|
|
282
|
+
const dateOk = typeof d === 'string' && isUsableDate(d).ok;
|
|
283
|
+
if (!dateOk) {
|
|
284
|
+
warnings.push(
|
|
285
|
+
`${key}: cisa_kev=true but cisa_kev_date is ${JSON.stringify(d)} (KEV status must carry a valid listing date — Hard Rule #1)`,
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
275
290
|
// V4 — Impossible-date guard.
|
|
276
291
|
for (const f of DATE_FIELDS) {
|
|
277
292
|
const v = entry[f];
|
|
@@ -352,18 +367,26 @@ function main() {
|
|
|
352
367
|
}
|
|
353
368
|
}
|
|
354
369
|
|
|
355
|
-
// Guard
|
|
356
|
-
//
|
|
357
|
-
//
|
|
358
|
-
//
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
370
|
+
// Guard hand-maintained _meta.entry_count fields against silent drift. The
|
|
371
|
+
// framework-control-gaps counter once declared 184 while the file held 192
|
|
372
|
+
// and nothing caught it; the zeroday-lessons counter drifted to 68 while the
|
|
373
|
+
// file held 422 because only framework-control-gaps was gated. This now
|
|
374
|
+
// checks EVERY loaded catalog that declares a numeric _meta.entry_count, so a
|
|
375
|
+
// new catalog with the field is covered automatically.
|
|
376
|
+
const ENTRY_COUNT_CATALOGS = [
|
|
377
|
+
{ name: 'framework-control-gaps', catalog: frameworks },
|
|
378
|
+
{ name: 'zeroday-lessons', catalog: lessons },
|
|
379
|
+
];
|
|
380
|
+
for (const { name, catalog: cat } of ENTRY_COUNT_CATALOGS) {
|
|
381
|
+
if (cat && cat._meta && typeof cat._meta.entry_count === 'number') {
|
|
382
|
+
const actual = Object.keys(cat).filter((k) => !k.startsWith('_')).length;
|
|
383
|
+
if (cat._meta.entry_count !== actual) {
|
|
384
|
+
process.stderr.write(
|
|
385
|
+
`[validate-cve-catalog] FAIL: ${name} _meta.entry_count (${cat._meta.entry_count}) ` +
|
|
386
|
+
`!= actual entry count (${actual}). Update _meta.entry_count to ${actual}.\n`,
|
|
387
|
+
);
|
|
388
|
+
process.exit(1);
|
|
389
|
+
}
|
|
367
390
|
}
|
|
368
391
|
}
|
|
369
392
|
|