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