@blamejs/exceptd-skills 0.19.33 → 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 (119) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/bin/exceptd.js +896 -2824
  3. package/data/_indexes/_meta.json +2 -2
  4. package/lib/auto-discovery.js +56 -286
  5. package/lib/canonical-eq.js +7 -40
  6. package/lib/citation-resolve.js +22 -70
  7. package/lib/collectors/ai-api.js +20 -54
  8. package/lib/collectors/cicd-pipeline-compromise.js +40 -108
  9. package/lib/collectors/citation-hygiene.js +72 -210
  10. package/lib/collectors/containers.js +41 -130
  11. package/lib/collectors/cred-stores.js +31 -115
  12. package/lib/collectors/crypto-codebase.js +55 -138
  13. package/lib/collectors/crypto.js +24 -54
  14. package/lib/collectors/hardening.js +20 -78
  15. package/lib/collectors/kernel.js +16 -46
  16. package/lib/collectors/library-author.js +57 -206
  17. package/lib/collectors/mcp.js +24 -70
  18. package/lib/collectors/runtime.js +24 -86
  19. package/lib/collectors/sbom.js +34 -106
  20. package/lib/collectors/scan-excludes.js +31 -138
  21. package/lib/collectors/secrets.js +62 -178
  22. package/lib/cross-ref-api.js +39 -123
  23. package/lib/currency-severity.js +8 -27
  24. package/lib/cve-batch.js +13 -21
  25. package/lib/cve-cli.js +13 -20
  26. package/lib/cve-curation.js +72 -239
  27. package/lib/cve-regression-watcher.js +29 -152
  28. package/lib/cvss.js +13 -54
  29. package/lib/doctor-bucketing.js +3 -19
  30. package/lib/exit-codes.js +10 -42
  31. package/lib/flag-suggest.js +7 -25
  32. package/lib/framework-gap.js +35 -114
  33. package/lib/gap-detectors.js +37 -159
  34. package/lib/id-validation.js +9 -30
  35. package/lib/job-queue.js +13 -36
  36. package/lib/lint-skills.js +64 -232
  37. package/lib/playbook-runner.js +693 -2095
  38. package/lib/prefetch.js +100 -376
  39. package/lib/refresh-external.js +199 -627
  40. package/lib/refresh-network.js +75 -307
  41. package/lib/rfc-cli.js +23 -68
  42. package/lib/scoring.js +77 -145
  43. package/lib/sign.js +43 -229
  44. package/lib/source-advisories.js +43 -194
  45. package/lib/source-ghsa.js +37 -120
  46. package/lib/source-osv.js +94 -266
  47. package/lib/ttp-mapper.js +14 -24
  48. package/lib/upstream-check-cli.js +10 -28
  49. package/lib/upstream-check.js +19 -44
  50. package/lib/validate-catalog-meta.js +17 -61
  51. package/lib/validate-cve-catalog.js +43 -119
  52. package/lib/validate-indexes.js +25 -76
  53. package/lib/validate-package.js +16 -62
  54. package/lib/validate-playbooks.js +69 -275
  55. package/lib/validate-vendor.js +16 -49
  56. package/lib/verify.js +56 -286
  57. package/lib/version-pins.js +5 -34
  58. package/lib/worker-pool.js +11 -30
  59. package/lib/xml-tokenizer.js +47 -152
  60. package/manifest.json +53 -53
  61. package/orchestrator/dispatcher.js +17 -68
  62. package/orchestrator/event-bus.js +11 -74
  63. package/orchestrator/index.js +138 -412
  64. package/orchestrator/pipeline.js +28 -85
  65. package/orchestrator/scanner.js +34 -138
  66. package/orchestrator/scheduler.js +20 -84
  67. package/package.json +1 -1
  68. package/sbom.cdx.json +241 -241
  69. package/scripts/audit-catalog-gaps.js +9 -62
  70. package/scripts/audit-cross-skill.js +5 -31
  71. package/scripts/audit-perf.js +6 -16
  72. package/scripts/backfill-theater-test.js +7 -64
  73. package/scripts/bootstrap.js +12 -44
  74. package/scripts/build-indexes.js +40 -154
  75. package/scripts/builders/activity-feed.js +4 -14
  76. package/scripts/builders/catalog-summaries.js +3 -10
  77. package/scripts/builders/currency.js +7 -20
  78. package/scripts/builders/cwe-chains.js +7 -30
  79. package/scripts/builders/did-ladders.js +6 -13
  80. package/scripts/builders/frequency.js +5 -19
  81. package/scripts/builders/jurisdiction-clocks.js +6 -25
  82. package/scripts/builders/recipes.js +6 -14
  83. package/scripts/builders/section-offsets.js +13 -51
  84. package/scripts/builders/stale-content.js +7 -28
  85. package/scripts/builders/summary-cards.js +8 -29
  86. package/scripts/builders/theater-fingerprints.js +12 -27
  87. package/scripts/builders/token-budget.js +4 -31
  88. package/scripts/check-agents-md-collectors.js +11 -54
  89. package/scripts/check-catalog-gap-budget.js +15 -32
  90. package/scripts/check-changelog-extract.js +18 -48
  91. package/scripts/check-codebase-patterns-currency.js +6 -22
  92. package/scripts/check-codebase-patterns.js +50 -143
  93. package/scripts/check-epss-consistency.js +9 -64
  94. package/scripts/check-framework-gap-coverage.js +13 -31
  95. package/scripts/check-manifest-snapshot.js +13 -73
  96. package/scripts/check-sbom-currency.js +44 -142
  97. package/scripts/check-test-count.js +15 -52
  98. package/scripts/check-test-coverage.js +66 -197
  99. package/scripts/check-test-subjects.js +21 -62
  100. package/scripts/check-ttp-references.js +14 -38
  101. package/scripts/check-ttp-upstream.js +8 -40
  102. package/scripts/check-version-bump.js +9 -61
  103. package/scripts/check-version-tags.js +20 -121
  104. package/scripts/predeploy.js +38 -184
  105. package/scripts/refresh-manifest-snapshot.js +16 -38
  106. package/scripts/refresh-mitre-atlas.js +3 -8
  107. package/scripts/refresh-mitre-attack.js +1 -8
  108. package/scripts/refresh-mitre-d3fend.js +3 -9
  109. package/scripts/refresh-mitre-ics-attack.js +3 -8
  110. package/scripts/refresh-reverse-refs.js +27 -94
  111. package/scripts/refresh-rfc-index.js +2 -10
  112. package/scripts/refresh-sbom.js +31 -161
  113. package/scripts/refresh-upstream-catalogs.js +40 -137
  114. package/scripts/release.js +69 -232
  115. package/scripts/run-e2e-scenarios.js +24 -71
  116. package/scripts/sync-manifest-metadata.js +10 -34
  117. package/scripts/sync-package-description.js +8 -17
  118. package/scripts/validate-vendor-online.js +13 -44
  119. 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"));