@blamejs/exceptd-skills 0.12.40 → 0.13.0
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/AGENTS.md +17 -0
- package/ARCHITECTURE.md +7 -4
- package/CHANGELOG.md +215 -248
- package/CONTEXT.md +2 -2
- package/README.md +2 -8
- package/agents/threat-researcher.md +2 -2
- package/bin/exceptd.js +179 -81
- package/data/_indexes/_meta.json +50 -50
- package/data/_indexes/activity-feed.json +1 -1
- package/data/_indexes/catalog-summaries.json +1 -1
- package/data/_indexes/chains.json +485 -13
- package/data/_indexes/frequency.json +4 -0
- package/data/_indexes/jurisdiction-map.json +15 -4
- package/data/_indexes/section-offsets.json +1224 -1224
- package/data/_indexes/token-budget.json +170 -170
- package/data/atlas-ttps.json +54 -11
- package/data/attack-techniques.json +113 -17
- package/data/cve-catalog.json +38 -52
- package/data/cwe-catalog.json +8 -2
- package/data/exploit-availability.json +1 -0
- package/data/framework-control-gaps.json +149 -6
- package/data/global-frameworks.json +1 -0
- package/data/playbooks/ai-api.json +5 -0
- package/data/playbooks/cicd-pipeline-compromise.json +970 -0
- package/data/playbooks/cloud-iam-incident.json +4 -1
- package/data/playbooks/cred-stores.json +10 -0
- package/data/playbooks/crypto-codebase.json +13 -0
- package/data/playbooks/framework.json +16 -0
- package/data/playbooks/hardening.json +4 -0
- package/data/playbooks/identity-sso-compromise.json +951 -0
- package/data/playbooks/idp-incident.json +3 -0
- package/data/playbooks/kernel.json +6 -0
- package/data/playbooks/llm-tool-use-exfil.json +963 -0
- package/data/playbooks/mcp.json +6 -0
- package/data/playbooks/runtime.json +4 -0
- package/data/playbooks/sbom.json +13 -0
- package/data/playbooks/secrets.json +6 -0
- package/data/playbooks/webhook-callback-abuse.json +916 -0
- package/data/zeroday-lessons.json +1 -0
- package/lib/cross-ref-api.js +33 -13
- package/lib/cve-curation.js +12 -1
- package/lib/exit-codes.js +29 -0
- package/lib/lint-skills.js +25 -3
- package/lib/playbook-runner.js +8 -4
- package/lib/refresh-external.js +10 -1
- package/lib/scoring.js +64 -1
- package/lib/sign.js +40 -7
- package/lib/verify.js +5 -5
- package/manifest.json +83 -83
- package/orchestrator/README.md +7 -7
- package/orchestrator/index.js +46 -25
- package/orchestrator/scheduler.js +2 -2
- package/package.json +1 -1
- package/sbom.cdx.json +135 -91
- package/scripts/check-test-coverage.js +6 -6
- package/scripts/predeploy.js +7 -13
- package/scripts/refresh-reverse-refs.js +107 -20
- package/scripts/refresh-sbom.js +21 -4
- package/skills/age-gates-child-safety/skill.md +1 -5
- package/skills/ai-attack-surface/skill.md +11 -4
- package/skills/ai-c2-detection/skill.md +11 -2
- package/skills/ai-risk-management/skill.md +4 -2
- package/skills/api-security/skill.md +7 -8
- package/skills/attack-surface-pentest/skill.md +2 -2
- package/skills/cloud-iam-incident/skill.md +1 -5
- package/skills/cloud-security/skill.md +0 -4
- package/skills/compliance-theater/skill.md +10 -2
- package/skills/container-runtime-security/skill.md +1 -3
- package/skills/dlp-gap-analysis/skill.md +3 -4
- package/skills/email-security-anti-phishing/skill.md +1 -8
- package/skills/exploit-scoring/skill.md +7 -2
- package/skills/framework-gap-analysis/skill.md +1 -1
- package/skills/fuzz-testing-strategy/skill.md +1 -2
- package/skills/global-grc/skill.md +3 -2
- package/skills/identity-assurance/skill.md +1 -3
- package/skills/idp-incident-response/skill.md +1 -4
- package/skills/incident-response-playbook/skill.md +1 -5
- package/skills/kernel-lpe-triage/skill.md +2 -2
- package/skills/mcp-agent-trust/skill.md +13 -3
- package/skills/mlops-security/skill.md +3 -4
- package/skills/ot-ics-security/skill.md +0 -3
- package/skills/policy-exception-gen/skill.md +11 -3
- package/skills/pqc-first/skill.md +4 -2
- package/skills/rag-pipeline-security/skill.md +2 -0
- package/skills/ransomware-response/skill.md +1 -5
- package/skills/researcher/skill.md +4 -3
- package/skills/sector-energy/skill.md +0 -4
- package/skills/sector-federal-government/skill.md +2 -3
- package/skills/sector-financial/skill.md +1 -4
- package/skills/sector-healthcare/skill.md +0 -5
- package/skills/sector-telecom/skill.md +0 -4
- package/skills/security-maturity-tiers/skill.md +1 -2
- package/skills/skill-update-loop/skill.md +4 -3
- package/skills/supply-chain-integrity/skill.md +4 -3
- package/skills/threat-model-currency/skill.md +1 -1
- package/skills/threat-modeling-methodology/skill.md +2 -1
- package/skills/webapp-security/skill.md +0 -5
package/orchestrator/index.js
CHANGED
|
@@ -27,6 +27,7 @@ const { dispatch, routeQuery, getSkillContext } = require('./dispatcher');
|
|
|
27
27
|
const { currencyCheck, initPipeline } = require('./pipeline');
|
|
28
28
|
const { bus, EVENT_TYPES } = require('./event-bus');
|
|
29
29
|
const { start: startScheduler, stop: stopScheduler, runCurrencyNow } = require('./scheduler');
|
|
30
|
+
const { EXIT_CODES, safeExit } = require('../lib/exit-codes');
|
|
30
31
|
|
|
31
32
|
const cmd = process.argv[2];
|
|
32
33
|
const args = process.argv.slice(3);
|
|
@@ -145,7 +146,12 @@ Examples:
|
|
|
145
146
|
exceptd framework-gap NIST-800-53 CVE-2026-31431
|
|
146
147
|
exceptd framework-gap PCI-DSS-4.0 "prompt injection"
|
|
147
148
|
exceptd framework-gap all CVE-2025-53773 --json`);
|
|
148
|
-
|
|
149
|
+
// v0.13 exit-code class fix: usage error is GENERIC_FAILURE (1),
|
|
150
|
+
// not DETECTED_ESCALATE (2). Pre-v0.13 the orchestrator emitted
|
|
151
|
+
// exit 2 for usage errors, colliding with CI gates that branch on
|
|
152
|
+
// exit 2 to mean "verb ran + detected escalation-worthy finding".
|
|
153
|
+
safeExit(EXIT_CODES.GENERIC_FAILURE);
|
|
154
|
+
return;
|
|
149
155
|
}
|
|
150
156
|
|
|
151
157
|
const root = path.join(__dirname, '..');
|
|
@@ -155,7 +161,8 @@ Examples:
|
|
|
155
161
|
cveCatalog = JSON.parse(fs.readFileSync(path.join(root, 'data', 'cve-catalog.json'), 'utf8'));
|
|
156
162
|
} catch (err) {
|
|
157
163
|
console.error(`[framework-gap] cannot read catalog: ${err.message}`);
|
|
158
|
-
|
|
164
|
+
safeExit(EXIT_CODES.GENERIC_FAILURE);
|
|
165
|
+
return;
|
|
159
166
|
}
|
|
160
167
|
|
|
161
168
|
const requested = args[0].toLowerCase() === 'all'
|
|
@@ -292,20 +299,20 @@ async function runDispatch() {
|
|
|
292
299
|
|
|
293
300
|
function runSkillContext(skillName) {
|
|
294
301
|
if (!skillName) {
|
|
295
|
-
// Cycle 20 A P2 (v0.12.40): operator-facing surface must reference
|
|
296
|
-
// the canonical `exceptd skill <name>` form, not the orchestrator
|
|
297
|
-
// path that's an implementation detail. CLAUDE.md global rule:
|
|
298
|
-
// "no internal narrative in operator-facing artifacts."
|
|
299
302
|
console.error('Usage: exceptd skill <skill-name>');
|
|
300
303
|
console.error(' (Lists available skills: exceptd brief --all)');
|
|
301
|
-
|
|
304
|
+
safeExit(EXIT_CODES.GENERIC_FAILURE);
|
|
305
|
+
return;
|
|
302
306
|
}
|
|
303
307
|
|
|
304
308
|
const context = getSkillContext(skillName);
|
|
305
309
|
if (!context) {
|
|
306
|
-
//
|
|
307
|
-
|
|
308
|
-
|
|
310
|
+
// v0.13 envelope harmonization: ok:false bodies land on stdout
|
|
311
|
+
// alongside successful results so a single consumer can parse the
|
|
312
|
+
// verb's envelope without splitting across two streams.
|
|
313
|
+
process.stdout.write(JSON.stringify({ ok: false, verb: "skill", error: `Skill not found: ${skillName}`, hint: "Run `exceptd brief --all` or check skills/ for available skill IDs." }) + "\n");
|
|
314
|
+
safeExit(EXIT_CODES.GENERIC_FAILURE);
|
|
315
|
+
return;
|
|
309
316
|
}
|
|
310
317
|
|
|
311
318
|
console.log(`Skill: ${context.skill.name} v${context.skill.version}`);
|
|
@@ -332,7 +339,7 @@ function runPipeline(triggerType, payload) {
|
|
|
332
339
|
console.log(` Agent: ${stage.agent_path}`);
|
|
333
340
|
}
|
|
334
341
|
console.log('\nTo run each stage, load the agent definition and follow its instructions:');
|
|
335
|
-
console.log('
|
|
342
|
+
console.log(' exceptd skill skill-update-loop');
|
|
336
343
|
return run;
|
|
337
344
|
}
|
|
338
345
|
|
|
@@ -368,12 +375,18 @@ async function runReport(format) {
|
|
|
368
375
|
// string. Now: reject with structured JSON error matching other verbs.
|
|
369
376
|
const VALID_REPORT_FORMATS = ['executive', 'technical', 'compliance', 'csaf'];
|
|
370
377
|
if (!VALID_REPORT_FORMATS.includes(format)) {
|
|
371
|
-
|
|
378
|
+
// v0.13 envelope harmonization: ok:false body on stdout, exit 1
|
|
379
|
+
// (GENERIC_FAILURE) not 2 (DETECTED_ESCALATE). Pre-v0.13 the
|
|
380
|
+
// body went to stderr and exit was 2; both broke CI consumers
|
|
381
|
+
// that expected the dispatch-error vs verb-finding distinction.
|
|
382
|
+
process.stdout.write(JSON.stringify({
|
|
372
383
|
ok: false,
|
|
373
|
-
error: `report: format "${format}" not in accepted set ${JSON.stringify(VALID_REPORT_FORMATS)}.`,
|
|
374
384
|
verb: 'report',
|
|
385
|
+
error: `report: format "${format}" not in accepted set ${JSON.stringify(VALID_REPORT_FORMATS)}.`,
|
|
386
|
+
accepted_formats: VALID_REPORT_FORMATS,
|
|
375
387
|
}) + '\n');
|
|
376
|
-
|
|
388
|
+
safeExit(EXIT_CODES.GENERIC_FAILURE);
|
|
389
|
+
return;
|
|
377
390
|
}
|
|
378
391
|
|
|
379
392
|
// v0.11.1 feature #55: `report csaf` emits a CSAF 2.0 envelope covering
|
|
@@ -693,7 +706,8 @@ async function runValidateCves(rawArgs = []) {
|
|
|
693
706
|
catalog = JSON.parse(fs.readFileSync(catalogPath, 'utf8'));
|
|
694
707
|
} catch (err) {
|
|
695
708
|
console.error(`[validate-cves] cannot read ${catalogPath}: ${err.message}`);
|
|
696
|
-
|
|
709
|
+
safeExit(EXIT_CODES.GENERIC_FAILURE);
|
|
710
|
+
return;
|
|
697
711
|
}
|
|
698
712
|
|
|
699
713
|
// --since <ISO|YYYY-MM-DD>: scope-limit validation to CVEs whose
|
|
@@ -863,7 +877,7 @@ async function runValidateCves(rawArgs = []) {
|
|
|
863
877
|
}
|
|
864
878
|
if (driftFound > 0) {
|
|
865
879
|
console.log(`\n[validate-cves] DRIFT DETECTED on ${driftFound} CVE(s). Update data/cve-catalog.json and bump source_verified.`);
|
|
866
|
-
if (!noFail)
|
|
880
|
+
if (!noFail) { safeExit(EXIT_CODES.GENERIC_FAILURE); return; }
|
|
867
881
|
} else {
|
|
868
882
|
console.log('[validate-cves] No drift detected against reachable sources.');
|
|
869
883
|
}
|
|
@@ -914,7 +928,8 @@ async function runValidateRfcs(rawArgs = []) {
|
|
|
914
928
|
refs = JSON.parse(fs.readFileSync(refsPath, 'utf8'));
|
|
915
929
|
} catch (err) {
|
|
916
930
|
console.error(`[validate-rfcs] cannot read ${refsPath}: ${err.message}`);
|
|
917
|
-
|
|
931
|
+
safeExit(EXIT_CODES.GENERIC_FAILURE);
|
|
932
|
+
return;
|
|
918
933
|
}
|
|
919
934
|
|
|
920
935
|
// --since <ISO|YYYY-MM-DD>: scope-limit (parity with validate-cves).
|
|
@@ -1043,7 +1058,7 @@ async function runValidateRfcs(rawArgs = []) {
|
|
|
1043
1058
|
console.log();
|
|
1044
1059
|
if (driftFound > 0) {
|
|
1045
1060
|
console.log(`[validate-rfcs] DRIFT DETECTED on ${driftFound} entry(ies). Update data/rfc-references.json and bump last_verified.`);
|
|
1046
|
-
if (!noFail)
|
|
1061
|
+
if (!noFail) { safeExit(EXIT_CODES.GENERIC_FAILURE); return; }
|
|
1047
1062
|
} else if (unreachable > 0) {
|
|
1048
1063
|
console.log(`[validate-rfcs] ${unreachable} entry(ies) unreachable. Network/IETF Datatracker is intermittent — re-run later.`);
|
|
1049
1064
|
} else if (!offline && validator) {
|
|
@@ -1078,7 +1093,8 @@ function runWatchlist(rawArgs = []) {
|
|
|
1078
1093
|
manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
|
|
1079
1094
|
} catch (err) {
|
|
1080
1095
|
console.error(`[watchlist] cannot read ${manifestPath}: ${err.message}`);
|
|
1081
|
-
|
|
1096
|
+
safeExit(EXIT_CODES.GENERIC_FAILURE);
|
|
1097
|
+
return;
|
|
1082
1098
|
}
|
|
1083
1099
|
|
|
1084
1100
|
// Exclude entries that are explicitly marked `status: "deprecated"` so
|
|
@@ -1125,7 +1141,12 @@ function runWatchlist(rawArgs = []) {
|
|
|
1125
1141
|
|
|
1126
1142
|
const jsonOut = rawArgs.includes('--json');
|
|
1127
1143
|
if (jsonOut) {
|
|
1144
|
+
// v0.13.0 envelope harmonization: top-level `ok: true` so every
|
|
1145
|
+
// verb's JSON body shares the contract whether emitted by
|
|
1146
|
+
// bin/exceptd.js emit() (which auto-defaults `ok`) or by the
|
|
1147
|
+
// orchestrator dispatch (which writes stdout directly).
|
|
1128
1148
|
const out = {
|
|
1149
|
+
ok: true,
|
|
1129
1150
|
generated_at: new Date().toISOString(),
|
|
1130
1151
|
skills_scanned: skills.length,
|
|
1131
1152
|
parse_errors: parseErrors,
|
|
@@ -1378,11 +1399,11 @@ Environment variables:
|
|
|
1378
1399
|
EXCEPTD_SCAN_TARGETS Directories to scan for MCP configs
|
|
1379
1400
|
|
|
1380
1401
|
Examples:
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1402
|
+
exceptd scan
|
|
1403
|
+
exceptd skill kernel-lpe-triage
|
|
1404
|
+
exceptd currency
|
|
1405
|
+
exceptd report executive
|
|
1406
|
+
exceptd watch
|
|
1386
1407
|
`);
|
|
1387
1408
|
}
|
|
1388
1409
|
|
|
@@ -1394,7 +1415,7 @@ Examples:
|
|
|
1394
1415
|
if (require.main === module) {
|
|
1395
1416
|
main().catch(err => {
|
|
1396
1417
|
console.error('[orchestrator] Fatal:', err.message);
|
|
1397
|
-
process.
|
|
1418
|
+
process.exitCode = 1;
|
|
1398
1419
|
});
|
|
1399
1420
|
}
|
|
1400
1421
|
|
|
@@ -277,12 +277,12 @@ function runMonthlyCveValidation() {
|
|
|
277
277
|
console.log(`[scheduler] Monthly CVE validation reminder — ${timestamp}`);
|
|
278
278
|
console.log('[scheduler] Action: Verify all data/cve-catalog.json entries against NVD and CISA KEV.');
|
|
279
279
|
console.log('[scheduler] Action: Update last_verified dates in data/exploit-availability.json.');
|
|
280
|
-
console.log('[scheduler] Run:
|
|
280
|
+
console.log('[scheduler] Run: exceptd validate-cves');
|
|
281
281
|
|
|
282
282
|
return {
|
|
283
283
|
task: 'monthly_cve_validation',
|
|
284
284
|
timestamp,
|
|
285
|
-
action: 'Run
|
|
285
|
+
action: 'Run `exceptd validate-cves` to check all CVE entries'
|
|
286
286
|
};
|
|
287
287
|
}
|
|
288
288
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blamejs/exceptd-skills",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"description": "AI security skills grounded in mid-2026 threat reality, not stale framework documentation. 42 skills, 10 catalogs, 34 jurisdictions, pre-computed indexes, Ed25519-signed.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai-security",
|