@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,31 +1,13 @@
1
1
  'use strict';
2
2
 
3
3
  /**
4
- * Shared validation for path-component-shaped operator inputs.
4
+ * Validation for path-component-shaped operator inputs — `--session-id`,
5
+ * `--playbook`, attestation and `--evidence-dir` filenames. The one definition
6
+ * for every such site in `bin/exceptd.js`; a second copy drifts. Callers
7
+ * propagate the returned {ok, reason} pair to their emit-error path.
5
8
  *
6
- * Six sites in `bin/exceptd.js` previously hand-rolled regexes of the form
7
- * /^[A-Za-z0-9._-]{1,64}$/ for `--session-id`, `--playbook`, attestation
8
- * filenames, and `--evidence-dir` filenames. Each regex was slightly
9
- * different in character class ordering; each grew its own follow-on checks
10
- * (all-dots refusal, length cap, leading-dot refusal) at different rates.
11
- *
12
- * This module is the single source of truth. Adding a new path-component
13
- * input means calling `validateIdComponent(value, role)` and propagating
14
- * the returned {ok, reason} pair to the caller's emit-error path.
15
- *
16
- * Three role types, three character classes:
17
- * - 'session' — sessions live under `.exceptd/attestations/<sid>/`. Allow
18
- * lower+upper alpha, digit, dot, underscore, hyphen, 1-64
19
- * chars. Refuse all-dots.
20
- * - 'playbook' — playbook ids index `data/playbooks/<id>.json`. Stricter:
21
- * lowercase-only, must start with a letter, no dots (all
22
- * catalogued playbook ids match `/^[a-z][a-z0-9-]{0,63}$/`).
23
- * - 'filename' — attestation filename inside a session directory. Same
24
- * charset as 'session' but length cap reflects filename
25
- * policy (no path separators ever).
26
- *
27
- * The function never reads the filesystem; combine with realpathSync at
28
- * the caller for full path-traversal defense.
9
+ * Never reads the filesystem — pair it with realpathSync at the caller for
10
+ * full path-traversal defense.
29
11
  */
30
12
 
31
13
  const SESSION_RE = /^[A-Za-z0-9._-]{1,64}$/;
@@ -61,8 +43,7 @@ function validateIdComponent(value, role) {
61
43
  if (!re.test(value)) {
62
44
  return { ok: false, reason: `must match ${constraint}` };
63
45
  }
64
- // All-dots refusal applies after the character-class regex because the
65
- // session/filename classes admit any string of dots (`.`, `..`, `...`),
46
+ // The session/filename classes admit any string of dots (`.`, `..`, `...`),
66
47
  // each of which path-resolves into or above the intended directory.
67
48
  if (ALL_DOTS_RE.test(value)) {
68
49
  return { ok: false, reason: 'must not consist entirely of dots' };
@@ -70,10 +51,8 @@ function validateIdComponent(value, role) {
70
51
  return { ok: true };
71
52
  }
72
53
 
73
- /**
74
- * Cheap typed-throw wrapper for callers that prefer exceptions over result
75
- * objects (lib/playbook-runner.js uses this shape for loadPlaybook).
76
- */
54
+ // Throwing counterpart to validateIdComponent; the error carries
55
+ // code `EXCEPTD_INVALID_ID`.
77
56
  function assertIdComponent(value, role) {
78
57
  const r = validateIdComponent(value, role);
79
58
  if (!r.ok) {
package/lib/job-queue.js CHANGED
@@ -1,21 +1,8 @@
1
1
  "use strict";
2
2
  /**
3
- * lib/job-queue.js
4
- *
5
- * Async job queue specialized for exceptd's upstream-fetch workloads. The
6
- * generic retry semantics (HTTP + Node net classifier, exponential
7
- * backoff with crypto jitter, AbortSignal-aware sleep) live in the
8
- * vendored blamejs retry primitive — this module wraps it with the
9
- * per-source concurrency caps + token-bucket rate limits + priority
10
- * ordering specific to the KEV / EPSS / NVD / IETF / GitHub workloads.
11
- *
12
- * - per-source concurrency caps (max in-flight)
13
- * - token-bucket rate limiting (max requests per window)
14
- * - priority ordering (higher number = sooner)
15
- * - retry classification + backoff delegated to vendor/blamejs/retry.js
16
- * - per-source stats (queued / in_flight / completed / failed / retried)
17
- *
18
- * No npm deps. Node 24 stdlib + vendored retry.js.
3
+ * Async job queue for exceptd's upstream fetches: per-source concurrency caps,
4
+ * token-bucket rate limits and priority ordering (higher number runs sooner).
5
+ * Retry classification and backoff come from vendor/blamejs/retry.js.
19
6
  */
20
7
 
21
8
  const retry = require("../vendor/blamejs/retry");
@@ -36,12 +23,9 @@ class TokenBucket {
36
23
  if (add >= 1) {
37
24
  const whole = Math.floor(add);
38
25
  this.tokens = Math.min(this.capacity, this.tokens + whole);
39
- // Advance lastRefill by the time the whole tokens we just granted
40
- // consumed, NOT to `now`. Snapping to `now` discards the sub-interval
41
- // remainder (`elapsed % refillIntervalMs`), so the bucket refills
42
- // slightly slower than the configured rate and under-utilizes the
43
- // budget over many refills. Crediting only the consumed time keeps
44
- // the long-run refill rate exactly tokens/windowMs.
26
+ // Credit only the time the granted tokens consumed; snapping lastRefill
27
+ // to `now` drops the sub-interval remainder, so the bucket refills
28
+ // slower than the configured tokens/windowMs.
45
29
  this.lastRefill += whole * this.refillIntervalMs;
46
30
  }
47
31
  }
@@ -59,9 +43,8 @@ class JobQueue {
59
43
  constructor(options = {}) {
60
44
  const defaults = { concurrency: 4 };
61
45
  this.sources = options.sources || { default: defaults };
62
- // Retry options forwarded to vendored withRetry. Defaults are tighter
63
- // than withRetry's own DEFAULT_RETRY so a network blip on KEV/EPSS
64
- // doesn't stall the whole refresh by 80s.
46
+ // Forwarded to the vendored withRetry, tighter than its own defaults so a
47
+ // network blip on one source does not stall the whole refresh.
65
48
  this.retry = {
66
49
  maxAttempts: 3,
67
50
  baseDelayMs: 200,
@@ -69,9 +52,7 @@ class JobQueue {
69
52
  jitterFactor: 0.5,
70
53
  ...options.retry,
71
54
  };
72
- // Caller may override the retry classifier. Default is the vendored
73
- // blamejs classifier (HTTP 408/425/429/5xx + Node net codes), which
74
- // matches everything the upstream sources emit.
55
+ // Defaults to the vendored classifier: HTTP 408/425/429/5xx + Node net codes.
75
56
  this.isRetryable = options.isRetryable || retry.isRetryable;
76
57
  this._perSource = {};
77
58
  for (const [name, cfg] of Object.entries(this.sources)) {
@@ -88,14 +69,10 @@ class JobQueue {
88
69
  }
89
70
 
90
71
  /**
91
- * Enqueue a job.
92
- * @param {object} job
93
- * - source: source key from the sources map (default: "default")
94
- * - priority: integer; higher runs sooner within a source
95
- * - run: async () => result
96
- * - signal: optional AbortSignal forwarded to retry.withRetry sleep
97
- * - retry: per-job retry override (merged onto queue defaults)
98
- * - meta: freeform metadata attached to stats / errors
72
+ * Enqueues { source, priority, run, signal, retry, meta }. `priority` orders
73
+ * within a source, higher first; `retry` merges onto the queue defaults;
74
+ * `signal` reaches the retry sleep. Resolves with run()'s result, or rejects
75
+ * with the last error, carrying source + meta on its `queue_meta`.
99
76
  */
100
77
  add(job) {
101
78
  if (this._closed) return Promise.reject(new Error("JobQueue is closed"));