@blamejs/exceptd-skills 0.19.32 → 0.19.34

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.
Files changed (127) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/bin/exceptd.js +896 -2824
  3. package/data/_indexes/_meta.json +8 -8
  4. package/data/_indexes/activity-feed.json +2 -2
  5. package/data/_indexes/catalog-summaries.json +7 -7
  6. package/data/_indexes/chains.json +60118 -0
  7. package/data/attack-techniques.json +267 -7
  8. package/data/cve-catalog.json +9991 -3
  9. package/data/cwe-catalog.json +109 -2
  10. package/data/framework-control-gaps.json +578 -3
  11. package/data/zeroday-lessons.json +8330 -1
  12. package/lib/auto-discovery.js +56 -286
  13. package/lib/canonical-eq.js +7 -40
  14. package/lib/citation-resolve.js +22 -70
  15. package/lib/collectors/ai-api.js +20 -54
  16. package/lib/collectors/cicd-pipeline-compromise.js +40 -108
  17. package/lib/collectors/citation-hygiene.js +72 -210
  18. package/lib/collectors/containers.js +41 -130
  19. package/lib/collectors/cred-stores.js +31 -115
  20. package/lib/collectors/crypto-codebase.js +55 -138
  21. package/lib/collectors/crypto.js +24 -54
  22. package/lib/collectors/hardening.js +20 -78
  23. package/lib/collectors/kernel.js +16 -46
  24. package/lib/collectors/library-author.js +57 -206
  25. package/lib/collectors/mcp.js +24 -70
  26. package/lib/collectors/runtime.js +24 -86
  27. package/lib/collectors/sbom.js +34 -106
  28. package/lib/collectors/scan-excludes.js +31 -138
  29. package/lib/collectors/secrets.js +62 -178
  30. package/lib/cross-ref-api.js +39 -123
  31. package/lib/currency-severity.js +8 -27
  32. package/lib/cve-batch.js +13 -21
  33. package/lib/cve-cli.js +13 -20
  34. package/lib/cve-curation.js +72 -239
  35. package/lib/cve-regression-watcher.js +29 -152
  36. package/lib/cvss.js +13 -54
  37. package/lib/doctor-bucketing.js +3 -19
  38. package/lib/exit-codes.js +10 -42
  39. package/lib/flag-suggest.js +7 -25
  40. package/lib/framework-gap.js +35 -114
  41. package/lib/gap-detectors.js +37 -159
  42. package/lib/id-validation.js +9 -30
  43. package/lib/job-queue.js +13 -36
  44. package/lib/lint-skills.js +64 -232
  45. package/lib/playbook-runner.js +693 -2095
  46. package/lib/prefetch.js +100 -376
  47. package/lib/refresh-external.js +199 -627
  48. package/lib/refresh-network.js +75 -307
  49. package/lib/rfc-cli.js +23 -68
  50. package/lib/scoring.js +77 -145
  51. package/lib/sign.js +43 -229
  52. package/lib/source-advisories.js +43 -194
  53. package/lib/source-ghsa.js +37 -120
  54. package/lib/source-osv.js +94 -266
  55. package/lib/ttp-mapper.js +14 -24
  56. package/lib/upstream-check-cli.js +10 -28
  57. package/lib/upstream-check.js +19 -44
  58. package/lib/validate-catalog-meta.js +17 -61
  59. package/lib/validate-cve-catalog.js +43 -119
  60. package/lib/validate-indexes.js +25 -76
  61. package/lib/validate-package.js +16 -62
  62. package/lib/validate-playbooks.js +69 -275
  63. package/lib/validate-vendor.js +16 -49
  64. package/lib/verify.js +56 -286
  65. package/lib/version-pins.js +5 -34
  66. package/lib/worker-pool.js +11 -30
  67. package/lib/xml-tokenizer.js +47 -152
  68. package/manifest.json +53 -53
  69. package/orchestrator/dispatcher.js +17 -68
  70. package/orchestrator/event-bus.js +11 -74
  71. package/orchestrator/index.js +138 -412
  72. package/orchestrator/pipeline.js +28 -85
  73. package/orchestrator/scanner.js +34 -138
  74. package/orchestrator/scheduler.js +20 -84
  75. package/package.json +2 -2
  76. package/sbom.cdx.json +253 -253
  77. package/scripts/audit-catalog-gaps.js +9 -62
  78. package/scripts/audit-cross-skill.js +5 -31
  79. package/scripts/audit-perf.js +6 -16
  80. package/scripts/backfill-theater-test.js +7 -64
  81. package/scripts/bootstrap.js +12 -44
  82. package/scripts/build-indexes.js +40 -154
  83. package/scripts/builders/activity-feed.js +4 -14
  84. package/scripts/builders/catalog-summaries.js +3 -10
  85. package/scripts/builders/currency.js +7 -20
  86. package/scripts/builders/cwe-chains.js +7 -30
  87. package/scripts/builders/did-ladders.js +6 -13
  88. package/scripts/builders/frequency.js +5 -19
  89. package/scripts/builders/jurisdiction-clocks.js +6 -25
  90. package/scripts/builders/recipes.js +6 -14
  91. package/scripts/builders/section-offsets.js +13 -51
  92. package/scripts/builders/stale-content.js +7 -28
  93. package/scripts/builders/summary-cards.js +8 -29
  94. package/scripts/builders/theater-fingerprints.js +12 -27
  95. package/scripts/builders/token-budget.js +4 -31
  96. package/scripts/check-agents-md-collectors.js +11 -54
  97. package/scripts/check-catalog-gap-budget.js +15 -32
  98. package/scripts/check-changelog-extract.js +18 -48
  99. package/scripts/check-codebase-patterns-currency.js +6 -22
  100. package/scripts/check-codebase-patterns.js +50 -143
  101. package/scripts/check-epss-consistency.js +9 -64
  102. package/scripts/check-framework-gap-coverage.js +13 -31
  103. package/scripts/check-manifest-snapshot.js +13 -73
  104. package/scripts/check-sbom-currency.js +44 -142
  105. package/scripts/check-test-count.js +15 -52
  106. package/scripts/check-test-coverage.js +66 -197
  107. package/scripts/check-test-subjects.js +21 -62
  108. package/scripts/check-ttp-references.js +14 -38
  109. package/scripts/check-ttp-upstream.js +8 -40
  110. package/scripts/check-version-bump.js +9 -61
  111. package/scripts/check-version-tags.js +20 -121
  112. package/scripts/predeploy.js +38 -184
  113. package/scripts/refresh-manifest-snapshot.js +16 -38
  114. package/scripts/refresh-mitre-atlas.js +3 -8
  115. package/scripts/refresh-mitre-attack.js +1 -8
  116. package/scripts/refresh-mitre-d3fend.js +3 -9
  117. package/scripts/refresh-mitre-ics-attack.js +3 -8
  118. package/scripts/refresh-reverse-refs.js +27 -94
  119. package/scripts/refresh-rfc-index.js +2 -10
  120. package/scripts/refresh-sbom.js +31 -161
  121. package/scripts/refresh-upstream-catalogs.js +40 -137
  122. package/scripts/release.js +69 -232
  123. package/scripts/run-e2e-scenarios.js +24 -71
  124. package/scripts/sync-manifest-metadata.js +10 -34
  125. package/scripts/sync-package-description.js +8 -17
  126. package/scripts/validate-vendor-online.js +13 -44
  127. package/scripts/verify-shipped-tarball.js +35 -140
@@ -1,20 +1,9 @@
1
1
  "use strict";
2
2
  /**
3
- * lib/validate-package.js
4
- *
5
- * Predeploy + prepublishOnly gate. Runs `npm pack --dry-run --json` and
6
- * asserts the publish tarball is what we expect:
7
- *
8
- * - includes every required file from package.json `files`
9
- * - excludes every forbidden file (secrets, tests, caches, dev artifacts)
10
- * - is under the size budget (SIZE_BUDGET_BYTES below — do not restate the
11
- * figure here; this line said 7 MB through three raises of it)
12
- * - `bin/exceptd.js` has the expected shebang
13
- * - the bin target listed in package.json exists on disk
14
- *
15
- * Exit 0 on success, 1 on any violation.
16
- *
17
- * Zero npm deps. Node 24 stdlib.
3
+ * Predeploy + prepublishOnly gate: runs `npm pack --dry-run --json` and asserts
4
+ * the publish tarball holds every required file, no forbidden one, a bin target
5
+ * that exists and carries a shebang, and a size under SIZE_BUDGET_BYTES — never
6
+ * restated in prose, which goes stale at every raise of it.
18
7
  */
19
8
 
20
9
  const fs = require("fs");
@@ -24,22 +13,8 @@ const { safeExit } = require("./exit-codes");
24
13
 
25
14
  const ROOT = path.join(__dirname, "..");
26
15
  const ABS = (p) => path.join(ROOT, p);
27
- // Published-tarball cap. Guards against accidental bloat (a vendored
28
- // node_modules, a committed binary — tens of MB), not the curated data that
29
- // legitimately grows each release: the CVE catalog gains entries and the RFC
30
- // index spans the full series. Packed size crossed 5 MB through that gradual
31
- // growth; 7 MB restored headroom. Completing five-jurisdiction framework-gap
32
- // coverage across the whole catalog added ~1,100 curated statements plus their
33
- // reverse-reference index, crossing 7 MB; 8 MB restored headroom. Curating a
34
- // further hundred KEV CVEs — each with its indicators, five framework-gap
35
- // statements and a paired zero-day lesson — crossed 8 MB; 9 MB restored
36
- // headroom. Recording the controls each CVE requires, across most of the
37
- // catalog, adds several hundred words per entry and crossed 9 MB; 11 MB
38
- // restores headroom through the remainder of that work while still catching a
39
- // gross-bloat accident. Two further hundred-CVE curation passes took the
40
- // catalog past 1,300 entries and crossed 11 MB; 13 MB restores headroom for
41
- // roughly two more passes at the current per-entry size, which is where the
42
- // next deliberate look at what ships in the tarball belongs.
16
+ // Sized to catch a gross-bloat accident — a vendored node_modules, a committed
17
+ // binary — not the curated data that legitimately grows each release.
43
18
  const SIZE_BUDGET_BYTES = 13 * 1024 * 1024;
44
19
 
45
20
  const REQUIRED_PATHS = [
@@ -52,10 +27,7 @@ const REQUIRED_PATHS = [
52
27
  "manifest-snapshot.json",
53
28
  "sbom.cdx.json",
54
29
  "bin/exceptd.js",
55
- // Modules require()d at the top of bin/exceptd.js on every invocation —
56
- // dropping any of these from the tarball bricks the CLI at launch with a
57
- // module-not-found, so they are pinned explicitly rather than relied on via
58
- // the directory-level files[] entries.
30
+ // require()d at the top of bin/exceptd.js: dropping one bricks the CLI at launch.
59
31
  "lib/exit-codes.js",
60
32
  "lib/id-validation.js",
61
33
  "lib/flag-suggest.js",
@@ -91,8 +63,7 @@ const FORBIDDEN_PATTERNS = [
91
63
  const PEM_ALLOWLIST = new Set(["keys/public.pem"]);
92
64
 
93
65
  function runNpmPack() {
94
- // `npm pack --dry-run --json` writes a JSON array to stdout describing
95
- // what would be in the tarball without actually creating it.
66
+ // --dry-run --json describes the tarball on stdout without creating it.
96
67
  const res = spawnSync("npm", ["pack", "--dry-run", "--json"], { cwd: ROOT, encoding: "utf8", shell: process.platform === "win32" });
97
68
  if (res.status !== 0) {
98
69
  process.stderr.write(`[validate-package] npm pack failed (exit ${res.status}): ${res.stderr || res.stdout}\n`);
@@ -113,20 +84,12 @@ function runNpmPack() {
113
84
  return first;
114
85
  }
115
86
 
116
- /* SBOM coverage of the ACTUAL tarball.
117
- *
118
- * The SBOM's own completeness gate expands package.json `files`, but npm ships
119
- * more than `files` names — package.json unconditionally, plus README files it
120
- * collects itself. Those extras shipped unhashed and nothing noticed, because
121
- * the generator and its checker both asked `files`: two sides agreeing on the
122
- * same incomplete question. `npm pack` is the only authority on what actually
123
- * ships, and this is the one gate holding its output, so the comparison belongs
124
- * here.
125
- *
126
- * Exclusions are read from the SBOM's own declared properties instead of a
127
- * second copy of the list, so a file can only be uncovered when the published
128
- * artifact says out loud that it is. The single structural exception is the
129
- * SBOM itself, which cannot contain its own hash.
87
+ /* SBOM coverage of the ACTUAL tarball. The SBOM's own completeness gate expands
88
+ * package.json `files`, but npm ships more than that, so a generator and its
89
+ * checker can agree on the same incomplete question; `npm pack` is the only
90
+ * authority on what ships. Exclusions come from the SBOM's own declared
91
+ * properties rather than a second copy of the list; the structural exception is
92
+ * the SBOM, which cannot hash itself.
130
93
  */
131
94
  function sbomCoverageIssues(filePaths, sbom) {
132
95
  const props = (sbom && sbom.metadata && sbom.metadata.properties) || [];
@@ -159,7 +122,6 @@ function main() {
159
122
 
160
123
  const pkg = JSON.parse(fs.readFileSync(ABS("package.json"), "utf8"));
161
124
 
162
- // package.json sanity
163
125
  if (pkg.private === true) issues.push(`package.json "private" is true — npm publish will fail`);
164
126
  if (!pkg.bin || !pkg.bin.exceptd) issues.push(`package.json missing bin.exceptd`);
165
127
  if (!Array.isArray(pkg.files) || pkg.files.length === 0) issues.push(`package.json missing files[] whitelist`);
@@ -167,7 +129,6 @@ function main() {
167
129
  issues.push(`package.json missing publishConfig.access: public (scoped package needs explicit access)`);
168
130
  }
169
131
 
170
- // bin target exists + has a shebang
171
132
  if (pkg.bin && pkg.bin.exceptd) {
172
133
  const binPath = ABS(pkg.bin.exceptd);
173
134
  if (!fs.existsSync(binPath)) {
@@ -180,19 +141,16 @@ function main() {
180
141
  }
181
142
  }
182
143
 
183
- // npm pack dry-run
184
144
  const packInfo = runNpmPack();
185
145
  const filePaths = packInfo.files.map((f) => f.path.replace(/\\/g, "/"));
186
146
  const fileSet = new Set(filePaths);
187
147
 
188
- // Required files present
189
148
  for (const r of REQUIRED_PATHS) {
190
149
  if (!fileSet.has(r)) {
191
150
  issues.push(`required file missing from publish tarball: ${r}`);
192
151
  }
193
152
  }
194
153
 
195
- // Forbidden files absent
196
154
  for (const p of filePaths) {
197
155
  if (PEM_ALLOWLIST.has(p)) continue;
198
156
  for (const re of FORBIDDEN_PATTERNS) {
@@ -210,12 +168,8 @@ function main() {
210
168
  issues.push(`could not read sbom.cdx.json to check tarball coverage: ${err.message}`);
211
169
  }
212
170
 
213
- // Size budget. An absent/non-numeric `size` field is NOT a pass — it means
214
- // the gate cannot evaluate the budget at all. Fail loudly instead of
215
- // silently skipping (the absent-field-fails-open class, symmetric with the
216
- // license_sha256 / vendored_sha256 guards in validate-vendor.js): a future
217
- // npm-pack output shape change that drops or renames `size` must not turn the
218
- // size budget into a no-op.
171
+ // An absent or non-numeric `size` is a failure, not a pass: a change in npm
172
+ // pack's output shape must not turn the budget into a silent no-op.
219
173
  if (typeof packInfo.size !== "number") {
220
174
  issues.push(`npm pack output missing numeric size — cannot enforce size budget`);
221
175
  } else if (packInfo.size > SIZE_BUDGET_BYTES) {