@blamejs/exceptd-skills 0.13.19 → 0.13.20
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 +41 -0
- package/data/_indexes/_meta.json +5 -5
- package/data/cve-catalog.json +301 -3792
- package/data/framework-control-gaps.json +168 -504
- package/data/zeroday-lessons.json +5 -3029
- package/lib/canonical-eq.js +88 -0
- package/lib/cve-regression-watcher.js +130 -9
- package/lib/source-advisories.js +9 -34
- package/lib/version-pins.js +73 -0
- package/lib/xml-tokenizer.js +344 -0
- package/manifest.json +44 -44
- package/package.json +2 -2
- package/sbom.cdx.json +74 -29
- package/scripts/audit-catalog-gaps.js +11 -2
- package/scripts/check-test-coverage.js +16 -18
- package/scripts/refresh-upstream-catalogs.js +13 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,46 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.13.20 — 2026-05-19
|
|
4
|
+
|
|
5
|
+
Root-cause refactor addressing every audit class surfaced by the v0.13.17–v0.13.19 self-audit (no-MVP violations, regex-where-logic-is-required, symptom patches, coincidence-pinning tests, uncaught bugs). The audit found I had been patching symptoms instead of fixing root causes; v0.13.20 fixes the actual issues and lets the audit tell the truth about catalog state.
|
|
6
|
+
|
|
7
|
+
### Features
|
|
8
|
+
|
|
9
|
+
**Real XML tokenizer replaces the regex-based RSS/Atom parser.** `lib/xml-tokenizer.js` is a proper streaming parser with CDATA handling, XML-namespace support (local-name matching), self-closing element handling, HTML-entity + numeric-character-reference decoding, and observable parse errors (the old regex parser returned `[]` silently on malformed input). `lib/source-advisories.js#parseRssAtom` now delegates to the tokenizer; the upstream contract is preserved. Failure modes the regex parser silently dropped (namespaced Atom feeds, CDATA-wrapped HTML titles, multi-line content, unterminated elements at EOF) are now explicit test cases (`tests/xml-tokenizer.test.js`).
|
|
10
|
+
|
|
11
|
+
**Canonical-form deep equality replaces JSON.stringify in diff-coverage.** `lib/canonical-eq.js` provides sorted-key recursive equality for catalog change detection. Pre-v0.13.20 the diff-coverage gate compared `JSON.stringify(before.iocs) !== JSON.stringify(after.iocs)` — non-canonical, false-positives on key-order rearrangement. The symptom was patched twice (`_auto_imported` skip in v0.13.17, `_iocs_stub` skip in v0.13.19). v0.13.20 fixes the comparator. The `_iocs_stub` skip rule is removed.
|
|
12
|
+
|
|
13
|
+
**Content-pattern matching in `lib/cve-regression-watcher.js`.** Pre-v0.13.20 the watcher fired only when a poller diff carried an explicit `CVE-YYYY-NNN` identifier. If a researcher's writeup announced "the 2020 fix is silently reverted" without typing the CVE ID, the watcher missed entirely. v0.13.20 adds three signal layers: historical-regression language patterns (`silently reverted`, `re-exploitable`, `same primitive as`), named-researcher patterns (Nightmare-Eclipse / Project Zero / Big Sleep / Forshaw / Horn / Ormandy), and tracked-component tokens (`cldflt.sys`, `HsmOsBlockPlaceholderAccess`, `ssh-keysign`, `CTFMON`). Diffs that lack a historical CVE-ID but trip the signals surface as `action: "content-only-investigate"` for operator triage.
|
|
14
|
+
|
|
15
|
+
**`forward_looking: true` schema field replaces blanket `_gap_skip` on framework-control-gaps.** v0.13.19 used per-entry `_gap_skip: { fields: ["evidence_cves"] }` on 84 framework gaps as a class-level exemption — opaque to operators reading the JSON. v0.13.20 promotes the exemption to a first-class schema field (`forward_looking: true` + `forward_looking_reason`) that the audit honors. The `_gap_skip` annotations on those 84 entries are removed in lockstep.
|
|
16
|
+
|
|
17
|
+
**`lib/version-pins.js` — single source of truth for MITRE pinned versions.** Pre-v0.13.20 the ATLAS version pin lived in 33+ files in lockstep. A bump (v5.4.0 → v5.6.0) required a regex sweep that incidentally touched dates in unrelated paragraphs. v0.13.20 reads ATLAS + ATT&CK version from `data/atlas-ttps.json._meta.atlas_version` and `data/attack-techniques.json._meta.attack_version` via the new module. Downstream tests + doc-currency checks consume through it. Future bumps refresh one JSON field; the module propagates.
|
|
18
|
+
|
|
19
|
+
**SPEC-driven refresher.** `scripts/refresh-upstream-catalogs.js` now imports the audit `SPEC.<catalog>.required_context` lists from `scripts/audit-catalog-gaps.js` instead of carrying parallel hardcoded field arrays. The v0.13.18→19 episode where the refresher backfilled `description_full` + `platforms` but forgot `description` + `tactic` (and the audit had to surface 106 ATT&CK rows still missing context) is structurally impossible now — one truth source.
|
|
20
|
+
|
|
21
|
+
**`tests/shipped-catalog-integrity.test.js` — new test file.** Splits the live-catalog assertions out of `tests/audit-catalog-gaps.test.js` (which now exercises detector logic against synthetic inputs only). Live invariants policed here: zero dangling cross-catalog refs, no `_gap_skip` stragglers on framework gaps that should be `forward_looking`, and a budget-per-catalog for missing-context findings (per-catalog snapshot count; a future PR that worsens any catalog without acknowledgement fires the test).
|
|
22
|
+
|
|
23
|
+
**`tests/refresher-fixture-roundtrip.test.js` — new test file.** Each upstream refresher gets a synthetic-fixture round-trip pin. Pre-v0.13.20 the only refresher coverage was a `typeof` check on the exported function; a refresher that regressed to "return early without writing" would have passed. Now CSAF index parsing, ATT&CK STIX shape, ICS-attack registry presence, RSS / Atom parse contract, and the canonical RFC-entry tag set are all pinned independently.
|
|
24
|
+
|
|
25
|
+
### Bugs (every audit class addressed)
|
|
26
|
+
|
|
27
|
+
**Class 1.1, 1.3 — stub fills stripped.** 291 CVE entries had stub IoCs (`"IOC list pending operator curation"`) auto-written by the v0.13.17 KEV bulk-import + v0.13.19 gap-fix passes; 252 zeroday-lessons entries had a generic `NEW-CTRL-001` baseline as their only `new_control_requirements`. Both fields stripped back to absent. The audit now reports the honest curation backlog instead of letting the catalog pass with placeholder content. Per-CVE IoC + per-primitive control curation is operator work going forward.
|
|
28
|
+
|
|
29
|
+
**Class 1.2, 5.15 — forward-looking framework gaps use a schema field.** 84 entries with `_gap_skip` converted to `forward_looking: true` + a `forward_looking_reason` prose field. The audit SPEC honors the schema field. `tests/shipped-catalog-integrity.test.js` pins that no `_gap_skip.evidence_cves` stragglers remain.
|
|
30
|
+
|
|
31
|
+
**Class 2.7 — CTFMON mapping corrected.** GreenPlasma's `attack_refs` was T1574.012 (Hijack Execution Flow: COR_PROFILER — .NET CLR profiler hijack, wrong primitive). v0.13.20 changes to T1574 base (Hijack Execution Flow) + T1068 (Exploitation for Privilege Escalation) with an `_attack_refs_correction_note` explaining the prior mapping was lazy.
|
|
32
|
+
|
|
33
|
+
**Class 4.12 — audit-test split.** `tests/audit-catalog-gaps.test.js` exercises detector logic only (synthetic inputs); `tests/shipped-catalog-integrity.test.js` carries the live-catalog assertions. A future regression to detector logic vs a future change to catalog data are now distinguishable.
|
|
34
|
+
|
|
35
|
+
**Class 5.14 — test-baseline drift investigated.** The 1028→1040 bump over 3 releases was driven by legitimate new test files (intake-coverage, regression-watcher, gap-detector, refresher-fixture, etc.), not by the gate being misused. Baseline grow-threshold convention preserved with an explanatory `notes` field in `tests/.test-count-baseline.json`.
|
|
36
|
+
|
|
37
|
+
### Internal
|
|
38
|
+
|
|
39
|
+
- `lib/canonical-eq.js`, `lib/xml-tokenizer.js`, `lib/version-pins.js` shipped under `lib/` (in the tarball file-allowlist).
|
|
40
|
+
- 5 new test files: `canonical-eq.test.js`, `xml-tokenizer.test.js`, `version-pins.test.js`, `shipped-catalog-integrity.test.js`, `refresher-fixture-roundtrip.test.js`, `refresher-spec-coupling.test.js`.
|
|
41
|
+
- `scripts/check-test-coverage.js#extractCveIocChanges` uses `canonicalEqual` for the iocs diff; the `_iocs_stub` skip rule is removed. `_auto_imported` skip rule retained (true positive — bulk-imported stub IoCs are intake-class events, not operator curation).
|
|
42
|
+
- 1377 tests / 1364 passing in this commit; remaining failures are the version + path checks fixed in the next commit hash chain.
|
|
43
|
+
|
|
3
44
|
## 0.13.19 — 2026-05-19
|
|
4
45
|
|
|
5
46
|
Automated catalog gap-detection + closure of every gap surfaced by the new detector. After the v0.13.18 bulk expansion grew six catalogs to comparable scale, the audit at T+1 day showed real holes (51 CVEs without IoCs, 120 RFCs without abstracts, 106 ATT&CK techniques without context fields, 84 framework gaps without evidence). This release ships the detector permanently and closes every hole it found.
|
package/data/_indexes/_meta.json
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema_version": "1.1.0",
|
|
3
|
-
"generated_at": "2026-05-
|
|
3
|
+
"generated_at": "2026-05-19T17:32:13.024Z",
|
|
4
4
|
"generator": "scripts/build-indexes.js",
|
|
5
5
|
"source_count": 54,
|
|
6
6
|
"source_hashes": {
|
|
7
|
-
"manifest.json": "
|
|
7
|
+
"manifest.json": "d9f9002ad675655e952674403fb030798e7ad0c98c65e6ad586960d7d7915af9",
|
|
8
8
|
"data/atlas-ttps.json": "d296c1d3e71807c9279b731f047e57796e85137f186586743a8cdad214b408f9",
|
|
9
9
|
"data/attack-techniques.json": "09bd917fe13c23d8a33f6a04978f5c89ea56ee53c8002ad357bd89cfb9ba8981",
|
|
10
|
-
"data/cve-catalog.json": "
|
|
10
|
+
"data/cve-catalog.json": "a09c83af3f9679a7ea73935726a1ff9de2cab94b4ab6321fc017fc147747d7c3",
|
|
11
11
|
"data/cwe-catalog.json": "c56e74b8c9290583b1d6fdd21b54bd65a254c58890c5f683379788ca7b080e9d",
|
|
12
12
|
"data/d3fend-catalog.json": "4271102f8c38999444bcd981c1cf5feb4ad09f8c0b1d9b79df3f1a82f4fb50f0",
|
|
13
13
|
"data/dlp-controls.json": "d2406c482dddd30e49203879999dc4b3a7fd4d0494d6a61d86b91ee76415df19",
|
|
14
14
|
"data/exploit-availability.json": "ec2656f0d9a893610e27b43eb6035fe9b18e057c9f6dfaac7e7d4959bbcbb795",
|
|
15
|
-
"data/framework-control-gaps.json": "
|
|
15
|
+
"data/framework-control-gaps.json": "b63fe398c3de068093871e8bbca11e16b6567fb15482648d0bbce06939c34104",
|
|
16
16
|
"data/global-frameworks.json": "9ba563a85f7f8d6c3c957de64945e20925a89d0ed6ea6fc561cf093811acf558",
|
|
17
17
|
"data/rfc-references.json": "926ea25892e052fc6a8b9952afc1d8e2bd06c4aec223a1a7aa79ef1dfd7b7bb5",
|
|
18
|
-
"data/zeroday-lessons.json": "
|
|
18
|
+
"data/zeroday-lessons.json": "7242a7349ac79a74813bf2b7486b6000c0c877e71cec17e2d68df33bc4007b93",
|
|
19
19
|
"skills/kernel-lpe-triage/skill.md": "08b3e9815ba481c57c80f5fc0ccbf5bb7cbb41f570c235ba6ff9596b8c07354d",
|
|
20
20
|
"skills/ai-attack-surface/skill.md": "6ff82cd5e805a29b694a71ffbeba22e78966249da921706f3256fa4319e402fc",
|
|
21
21
|
"skills/mcp-agent-trust/skill.md": "bf3ded40e84443400c9bec8634e0d6a14c9633e569d8c2e26f9d5881f8e78dff",
|