@blamejs/exceptd-skills 0.19.31 → 0.19.33

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 CHANGED
@@ -6,7 +6,7 @@ exceptd Security is a skills repository. Each skill is a `.md` file with YAML fr
6
6
 
7
7
  The repository has three layers:
8
8
 
9
- ```
9
+ ```text
10
10
  skills/ Instruction layer — tells the AI what to analyze, how to score, what to output
11
11
  data/ Intelligence layer — CVE metadata, ATLAS TTPs, framework gap mappings
12
12
  lib/ Logic layer — scoring algorithms, TTP mapper, framework gap analyzer
@@ -16,7 +16,7 @@ lib/ Logic layer — scoring algorithms, TTP mapper, framework gap a
16
16
 
17
17
  ## Skill File Anatomy
18
18
 
19
- ```
19
+ ```text
20
20
  skills/
21
21
  └── <skill-name>/
22
22
  └── skill.md Single file per skill. Frontmatter + body.
@@ -42,7 +42,7 @@ attack_refs:
42
42
  - T1068 # MITRE ATT&CK TTP IDs
43
43
  framework_gaps:
44
44
  - NIST-800-53-SI-2 # control IDs documented as insufficient in this skill
45
- - ISO-27001-A.12.6.1
45
+ - ISO-27001-2022-A.8.8 # must resolve against data/framework-control-gaps.json
46
46
  last_threat_review: "2026-05-01"
47
47
  ---
48
48
  ```
@@ -84,7 +84,7 @@ Schema per entry:
84
84
  "poc_description": "Public PoC description — no direct exploit links",
85
85
  "ai_discovered": false,
86
86
  "ai_assisted_weaponization": false,
87
- "active_exploitation": true,
87
+ "active_exploitation": "confirmed | suspected | theoretical | none | unknown",
88
88
  "affected": "Human-readable scope description",
89
89
  "affected_versions": ["kernel >= 4.14", "kernel < 6.8.10"],
90
90
  "vector": "Attack vector description",
@@ -95,26 +95,33 @@ Schema per entry:
95
95
  "live_patch_tools": ["kpatch", "livepatch", "kGraft"],
96
96
  "framework_control_gaps": {
97
97
  "NIST-800-53-SI-2": "Why this control is insufficient for this CVE",
98
- "ISO-27001-A.12.6.1": "Why this control is insufficient"
98
+ "ISO-27001-2022-A.8.8": "Why this control is insufficient"
99
99
  },
100
100
  "atlas_refs": ["AML.T0043"],
101
101
  "attack_refs": ["T1068"],
102
- "rwep_score": 96,
102
+ "rwep_score": 85,
103
103
  "rwep_factors": {
104
104
  "cisa_kev": 25,
105
105
  "poc_available": 20,
106
- "ai_assisted": 0,
106
+ "ai_factor": 0,
107
107
  "active_exploitation": 20,
108
- "blast_radius": 15,
109
- "patch_available": -7,
110
- "live_patch": -5,
111
- "reboot_required": 5
108
+ "blast_radius": 20,
109
+ "patch_available": 0,
110
+ "live_patch_available": 0,
111
+ "reboot_required": 0
112
112
  },
113
113
  "last_updated": "YYYY-MM-DD"
114
114
  }
115
115
  }
116
116
  ```
117
117
 
118
+ Two invariants the schema cannot express and the validator enforces:
119
+ `rwep_factors` must sum to `rwep_score`, and every key must match the weight
120
+ names in `lib/scoring.js` — `ai_factor` and `live_patch_available`, not
121
+ `ai_assisted` and `live_patch`. The weights are `cisa_kev` 25, `poc_available`
122
+ 20, `ai_factor` 15, `active_exploitation` 20, `blast_radius` 0–30,
123
+ `patch_available` −15, `live_patch_available` −10, `reboot_required` +5.
124
+
118
125
  ### `data/atlas-ttps.json`
119
126
 
120
127
  Schema per entry:
@@ -176,7 +183,7 @@ Tracks PoC status, weaponization stage, and AI-assist factor per CVE. Updated wh
176
183
 
177
184
  ### `data/cwe-catalog.json`
178
185
 
179
- 233 CWE entries pinned to **CWE v4.20**. Covers the Top 25 Most Dangerous Software Weaknesses (2024 release) plus AI- and supply-chain-relevant weakness classes (prompt-injection-as-trust-boundary failure, training data integrity, dependency confusion, untrusted artifact ingestion). Each entry records root-cause description, common consequences, mitigation patterns, and the CVEs in `cve-catalog.json` that instantiate the weakness. Skills cite CWE IDs in `cwe_refs` to anchor a finding to a stable weakness taxonomy rather than to a single CVE.
186
+ 236 CWE entries pinned to **CWE v4.20**. Covers the Top 25 Most Dangerous Software Weaknesses (2024 release) plus AI- and supply-chain-relevant weakness classes (prompt-injection-as-trust-boundary failure, training data integrity, dependency confusion, untrusted artifact ingestion). Each entry records root-cause description, common consequences, mitigation patterns, and the CVEs in `cve-catalog.json` that instantiate the weakness. Skills cite CWE IDs in `cwe_refs` to anchor a finding to a stable weakness taxonomy rather than to a single CVE.
180
187
 
181
188
  `_meta.cwe_version` pins the version; on a CWE release, audit IDs for renames or deprecations, bump `last_threat_review` on affected skills, and update `_meta`.
182
189
 
@@ -207,16 +214,18 @@ RWEP (Real-World Exploit Priority) scoring engine.
207
214
  - `validate()` — Schema validation: check all skill data_deps resolve, all CVE entries are complete, all ATLAS refs are valid v2026.07 IDs
208
215
  - `compare(cveId)` — Return CVSS vs. RWEP comparison with explanation of the delta
209
216
 
210
- RWEP factor weights:
211
- ```
212
- cisa_kev +25 (binary)
213
- poc_available +20 (binary)
214
- ai_assisted_weapon +15 (binary)
215
- active_exploitation +20 (binary)
216
- blast_radius +30 (0–30 scaled)
217
- patch_available -15 (binary)
218
- live_patch_available -10 (binary: additional reduction if no reboot required)
219
- reboot_required +5 (binary penalty: patch exists but requires reboot)
217
+ RWEP factor weights. The key names here are the ones a catalog entry's
218
+ `rwep_factors` must use, and the factors must sum to `rwep_score`:
219
+
220
+ ```text
221
+ cisa_kev +25 binary
222
+ poc_available +20 binary
223
+ ai_factor +15 binary — ai_discovered OR ai_assisted_weaponization
224
+ active_exploitation +20 graded — confirmed 20, suspected 10, unknown 5, none 0
225
+ blast_radius 0-30 scaled
226
+ patch_available -15 binary
227
+ live_patch_available -10 binary
228
+ reboot_required +5 binary — the patch exists but needs a reboot
220
229
  ```
221
230
 
222
231
  ### `lib/ttp-mapper.js`
@@ -277,7 +286,7 @@ Skills can be composed. `framework-gap-analysis` calls out to `threat-model-curr
277
286
 
278
287
  Composition is explicit: skills declare which other skills they depend on in their frontmatter `skill_deps` field. Circular dependencies are not permitted.
279
288
 
280
- ```
289
+ ```text
281
290
  zeroday-gap-learn → framework-control-gaps.json (writes)
282
291
  framework-gap-analysis → framework-control-gaps.json (reads)
283
292
  compliance-theater → exploit-scoring (depends on RWEP)
package/CHANGELOG.md CHANGED
@@ -1,5 +1,33 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.19.33 — 2026-08-23
4
+
5
+ The catalog reaches 1,417 CVEs with 94 additions from CISA KEV, weighted to the years the vendors in question were shipping fastest: 25 from 2017, 18 from 2018, 11 from 2015, and ten each from 2016 and 2019. Cisco accounts for 38, Microsoft 28 and Adobe 12. Sixteen carry CISA's ransomware designation, 42 have an obtainable public exploit, and 61 need a restart before the fix is running — the entries keep that separate from the update being installed, because a remediation record keyed to the deployed version reports a host as done while the pre-patch code is still executing.
6
+
7
+ Thirty-eight of the additions are Cisco IOS and IOS XE advisories, and most of them publish no fixed-release table. Cisco routes operators to its Software Checker, which answers per image and per train rather than per CVE, so those entries name the Checker and the Cisco bug ID as the lookup key instead of a version number. Where a version boundary does exist it is recorded; where one does not, the entry says so rather than inventing one. The same advisories share bug IDs across CVEs without publishing a per-CVE mapping, and for the nine SNMP entries that means a single configuration change — dropping the MIB view exclusion — reopens all of them at once.
8
+
9
+ Where sources disagree, the entries carry the disagreement. Microsoft's record for CVE-2019-1297 still rates exploitation less likely while CISA listed it as exploited two and a half years later, and the entry states both rather than resolving them. Cisco's advisory for CVE-2018-0151 has not been revised since 2018 and says its response team is unaware of malicious use, while CISA lists it; the entry scopes its remediation trigger to the KEV listing and records the vendor's position beside it. NVD and Cisco score CVE-2018-0161 differently on attack complexity, and neither publishes the device state that would explain the gap, so both vectors are reported.
10
+
11
+ Twenty-one entries carry a weakness assigned editorially, and each says so in its attribution along with the reason. Thirteen are CVEs for which NVD published no weakness at all. The other eight are ones where NVD published only CWE-399, a category MITRE prohibits in that position: those name the real weakness the mechanism implies — an unbounded MAC table is a resource-allocation failure, an SNMP walk that pins the CPU is uncontrolled consumption — rather than repeating a classification that resolves to nothing.
12
+
13
+ Framework-gap statements are written from each CVE's own dates, versions and vendor wording. Claims about what organisations typically do — which patches get deferred, what a monitoring programme usually collects, how much of an estate runs a given configuration — are absent, because none of them could be sourced and each was load-bearing for the conclusion it supported. Where a standard's text carries the argument it is quoted; where the standard could not be reached, the argument rests on something that could.
14
+
15
+ ## 0.19.32 — 2026-08-21
16
+
17
+ A KEV entry stores four fields from CISA's record and the refresh compared two of them. The listing flag and its date tracked upstream; the remediation deadline and the ransomware designation were written once, at curation, and never looked at again. Both now reconcile on every refresh, on the live path and the cached one alike, which closes a gap that had been widening since the fields were first stored.
18
+
19
+ The catalog is corrected accordingly. Fifty-one entries carried no ransomware designation where CISA now records one, and forty-three of those had no such field at all — which every consumer reads as a denial rather than as an absence. All 1,167 KEV-listed entries now carry the boolean explicitly, and the catalog validator refuses one that does not, so the field cannot go back to being sometimes-absent. Four entries stated a remediation deadline of twenty-one days after listing where CISA required three or fourteen; that date is rendered into remediation output and regulator notification drafts, so it was telling operators they had time the directive does not give them. Eleven more had no deadline stored at all.
20
+
21
+ Six entries said in prose that CISA recorded no ransomware association while their own corrected flag said otherwise. An entry that contradicts itself is worse than one that is simply wrong, because the reader cannot tell which half to believe; those sentences now state what the record states.
22
+
23
+ A designation no longer outlives the listing it came from. When CISA removes a CVE, the refresh already cleared the listing dates but left the ransomware flag standing on a record that no longer exists; it is cleared to unknown rather than to false, since false would assert something upstream is no longer there to say.
24
+
25
+ `refresh --drift-only` reconciles the entries the catalog already holds and skips discovery of new ones. Discovery imports drafts that still need curation, so correcting stale fields on shipped entries previously meant either taking that work in the same change or leaving the fields stale.
26
+
27
+ The repository documentation describes the repository again. `ARCHITECTURE.md` carried a CVE schema example — the block a contributor copies — whose `active_exploitation` was a boolean where the schema defines a five-value string, whose factor keys were `ai_assisted` and `live_patch` where the scorer reads `ai_factor` and `live_patch_available`, and whose patch weights were −7 and −5 against the real −15 and −10. It also cited an ISO control under its superseded 2013 numbering, which resolves against nothing. `CONTEXT.md` wrote the RWEP formula with a minus in front of two already-negative weights, turning both mitigating factors into penalties. `MAINTAINERS.md` told a maintainer to commit and push to `main`, which requires a pull request and rejects the push, and restated upstream version pins that had drifted from the catalogs that own them. `SECURITY.md` told reporters not to open a public issue without naming the private advisory channel that is enabled. Counts across all six files now match the data they describe.
28
+
29
+ Comment volume is down across the scoring engine and the curation modules, with every surviving comment either a contract the signature cannot state or a trap worth naming. No behavior changed.
30
+
3
31
  ## 0.19.31 — 2026-08-19
4
32
 
5
33
  The catalog reaches 1,323 CVEs with 98 additions from CISA KEV, spanning 2005 to 2025 with the weight in the middle years: 15 from 2019, 11 from 2016, 10 each from 2018 and 2020. Microsoft accounts for 29, with Adobe, Cisco, D-Link, Oracle, Apache, Citrix, NETGEAR and VMware behind it. Twenty-four carry CISA's ransomware designation and 76 have an obtainable public exploit.
package/CONTEXT.md CHANGED
@@ -115,14 +115,14 @@ Skills and playbooks read from `data/`. Authoritative catalog inventory:
115
115
 
116
116
  | File | Entries | Purpose |
117
117
  |------|---------|---------|
118
- | `cve-catalog.json` | 1125 | CVEs with CVSS, RWEP score, EPSS estimates, CISA KEV flags, PoC and live-patch availability |
118
+ | `cve-catalog.json` | 1323 | CVEs with CVSS, RWEP score, EPSS estimates, CISA KEV flags, PoC and live-patch availability |
119
119
  | `atlas-ttps.json` | 174 | MITRE ATLAS v2026.07 (August 2026) techniques with framework gap flags |
120
120
  | `attack-techniques.json` | 794 | MITRE ATT&CK techniques with framework coverage mappings |
121
121
  | `framework-control-gaps.json` | 194 | Framework control gap entries: designed-for vs. what each control misses |
122
122
  | `exploit-availability.json` | 28 | Per-CVE PoC locations, weaponization stage, AI-acceleration factor, live-patch status |
123
123
  | `global-frameworks.json` | 35 jurisdictions | Patch SLAs and notification windows across global regulatory regimes |
124
- | `zeroday-lessons.json` | 1125 | Learning-loop entries: zero-day → attack vector → control gap → framework gap → new control |
125
- | `cwe-catalog.json` | 233 | CWE v4.20 entries (Top 25 2024 plus AI- and supply-chain-relevant weaknesses) |
124
+ | `zeroday-lessons.json` | 1323 | Learning-loop entries: zero-day → attack vector → control gap → framework gap → new control |
125
+ | `cwe-catalog.json` | 236 | CWE v4.20 entries (Top 25 2024 plus AI- and supply-chain-relevant weaknesses) |
126
126
  | `d3fend-catalog.json` | 468 | MITRE D3FEND v1.3.0 defensive techniques for offensive → defensive mapping |
127
127
  | `rfc-references.json` | 8889 | IETF RFC / Internet-Draft references with status, errata count, replaces / replaced-by, `last_verified` dates |
128
128
  | `dlp-controls.json` | 22 | DLP control entries indexed by channel, classifier, surface, enforcement mode, evidence type |
@@ -154,16 +154,24 @@ researcher — front-door dispatcher for raw threat intel
154
154
 
155
155
  The repository uses Real-World Exploit Priority (RWEP) scoring, not CVSS alone. CVSS is reported alongside RWEP but never as the sole score.
156
156
 
157
- RWEP formula (0–100):
158
- ```
159
- base = cisa_kev(+25) + poc_public(+20) + ai_factor(+15)
160
- + active_exploitation(+20) + blast_radius(0-30)
161
- - patch_available(-15) - live_patch(-10) + reboot_required(+5)
157
+ RWEP is the sum of eight weighted factors, clamped to 0–100. The two mitigating
158
+ factors carry negative weights, so every term is added:
162
159
 
163
- ai_factor = ai_discovered OR ai_assisted_weaponization
164
- blast_radius = 0-30 scale (30 = all-Linux or 150M+ installations)
165
- reboot_required = +5 always when patch requires reboot
166
160
  ```
161
+ rwep_score = cisa_kev(+25) + poc_available(+20) + ai_factor(+15)
162
+ + active_exploitation(+20) + blast_radius(0..+30)
163
+ + patch_available(-15) + live_patch_available(-10)
164
+ + reboot_required(+5)
165
+
166
+ ai_factor = ai_discovered OR ai_assisted_weaponization
167
+ blast_radius = 0-30 (30 = all-Linux, or an install base in the 150M range)
168
+ active_exploitation = +20 confirmed, +10 suspected, +5 unknown
169
+ reboot_required = +5 whenever the patch needs a reboot
170
+ ```
171
+
172
+ The stored `rwep_factors` must sum to the stored `rwep_score`; the catalog
173
+ validator fails the entry when they disagree. `lib/scoring.js` holds the weights,
174
+ and its key names are the ones the catalog must use.
167
175
 
168
176
  Example: CVE-2026-31431 (Copy Fail) — CVSS 7.8 / **RWEP 90**
169
177
  - CVSS 7.8 suggests "high, patch within 30 days"
package/README.md CHANGED
@@ -28,9 +28,27 @@
28
28
 
29
29
  Every skill explicitly flags where a compliance framework's control is insufficient for current attack patterns. The framework is often the problem, not the org.
30
30
 
31
- ## Status
31
+ ## What ships
32
32
 
33
- Pre-1.0. Latest release lives on [GitHub Releases](https://github.com/blamejs/exceptd-skills/releases) and on npm as [`@blamejs/exceptd-skills`](https://www.npmjs.com/package/@blamejs/exceptd-skills) with signed npm provenance attestation and Ed25519-signed skill bodies. The package ships 51 skills across kernel LPE, MCP supply chain, AI-as-C2, prompt injection, post-quantum crypto, SBOM integrity, identity-incident response, and 35 other AI/security domains, plus 11 intelligence catalogs (CVE / ATLAS / ATT&CK / CWE / D3FEND / DLP / RFC / framework gaps / global frameworks / zero-day lessons / exploit availability) covering 35 jurisdictions; the CVE catalog holds 1025 actively-exploited and high-priority entries, each carrying behavioral indicators, an ATT&CK technique mapping, and a defense-chain zero-day lesson. 33 investigation playbooks (kernel, MCP, AI-API, framework, SBOM, runtime, hardening, secrets, cred-stores, containers, crypto, plus `webhook-callback-abuse`, `cicd-pipeline-compromise`, `identity-sso-compromise`, `llm-tool-use-exfil`, `post-quantum-migration`, `ai-discovered-cve-triage`, `supply-chain-recovery`, `citation-hygiene`, `vc-wallet-trust`, `mail-server-hardening`, `network-trust`, `audit-log-integrity`, `self-update-integrity`, `multitenancy-isolation`, `decompression-dos`, `log-injection-telemetry`, `privacy-consent-ops`, and more), a CLI for discovery and investigation built around `discover → brief → run → attest` (each run executes the playbook's seven-phase contract), and a nightly auto-refresh job that pulls KEV / NVD / EPSS / GHSA / OSV / IETF deltas plus 15 primary-source advisory, research-blog, and tech-press feeds (Qualys TRU, Red Hat RHSA, Ubuntu USN, ZDI, kernel.org, oss-security, JFrog, CISA, Microsoft Security Blog, Sysdig, Trail of Bits, Embrace the Red, BleepingComputer security, and The Hacker News) into auto-PRs for editorial review, alongside a silent-regression watcher that flags historical CVEs re-broken without a new identifier.
33
+ Pre-1.0. Released on [GitHub](https://github.com/blamejs/exceptd-skills/releases)
34
+ and on npm as [`@blamejs/exceptd-skills`](https://www.npmjs.com/package/@blamejs/exceptd-skills),
35
+ with npm provenance attestation and an Ed25519 signature on every skill body.
36
+
37
+ 51 skills across kernel LPE, MCP supply chain, AI-as-C2, prompt injection,
38
+ post-quantum crypto, SBOM integrity, identity incident response and 35 further
39
+ domains.
40
+
41
+ | | |
42
+ |---|---|
43
+ | **11 catalogs** | CVE, ATLAS, ATT&CK, CWE, D3FEND, DLP, RFC, framework gaps, global frameworks, zero-day lessons, exploit availability — across 35 jurisdictions |
44
+ | **1,323 CVEs** | Each with behavioral indicators, an ATT&CK technique mapping, and a defense-chain zero-day lesson |
45
+ | **33 playbooks** | Seven-phase investigations: `kernel`, `mcp`, `ai-api`, `sbom`, `containers`, `crypto`, `secrets` and the rest, through `webhook-callback-abuse`, `cicd-pipeline-compromise`, `identity-sso-compromise`, `llm-tool-use-exfil` and `post-quantum-migration`. `exceptd brief --all` is the live list |
46
+ | **A CLI** | `discover → brief → run → attest`, where each run executes the playbook's seven-phase contract |
47
+
48
+ A nightly job pulls KEV, NVD, EPSS, GHSA, OSV and IETF deltas alongside 15
49
+ advisory, vendor-research and tech-press feeds, and opens a pull request for
50
+ editorial review rather than merging. A companion watcher flags historical CVEs
51
+ re-broken without a new identifier being assigned.
34
52
 
35
53
  ---
36
54
 
@@ -159,20 +177,6 @@ Verify on npm: `npm view @blamejs/exceptd-skills@<version> dist.signatures` show
159
177
 
160
178
  Air-gapped operation: run `exceptd refresh --prefetch` on a connected host, copy the resulting `.cache/upstream/` to the airgap, run `exceptd refresh --from-cache <path> --apply` over there. The vendored upstream snapshots replace every network call.
161
179
 
162
- Fresh-disclosure workflow (v0.12.0): the nightly auto-PR job pulls KEV / NVD / EPSS / IETF / **GHSA** (added in v0.12.0) / **OSV** (added in v0.12.10). KEV typically takes days; NVD ~10 days; GHSA fires within hours of disclosure and covers npm + PyPI + Maven + Go + NuGet + …; OSV aggregates the OSSF Malicious Packages dataset (`MAL-*` keys) + Snyk + RustSec + Mageia + Ubuntu USN + Go Vuln DB + PYSEC + UVI on top of GHSA — useful for malicious-package compromises that don't have CVEs yet (`exceptd refresh --advisory MAL-2026-3083`). New IDs land as drafts (`_auto_imported: true`, `_draft: true`) that the catalog validator treats as warnings, not errors — operators get the fresh entry immediately, editorial review (framework gaps, IoCs, ATLAS/ATT&CK refs) follows via `exceptd refresh --curate <ID>`. To pull one advisory immediately: `exceptd refresh --advisory <CVE-or-GHSA-or-MAL-or-SNYK-or-RUSTSEC-ID> --apply`.
163
-
164
- Primary-source advisory polling: `exceptd refresh --check-advisories` polls 15 vendor and coordinated-disclosure feeds — 8 advisory/coordinated-disclosure venues (Qualys TRU, Red Hat RHSA, Ubuntu USN, Zero Day Initiative, kernel.org commits, oss-security mailing list, JFrog SecOps, CISA current advisories), 4 vendor security research blogs (Microsoft Security Blog, Sysdig, Trail of Bits, Embrace the Red), and 3 more (BleepingComputer security, The Hacker News, and a researcher activity-feed tracker). Combined coverage publishes CVE IDs at T+0 to T+1 — typically 3–14 days ahead of NVD enrichment. The command is report-only: it returns a structured `diffs[]` listing each newly-seen CVE ID with its source attributions and advisory URLs, but does not mutate the catalog. A complementary silent-regression watcher (`lib/cve-regression-watcher.js`) cross-checks poller diffs for historical-CVE references (year ≤ currentYear − 2) and surfaces candidate silent-regression cases — historical CVEs re-broken by a new proof-of-concept without a new ID being assigned. Operators triage the output and route promising IDs through `exceptd refresh --advisory <CVE-ID> --apply`. Pairs with the daily scheduled remote agent below.
165
-
166
- CVE-class alert surfacing: `exceptd watchlist --alerts` matches the live `cve-catalog.json` against five operational patterns (`kernel_lpe_with_poc`, `supply_chain_family`, `ai_discovered_kev`, `active_exploitation_unpatched`, `recent_poc_no_kev_yet`) and returns the matches sorted critical-severity-first, then by RWEP. Use it to triage a refreshed catalog without scanning every entry by hand.
167
-
168
- GitHub repo-pattern monitoring: `exceptd watchlist --org-scan --org <login>` probes GitHub Search for repositories matching known threat-actor naming patterns ("A Gift From TeamPCP", "Shai-Hulud", "TeamPCP") scoped to one org. Custom patterns via repeatable `--pattern <s>`. Implements the canonical detection for the Shai-Hulud / TeamPCP supply-chain framework class — the attacker uses GitHub itself as the exfil channel. Set `GITHUB_TOKEN` for private-repo coverage and rate-limit headroom; public-repo search works without auth.
169
-
170
- AI-assistant config-file audit: `exceptd doctor --ai-config` walks `~/.claude`, `~/.cursor`, `~/.codeium`, `~/.aider`, and `~/.continue`, flagging sensitive files (`settings.json`, `mcp.json`, `*.mcp_config.json`, `api_key*`, `*.token`, `*.credentials`) not at mode 0600 on POSIX. On Windows the mode bits aren't load-bearing; each finding is surfaced with an info-level "manual ACL review" note. Catches the AI-config-credential-exfil class that the Shai-Hulud framework targets. Opt-in — does not run as part of the default no-flag `doctor` pass.
171
-
172
- Evidence-collection layer: `exceptd collect <playbook>` invokes a companion script under `lib/collectors/<playbook>.js` that walks cwd, applies the catalogued regex set, stats permissions, and emits the submission JSON in the same shape `exceptd run --evidence -` accepts. 14 of 33 playbooks have collectors today (`ai-api`, `cicd-pipeline-compromise`, `citation-hygiene`, `containers`, `cred-stores`, `crypto`, `crypto-codebase`, `hardening`, `kernel`, `library-author`, `mcp`, `runtime`, `sbom`, `secrets`); the remaining 19 are policy-skipped per AGENTS.md (judgement-shaped incident / governance / pure-analyze playbooks where AI-driven evidence collection is the design). Canonical operator pipe: `exceptd collect <pb> | exceptd run <pb> --evidence -`. `exceptd doctor --collectors` enumerates the layer; `exceptd discover` tags applicable playbooks with `[collector]` when one ships. `cicd-pipeline-compromise` requires `--attest-ownership` on the collect call (the playbook's `operator-owns-ci-fleet` precondition is opt-in to prevent unauthorized CI assessments).
173
-
174
- Daily scheduled threat intake: a `routine: exceptd-threat-intake` (claude.ai remote agent) runs daily at 14:00 UTC. Sequence: `npm install` → `refresh --check-advisories` → `watchlist --alerts` → `refresh --apply` → `refresh --advisory <CVE-ID>` for up to 5 new CVE IDs from the primary-source feeds → re-sign + rebuild-indexes if the catalog mutated → commit on `intake/<YYYY-MM-DD>` branch with the full diff in the report. Fresh disclosures no longer wait for an operator to trigger an intake run. Operator-managed at <https://claude.ai/code/routines>.
175
-
176
180
  Optional env vars for higher rate budgets:
177
181
 
178
182
  | Variable | Purpose |
@@ -202,11 +206,83 @@ npm run predeploy # full predeploy gate sequence locally
202
206
 
203
207
  Direct invocations also available: `npm run verify`, `node lib/sign.js sign-all`.
204
208
 
209
+ ## Keeping the catalog current
210
+
211
+ A CVE reaches the catalog through one of three paths, at different speeds.
212
+
213
+ **The nightly job** pulls KEV, NVD, EPSS, IETF, GHSA and OSV. They arrive at
214
+ different times: KEV takes days and NVD around ten, while GHSA fires within hours
215
+ of disclosure across npm, PyPI, Maven, Go and NuGet. OSV layers Snyk, RustSec,
216
+ Mageia, Ubuntu USN, the Go vulnerability database, PYSEC and UVI on top, plus the
217
+ OSSF Malicious Packages dataset — which is where a compromised package with no
218
+ CVE shows up at all. New IDs land as drafts flagged `_auto_imported`, which the
219
+ catalog validator reports as warnings rather than errors: the entry is available
220
+ immediately and the editorial work follows.
221
+
222
+ ```bash
223
+ exceptd refresh --advisory CVE-2026-45321 --apply # pull one ID now
224
+ exceptd refresh --curate CVE-2026-45321 # editorial questions for a draft
225
+ exceptd refresh --drift-only --apply # reconcile what is already held
226
+ ```
227
+
228
+ **Primary-source polling** runs ahead of all of them. `exceptd refresh
229
+ --check-advisories` reads 15 feeds — eight advisory and coordinated-disclosure
230
+ venues (Qualys TRU, Red Hat RHSA, Ubuntu USN, ZDI, kernel.org commits,
231
+ oss-security, JFrog SecOps, CISA), four vendor research blogs (Microsoft
232
+ Security, Sysdig, Trail of Bits, Embrace the Red), and three press and researcher
233
+ trackers. Between them they publish CVE IDs three to fourteen days ahead of NVD
234
+ enrichment. The command is report-only: it returns each newly-seen ID with its
235
+ sources and advisory URLs and changes nothing. `lib/cve-regression-watcher.js`
236
+ reads the same diffs for references to CVEs two or more years old, which is what
237
+ a silently re-broken historical flaw looks like before anyone assigns it a new
238
+ identifier.
239
+
240
+ **A daily agent** (`routine: exceptd-threat-intake`, 14:00 UTC) chains those
241
+ steps — poll, alert, refresh, enrich up to five new IDs, re-sign and rebuild if
242
+ the catalog moved — and commits to an `intake/<date>` branch. Managed at
243
+ <https://claude.ai/code/routines>.
244
+
245
+ Once a refresh lands, `exceptd watchlist --alerts` matches the catalog against
246
+ five operational patterns — `kernel_lpe_with_poc`, `supply_chain_family`,
247
+ `ai_discovered_kev`, `active_exploitation_unpatched`, `recent_poc_no_kev_yet` —
248
+ sorted critical-first, then by RWEP, so a refreshed catalog can be triaged
249
+ without reading every entry.
250
+
251
+ ## Evidence collection
252
+
253
+ `exceptd collect <playbook>` walks the working directory, applies the playbook's
254
+ catalogued patterns, stats permissions, and emits submission JSON in the shape
255
+ `exceptd run --evidence -` accepts:
256
+
257
+ ```bash
258
+ exceptd collect <playbook> | exceptd run <playbook> --evidence -
259
+ exceptd doctor --collectors # which playbooks ship one, and which do not
260
+ ```
261
+
262
+ 14 of the 33 playbooks ship a collector. The other 19 are deliberately without
263
+ one: they are judgement-shaped incident, governance and pure-analyze playbooks
264
+ where the evidence is an assessment rather than a file on disk.
265
+ `cicd-pipeline-compromise` additionally requires `--attest-ownership`, because
266
+ its `operator-owns-ci-fleet` precondition is what stops it being pointed at
267
+ someone else's CI.
268
+
269
+ Two scans sit outside the playbook contract:
270
+
271
+ - `exceptd watchlist --org-scan --org <login>` searches one GitHub org for
272
+ repositories matching known threat-actor naming patterns. This is the
273
+ detection for the supply-chain class that uses GitHub itself as the exfil
274
+ channel. Set `GITHUB_TOKEN` for private repositories and rate-limit headroom.
275
+ - `exceptd doctor --ai-config` checks `~/.claude`, `~/.cursor`, `~/.codeium`,
276
+ `~/.aider` and `~/.continue` for credential-bearing files — `settings.json`,
277
+ `mcp.json`, `api_key*`, `*.token`, `*.credentials` — left readable beyond mode
278
+ 0600. Windows has no equivalent bit, so findings there are raised for manual
279
+ ACL review. Opt-in; the bare `doctor` pass does not run it.
280
+
205
281
  ## CLI command reference
206
282
 
207
283
  Every command works the same via `npx @blamejs/exceptd-skills`, a global install (`exceptd`), or a local `node bin/exceptd.js`.
208
284
 
209
- ### v0.11.0 canonical verbs
285
+ ### Canonical verbs
210
286
 
211
287
  ```
212
288
  exceptd First-run welcome — two ways to start
@@ -415,6 +491,11 @@ exceptd refresh Refresh upstream catalogs + indexes.
415
491
  upstream artifact now (network required).
416
492
  Run on a connected host, then point
417
493
  --from-cache at the result on the air-gap.
494
+ --drift-only Reconcile the entries the catalog already
495
+ holds; skip discovery of new ones. Use it
496
+ to correct stale fields on shipped entries
497
+ without pulling in drafts that still need
498
+ curation.
418
499
  --no-network Report-only dry-run: list what would be
419
500
  fetched without touching the network.
420
501
  --network (v0.11.14) Fetch latest signed catalog
@@ -506,7 +587,7 @@ exceptd <verb> --help Most verbs print per-verb usage with flag
506
587
  descriptions.
507
588
  ```
508
589
 
509
- ### Legacy v0.10.x verbs
590
+ ### Deprecated and removed verbs
510
591
 
511
592
  Five verbs removed in v0.13.0 after deprecation since v0.11.0. Invoking any of these now returns a structured `ok:false` refusal pointing at the replacement; pre-v0.13 scripts must migrate.
512
593
 
package/SECURITY.md CHANGED
@@ -1,73 +1,93 @@
1
1
  # Security Policy
2
2
 
3
- ## Scope
3
+ ## Reporting a vulnerability
4
4
 
5
- This security policy covers the exceptd Security skills repository itself — the skill files, data catalogs, and library code. It does not cover downstream applications that use these skills.
5
+ Two private channels, either is fine:
6
6
 
7
- ## Reporting a Vulnerability
7
+ - **GitHub** — open a draft advisory from the repository's Security tab
8
+ ([Report a vulnerability](https://github.com/blamejs/exceptd-skills/security/advisories/new)).
9
+ Private vulnerability reporting is enabled, so the report stays between you and
10
+ the maintainers until an advisory is published.
11
+ - **Email** — security@exceptd.com
8
12
 
9
- Email: security@exceptd.com
13
+ **Do not open a public GitHub issue.** A public issue is the one channel that
14
+ tells everyone else before the fix exists.
10
15
 
11
- Include:
12
- - Description of the issue
13
- - Steps to reproduce
14
- - Impact assessment
15
- - Whether you believe this is being actively exploited
16
+ Include what you have:
16
17
 
17
- **Do not file public GitHub issues for security vulnerabilities.**
18
+ - What the issue is
19
+ - How to reproduce it
20
+ - What an attacker gets
21
+ - Whether you believe it is being exploited now
18
22
 
19
- ## Response SLAs
23
+ ## What to expect
20
24
 
21
- | Severity | First Response | Triage | Fix |
25
+ | Severity | First response | Triage | Fix |
22
26
  |---|---|---|---|
23
- | Critical (data integrity attack on CVE catalog, RWEP score manipulation) | 24h | 72h | 7d |
24
- | High (skill instruction that produces incorrect remediation for CISA KEV) | 72h | 7d | 14d |
25
- | Medium (incorrect framework gap mapping, wrong control ID) | 7d | 14d | 30d |
26
- | Low (missing data, incomplete entries) | 14d | 30d | next minor |
27
-
28
- ## Supported Versions
29
-
30
- Pre-1.0: Latest patch on the most recent minor receives data updates (CVE catalog, framework gap updates, new ATLAS TTPs). All versions receive critical accuracy corrections.
27
+ | Critical — data-integrity attack on the CVE catalog, RWEP score manipulation | 24h | 72h | 7d |
28
+ | High — a skill that produces incorrect remediation for a CISA KEV entry | 72h | 7d | 14d |
29
+ | Medium — an incorrect framework gap mapping or wrong control ID | 7d | 14d | 30d |
30
+ | Low — missing data, incomplete entries | 14d | 30d | next minor |
31
31
 
32
- Once 1.0: 18-month data update support after each major version.
32
+ ## Supported versions
33
33
 
34
- ## Threat Model
34
+ Pre-1.0, the latest patch on the most recent minor receives data updates: CVE
35
+ catalog, framework gap changes, new ATLAS TTPs. Every version receives critical
36
+ accuracy corrections.
35
37
 
36
- ### What This Repo Defends
38
+ From 1.0, each major version receives data updates for 18 months.
37
39
 
38
- **Data integrity of the CVE catalog and RWEP scores.** Tampered scores could cause security teams to deprioritize genuinely critical vulnerabilities. Every RWEP calculation is reproducible from `data/cve-catalog.json` inputs and the formula in `lib/scoring.js`. Auditors should verify scores independently for high-stakes decisions.
39
-
40
- **Accuracy of framework gap declarations.** If a gap is incorrectly declared as "closed" when it remains open, organizations may believe they are protected when they are not. Gap status changes require evidence (framework update reference + control text analysis) not assertions.
40
+ ## Scope
41
41
 
42
- **Freshness of exploit availability data.** Stale PoC status (marking an exploit as not-public when it is) causes teams to use incorrect RWEP scores. `data/exploit-availability.json` is versioned and dated. Every entry has a `last_verified` field.
42
+ This policy covers the repository itself — the skill files, the data catalogs,
43
+ and the library code. It does not cover applications built on top of them.
43
44
 
44
- **Skill instruction correctness.** A skill that produces incorrect remediation guidance (e.g., recommending a patch that doesn't exist for a kernel version, citing a wrong ATLAS TTP ID) creates direct harm. Skills are pinned to `last_threat_review` dates and reviewed when referenced CVEs or TTPs change.
45
+ The repository has no npm runtime dependencies; `lib/` is self-contained and the
46
+ skills and catalogs are plain text and JSON. Loaded through an AI assistant, the
47
+ skills are instruction text: nothing here executes in your environment unless
48
+ your assistant chooses to run it.
45
49
 
46
- ### What This Repo Does Not Defend
50
+ Out of scope:
47
51
 
48
- - Runtime security of applications that use these skills (that's blamejs's scope)
49
- - Upstream framework accuracy (NIST, ISO, MITRE ATLAS) — we track lag, we don't control it
50
- - Physical access to systems this runs on
52
+ - Runtime security of applications that consume these skills
53
+ - Accuracy of the upstream frameworks themselves — NIST, ISO and MITRE lag is
54
+ tracked here, not controlled here
55
+ - Physical access to the machine this runs on
51
56
 
52
- ## Data Integrity
57
+ ## What the repository defends
53
58
 
54
- CVE catalog entries and RWEP scores are not authoritative sources — they are analytical summaries for operational use. Always cross-reference:
59
+ **The CVE catalog and its RWEP scores.** Tampered scores deprioritize
60
+ vulnerabilities that are genuinely critical. Every RWEP score is reproducible
61
+ from the inputs in `data/cve-catalog.json` and the formula in `lib/scoring.js`;
62
+ recompute it yourself when the decision is a large one.
55
63
 
56
- - CISA KEV: https://www.cisa.gov/known-exploited-vulnerabilities-catalog
57
- - NVD: https://nvd.nist.gov/
58
- - MITRE ATLAS: https://atlas.mitre.org/
59
- - MITRE ATT&CK: https://attack.mitre.org/
64
+ **Framework gap declarations.** A gap recorded as closed while it remains open
65
+ tells an organization it is covered when it is not. Changing a gap's status
66
+ requires evidence — a framework update reference and the control text it turns
67
+ on — not an assertion.
60
68
 
61
- For critical security decisions, verify CISA KEV status directly. RWEP scores are a prioritization heuristic, not a compliance instrument.
69
+ **Exploit-availability freshness.** An exploit marked not-public when it is
70
+ public understates RWEP by a fifth of the scale. `data/exploit-availability.json`
71
+ is versioned and every entry carries `last_verified`.
62
72
 
63
- ## Supply Chain
73
+ **Skill instruction correctness.** A skill that recommends a patch which does not
74
+ exist for a given kernel version, or cites the wrong ATLAS technique, does direct
75
+ harm. Skills carry a `last_threat_review` date and are re-reviewed when the CVEs
76
+ or techniques they cite change.
64
77
 
65
- This repository has no npm runtime dependencies. The library code in `lib/` is self-contained. Skills and data files are plain text/JSON.
78
+ ## Using the data
66
79
 
67
- When using these skills via an AI assistant, the skills are loaded as instruction text. No code from this repository executes in your environment beyond what your AI assistant chooses to implement.
80
+ Catalog entries and RWEP scores are analytical summaries for operational use, not
81
+ authoritative sources. Cross-reference before acting:
68
82
 
69
- ## Accuracy Disclaimer
83
+ - CISA KEV — https://www.cisa.gov/known-exploited-vulnerabilities-catalog
84
+ - NVD — https://nvd.nist.gov/
85
+ - MITRE ATLAS — https://atlas.mitre.org/
86
+ - MITRE ATT&CK — https://attack.mitre.org/
70
87
 
71
- Security threat intelligence has a short shelf life. CVE data, PoC availability status, and framework coverage assessments in this repository reflect the state of knowledge at the `last_threat_review` date in each skill's frontmatter. Verify current status with primary sources before making production security decisions.
88
+ Verify KEV status against CISA directly for critical decisions. RWEP is a
89
+ prioritization heuristic, not a compliance instrument.
72
90
 
73
- RWEP scores are analytical tools, not authoritative risk assessments. They are designed to surface prioritization signal beyond CVSS, not to replace professional security judgment.
91
+ Threat intelligence has a short shelf life. What this repository asserts reflects
92
+ the state of knowledge at each skill's `last_threat_review` date. Check the
93
+ primary source before a production decision rests on it.
@@ -1,22 +1,22 @@
1
1
  {
2
2
  "schema_version": "1.1.0",
3
- "generated_at": "2026-08-19T19:44:10.894Z",
3
+ "generated_at": "2026-08-23T07:03:41.141Z",
4
4
  "generator": "scripts/build-indexes.js",
5
5
  "source_count": 64,
6
6
  "source_hashes": {
7
- "manifest.json": "18dc296b988a016e7750d51224ba1e047c8546286f0940d70b5c134f43b71cac",
8
- "README.md": "a757b8ed9923b7954518d00a768d338800460c9a90811094f050710fe9888615",
7
+ "manifest.json": "ab7c042636d0c7d610957171d74bd4e0973d8f5718315c90488333a824444a77",
8
+ "README.md": "bc575c178c21e3d07f1491710e24b26cad3a3cee012c43641b6ea7e83468e64e",
9
9
  "data/atlas-ttps.json": "a14089671efcb4f06dd0f82d688fe49276c1370e167e4483d76e9c0a40ef41eb",
10
- "data/attack-techniques.json": "cf192b45621ce697d3b86789db58c840312c1fc13601beb58df7c747b065d08b",
11
- "data/cve-catalog.json": "5baa25c6568864484499abfd3f6016dcd2efaacfd5fdc5105a70f5a51056461e",
12
- "data/cwe-catalog.json": "7db3e297a7401c99e1bf9019e9b2eaf88e5cda97f6799e01667acab13362a746",
10
+ "data/attack-techniques.json": "2179122ff8347bc691f245d5fd2601ca81fd1d6f790feae44abca86d3c08f865",
11
+ "data/cve-catalog.json": "cac36e318f4ab524f8c578180fcedf32d2cb9a12fa541be876162975806be7cf",
12
+ "data/cwe-catalog.json": "b1e0db672d1de7cb3d36cac05059f0302b3be4f88636e6beb47d57ec0d972928",
13
13
  "data/d3fend-catalog.json": "9a4a356a1446d7db8be8b6684fa789802405a96cdaf769f06db4136bd07db6ac",
14
14
  "data/dlp-controls.json": "791f6a46b19b0c0fa2f46630ac8b398afb7ec9c2f2019056828c8820fe255f19",
15
15
  "data/exploit-availability.json": "7139702266a8d5ba8b235ab76518b8a84deaa31fdb912e81cb124121cf3e9930",
16
- "data/framework-control-gaps.json": "79cd66ea9ca6eb1e63c6647d52a28a205747d64c4cb96e61fb2bb0c057023834",
16
+ "data/framework-control-gaps.json": "5d407cd31e4cdbc34fe37253c374488158d7c15f597158930b4ac9729e666bb3",
17
17
  "data/global-frameworks.json": "20b18a851b3ab82e57cd159b49476d69fe544f02523398b2015189ab81c7c3f8",
18
18
  "data/rfc-references.json": "6e9017eca910ab7e4bee85ad7c23927fd6ec766f34be7fce49ebf020cec3381a",
19
- "data/zeroday-lessons.json": "a48c538ba1bb636fd2165768e9b045f0cf36ad23caa5fe451497a965649eaa1e",
19
+ "data/zeroday-lessons.json": "fbf03302ccf8f758f00541ce0e21b5ae6980eac8357564fe5825a09ddf0b4c18",
20
20
  "skills/kernel-lpe-triage/skill.md": "0f79c641cef6e5f4a942eb94f43c460562bf83dfb67ae112d146c39c6b320fb0",
21
21
  "skills/ai-attack-surface/skill.md": "c97335e14cd34bd1cd3c9d2cbd397f33569a07292b2f2f7721483575eb4459f7",
22
22
  "skills/mcp-agent-trust/skill.md": "6195c93a6cadb213051214742890fa2bf4e39bae377a654d4195f0c90bd8b896",
@@ -101,7 +101,7 @@
101
101
  "dlp_refs": 0
102
102
  },
103
103
  "trigger_table_entries": 688,
104
- "chains_cve_entries": 1310,
104
+ "chains_cve_entries": 1404,
105
105
  "chains_cwe_entries": 236,
106
106
  "jurisdictions_indexed": 34,
107
107
  "handoff_dag_nodes": 51,
@@ -6,20 +6,20 @@
6
6
  },
7
7
  "events": [
8
8
  {
9
- "date": "2026-08-19",
9
+ "date": "2026-08-22",
10
10
  "type": "catalog_update",
11
- "artifact": "data/attack-techniques.json",
12
- "path": "data/attack-techniques.json",
11
+ "artifact": "data/cve-catalog.json",
12
+ "path": "data/cve-catalog.json",
13
13
  "schema_version": "1.0.0",
14
- "entry_count": 794
14
+ "entry_count": 1417
15
15
  },
16
16
  {
17
17
  "date": "2026-08-19",
18
18
  "type": "catalog_update",
19
- "artifact": "data/cve-catalog.json",
20
- "path": "data/cve-catalog.json",
19
+ "artifact": "data/attack-techniques.json",
20
+ "path": "data/attack-techniques.json",
21
21
  "schema_version": "1.0.0",
22
- "entry_count": 1323
22
+ "entry_count": 794
23
23
  },
24
24
  {
25
25
  "date": "2026-08-19",
@@ -43,7 +43,7 @@
43
43
  "artifact": "data/zeroday-lessons.json",
44
44
  "path": "data/zeroday-lessons.json",
45
45
  "schema_version": "1.1.0",
46
- "entry_count": 1323
46
+ "entry_count": 1417
47
47
  },
48
48
  {
49
49
  "date": "2026-08-08",