@blamejs/exceptd-skills 0.12.41 → 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/CHANGELOG.md +91 -0
- package/bin/exceptd.js +52 -44
- package/data/_indexes/_meta.json +47 -47
- package/data/_indexes/chains.json +485 -13
- package/data/_indexes/jurisdiction-map.json +15 -4
- package/data/_indexes/section-offsets.json +1244 -1244
- package/data/_indexes/token-budget.json +173 -173
- package/data/atlas-ttps.json +54 -11
- package/data/attack-techniques.json +113 -17
- package/data/cve-catalog.json +17 -24
- package/data/cwe-catalog.json +8 -2
- package/data/framework-control-gaps.json +13 -3
- 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/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/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 +24 -2
- package/lib/refresh-external.js +10 -1
- package/lib/scoring.js +55 -0
- package/manifest.json +83 -83
- package/orchestrator/index.js +32 -24
- package/package.json +1 -1
- package/sbom.cdx.json +122 -78
- package/scripts/predeploy.js +7 -13
- package/scripts/refresh-reverse-refs.js +86 -0
- 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 +2 -3
- 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/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,96 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.13.0 — 2026-05-17
|
|
4
|
+
|
|
5
|
+
Minor release. Breaking-change bundle for the v0.10.x legacy-verb removal that has been deprecation-bannered since v0.11.0; envelope harmonization across every JSON-emitting verb; 4 new playbooks expanding the canonical set to 20; engine hardening (factor-shape validation, cache invalidation, fsync-on-rename, deterministic SBOM); schema reverse fields on ATLAS, ATT&CK, and the playbook chain.
|
|
6
|
+
|
|
7
|
+
### Breaking changes — migration required
|
|
8
|
+
|
|
9
|
+
**Five v0.10.x legacy verbs hard-removed: `plan`, `govern`, `direct`, `look`, `ingest`.** They were deprecation-bannered since v0.11.0 and slated-for-removal-in-v0.13 since v0.12.0. Operators on v0.10.x → v0.13.0 now get a structured `ok:false` refusal with the v0.11+ replacement command. Each removal is a pure rename — same underlying capability is reachable via the replacement. Refusal body shape:
|
|
10
|
+
|
|
11
|
+
```json
|
|
12
|
+
{
|
|
13
|
+
"ok": false,
|
|
14
|
+
"error": "'plan' was removed in v0.13.0. Use `exceptd brief --all` instead.",
|
|
15
|
+
"verb": "plan",
|
|
16
|
+
"removed_in": "0.13.0",
|
|
17
|
+
"replacement": "brief --all",
|
|
18
|
+
"deprecation_history": "Deprecated in v0.11.0 ... removed in v0.13.0."
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Replacements:
|
|
23
|
+
- `exceptd plan` → `exceptd brief --all`
|
|
24
|
+
- `exceptd govern <pb>` → `exceptd brief <pb> --phase govern`
|
|
25
|
+
- `exceptd direct <pb>` → `exceptd brief <pb> --phase direct`
|
|
26
|
+
- `exceptd look <pb>` → `exceptd brief <pb> --phase look`
|
|
27
|
+
- `exceptd ingest <args>` → `exceptd run <args>`
|
|
28
|
+
|
|
29
|
+
`reattest` and `list-attestations` were also deprecation-bannered but are PRESERVED — they remain canonical short-form routings of `attest diff` / `attest list` and stay functional.
|
|
30
|
+
|
|
31
|
+
The deprecation-banner + tempdir-marker mechanism (added v0.11.0, persisted via `EXCEPTD_DEPRECATION_SHOWN` env var + `exceptd-deprecation-shown-v<X.Y.Z>` tempdir marker) is removed. Pre-v0.13 scripts that pinned the banner shape should remove those assertions.
|
|
32
|
+
|
|
33
|
+
**Orchestrator exit-code class change: usage errors exit 1 (`GENERIC_FAILURE`), not 2 (`DETECTED_ESCALATE`).** Affected verbs: `framework-gap` (missing args), `report <format>` (unknown format), `validate-cves` / `validate-rfcs` (catalog-read failure), `watchlist` (manifest-read failure), `skill <name>` (skill-not-found). Pre-v0.13 these exited 2, colliding with the canonical CI contract where exit 2 means "verb ran and detected an escalation-worthy finding." CI gates wired to branch on exit 2 will need to also accept exit 1 for these verbs, OR pre-validate inputs before invocation.
|
|
34
|
+
|
|
35
|
+
**Envelope harmonization: every JSON-emitting verb now carries top-level `ok` and (where applicable) `verb`.** Pre-v0.13 `brief --all`, `watchlist`, `ci`, `doctor`, `discover`, `attest show`, `attest export`, and `cmdRunMulti` omitted one or both fields inconsistently. `emit()` now defaults `ok: true` when not set (symmetric to the existing `ok: false → exit 1` fallback), and per-verb call sites set `verb: "..."` explicitly. Consumers that parsed bodies for the absence of these fields will break; consumers reading specific known fields are unaffected.
|
|
36
|
+
|
|
37
|
+
**Orchestrator `ok:false` bodies now land on stdout (not stderr).** Aligns with the bin/exceptd.js convention so a single consumer can parse the verb's envelope without splitting across two streams. Advisory text (`[verb] hint: ...`) still goes to stderr.
|
|
38
|
+
|
|
39
|
+
### Security
|
|
40
|
+
|
|
41
|
+
**`lib/sign.js` `generateKeypair()` ACL-hardening status surfaces in CLI output.** `restrictWindowsAcl()` now returns a boolean; the verdict line announces `Windows ACL hardened: yes|NO` rather than silently warning.
|
|
42
|
+
|
|
43
|
+
**`lib/cve-curation.js` + `lib/refresh-external.js` `writeJsonAtomic()` fsync before rename.** Pre-v0.13 a power loss between the tmp-write and the rename could leave the renamed destination zero-length / partial. The open + write + fsync + close + rename idiom closes the durability gap on both atomic-write helpers.
|
|
44
|
+
|
|
45
|
+
### Features
|
|
46
|
+
|
|
47
|
+
**4 new playbooks expand the canonical set to 20.**
|
|
48
|
+
- `webhook-callback-abuse` — OAuth callback hijack, inbound-webhook signature validation, Slack/Teams/Discord webhook leakage, the Snowflake-class long-lived-callback-token-in-CI-log pattern.
|
|
49
|
+
- `cicd-pipeline-compromise` — self-hosted runner takeover, workflow-injection (the `${{ inputs.* }}` class), third-party Action SHA-pin discipline, OIDC trust-policy abuse, runner-scoped signing keys. Distinct from `sbom` (package-registry supply chain).
|
|
50
|
+
- `identity-sso-compromise` — in-progress IdP-plane detection (Salt Typhoon / Scattered Spider / Okta-2023 / golden-SAML / PRT theft patterns). Detect-side counterpart to the existing `idp-incident` (response playbook).
|
|
51
|
+
- `llm-tool-use-exfil` — agentic-AI tool abuse via prompt injection. Auto-approve-on-high-impact-tool, instruction-coercion grammar in tool responses, unprompted tool chains, credential-shadow in tool args. Distinct from `dlp-exfiltration` (enterprise DLP) and `mcp` (install-time tool trust).
|
|
52
|
+
|
|
53
|
+
Each new playbook carries `threat_currency_score >= 90`, full air-gap alternatives on look artifacts, substantive theater_test blocks on framework gaps, and `feeds_into[]` chains into the existing playbook set.
|
|
54
|
+
|
|
55
|
+
**Schema reverse fields populated across 3 catalogs + playbooks.**
|
|
56
|
+
- ATLAS TTPs now carry `cve_refs[]` (11 entries populated with 21 back-edges from `cve.atlas_refs`).
|
|
57
|
+
- ATT&CK techniques now carry `cve_refs[]` (20 entries populated with 56 back-edges from `cve.attack_refs`).
|
|
58
|
+
- Every playbook now carries `_meta.fed_by[]` (11 playbooks populated with 54 back-edges from `_meta.feeds_into[].playbook_id`). Operators reading a playbook can see what chains INTO it without grepping every other playbook.
|
|
59
|
+
|
|
60
|
+
`scripts/refresh-reverse-refs.js` extends to 8 reverse-direction passes (4 manifest-driven, 2 CVE-driven, 2 catalog-back-edge, 1 playbook-back-edge); `npm run refresh-reverse-refs` rebuilds the full set in one pass.
|
|
61
|
+
|
|
62
|
+
**`lib/scoring.js validate()` refuses mixed Shape A / Shape B factor sets.** The catalog historically stored `rwep_factors` in two distinct shapes (raw booleans + post-weight integers). Mixing shapes inside one entry silently broke the sum invariant — a CVE with `cisa_kev: true, blast_radius: 30` reported rwep 30 instead of the operator-intended 55. The new `detectFactorShape()` helper detects mixed entries and emits a structured error pointing at the affected CVE id.
|
|
63
|
+
|
|
64
|
+
**`lib/cross-ref-api.js` cache invalidation uses (mtime, size) tier.** Pre-v0.13 cache invalidation was mtime-only; on filesystems with 1-2s mtime granularity (FAT32, HFS+ pre-APFS, NFSv3, Docker bind-mounts that proxy mtime) a rapid refresh-then-reload within the same second served stale data. Adding `size` catches every content change that affects byte count.
|
|
65
|
+
|
|
66
|
+
**`lib/lint-skills.js` enforces `last_threat_review` staleness gate.** Warn at >180 days; hard fail at >365 days. Operators with stale skills get a structured warning naming the affected file + the exact day count; year-stale skills fail the lint outright. The forcing function for Hard Rule #8 (which was policy-only pre-v0.13).
|
|
67
|
+
|
|
68
|
+
**`scripts/refresh-sbom.js` produces a deterministic bundle.** `metadata.timestamp` and `serialNumber` are derived from the content-hash seed (`<name>@<version>@<bundleSha>`) instead of wall-clock. Identical content → identical SBOM across re-runs. The SBOM-currency predeploy gate can now rely on byte-identity for the no-change case.
|
|
69
|
+
|
|
70
|
+
**`exceptd doctor --fix` second remediation branch: post-rotate stale signatures.** Continues the v0.12.41 fix. When the private key IS present but the signatures check fails (the `generate-keypair --rotate` followup state), `doctor --fix` runs `sign-all` to re-sign skills + manifest against the current keypair. Without this branch the rotation flow would converge to a broken-but-not-self-healing state.
|
|
71
|
+
|
|
72
|
+
### Bugs
|
|
73
|
+
|
|
74
|
+
**3 catalogs got `last_threat_review` fields backfilled.** `exploit-availability.json`, `global-frameworks.json`, `zeroday-lessons.json` carried `last_updated` but lacked the threat-review timestamp the other 8 catalogs use. All 11 now follow the same shape.
|
|
75
|
+
|
|
76
|
+
**`active_exploitation` field vocabulary now declared in `cve-catalog.json._meta`.** Pre-v0.13 the field accepted free-form values; 10 entries used `"unknown"` which wasn't documented. The new `_meta.active_exploitation_vocabulary` block enumerates `confirmed | suspected | theoretical | none | unknown` with per-value definitions.
|
|
77
|
+
|
|
78
|
+
**4 CVEs flipped `_draft: false` (verified).** `CVE-2024-3094` (xz-utils backdoor), `CVE-2024-21626` (Leaky Vessels), `CVE-2026-42945` (NGINX Rift), `MAL-2026-TANSTACK-MINI`. 1 quarantined (`MAL-2026-ANTHROPIC-MCP-STDIO` — duplicate of `CVE-2026-30623`). The remaining 15 draft CVEs are now marked with a structured `_draft_reason` ("blocked on missing zeroday-lessons entry" in all 14 cases except the GTIG embargoed placeholder).
|
|
79
|
+
|
|
80
|
+
**Hard Rule #5 regional-framework backfill on 7 skills.** `policy-exception-gen`, `compliance-theater`, `exploit-scoring`, `ai-c2-detection`, `ai-attack-surface`, `mcp-agent-trust`, `api-security` previously cited NIST without one or more of EU/UK/AU/ISO equivalents. Each now carries substantive references to NIS2/DORA/EU AI Act, NCSC CAF, ASD ISM/Essential 8, and ISO 27001:2022 controls as appropriate.
|
|
81
|
+
|
|
82
|
+
**39 of 42 skills got `data_deps` arrays regenerated** from body content references. Pre-v0.13 the array drifted whenever a skill body added or removed a `data/<file>.json` reference without the frontmatter being updated. `api-security` and `email-security-anti-phishing` ended up with empty `data_deps` — their bodies reference no catalog file by name; flagged for v0.14 body-content review.
|
|
83
|
+
|
|
84
|
+
**`scripts/refresh-reverse-refs.js` orphan detection caught 8 framework-gap forward-orphan references introduced by the Hard Rule #5 backfill.** `NIST-800-53-SC-39`, `ISO-27001-2022-A.8.22`, `CIS-Kubernetes-Benchmark-5.7`, `NIST-800-218-SSDF-PW.4`, `NIST-800-53-SR-3`, `SLSA-v1.0-Source-L3`, `NIST-AI-RMF-MAP-3.4`, `OWASP-Top-10-2021-A06`. These are real framework controls cited by the new skill content but absent from the gap catalog; tracked for v0.14 gap-catalog expansion.
|
|
85
|
+
|
|
86
|
+
### Internal
|
|
87
|
+
|
|
88
|
+
- `lib/exit-codes.js` exports `safeExit(code)` — sets `process.exitCode` without calling `process.exit()`. Dispatch surface (`bin/exceptd.js`, `orchestrator/index.js`) converted from `process.exit(N)` to `safeExit(EXIT_CODES.X)` for non-zero codes; `tests/safe-exit-grep.test.js` refuses regressions.
|
|
89
|
+
- `validate-playbooks` predeploy gate flipped from informational to required. 20/20 playbooks validate cleanly.
|
|
90
|
+
- 7 new pinning tests in `tests/v0_12_41-fixes.test.js`, `tests/safe-exit-grep.test.js`, `tests/atlas-version-canonical.test.js`, `tests/operator-leak-grep.test.js`, `tests/verify-shipped-tarball-wrapper.test.js`.
|
|
91
|
+
- Test suite: 1179 total, 1173 pass, 6 skipped (POSIX-only / no-privkey gates), 0 fail.
|
|
92
|
+
- `release.yml` publish-job split (id-token:write vs contents:write separation) and `refresh.yml` split-checkout pattern remain in v0.14 backlog; they're workflow-security hardening with no operator-facing surface change.
|
|
93
|
+
|
|
3
94
|
## 0.12.41 — 2026-05-17
|
|
4
95
|
|
|
5
96
|
Cross-domain hygiene pass: signature-regression class fix, sidecar hardening, attestation UX, ATLAS pin reconciliation, operator-narrative scrub, and structural test pins to lock the class fixes against future drift.
|
package/bin/exceptd.js
CHANGED
|
@@ -207,31 +207,46 @@ function suggestVerb(cmd, known) {
|
|
|
207
207
|
// v0.11.0 introduces: brief (collapses plan/govern/direct/look), discover (scan + dispatch),
|
|
208
208
|
// doctor (currency + verify + validate-cves + validate-rfcs), ci (CI gate),
|
|
209
209
|
// ai-run (streaming JSONL), ask (plain-English routing).
|
|
210
|
+
//
|
|
211
|
+
// v0.13.0 removed the v0.10.x phase-name aliases (plan, govern, direct,
|
|
212
|
+
// look, ingest). They were deprecation-bannered since v0.11.0 and
|
|
213
|
+
// slated-for-removal-in-v0.13 since v0.12.0; v0.13 honors that contract.
|
|
214
|
+
// REMOVED_VERBS below carries the rename map for operator-facing refusal
|
|
215
|
+
// hints. `reattest` and `list-attestations` are preserved as canonical
|
|
216
|
+
// routings — they're short forms of `attest diff` / `attest list` that
|
|
217
|
+
// remain operationally useful and have substantial test coverage.
|
|
210
218
|
const PLAYBOOK_VERBS = new Set([
|
|
211
|
-
// v0.11.0 canonical surface:
|
|
212
219
|
"brief", "run", "ai-run", "attest", "discover", "doctor", "ci", "ask",
|
|
213
220
|
"verify-attestation", "run-all", "lint",
|
|
214
|
-
|
|
215
|
-
"plan", "govern", "direct", "look", "ingest", "reattest", "list-attestations",
|
|
221
|
+
"reattest", "list-attestations",
|
|
216
222
|
]);
|
|
217
223
|
|
|
218
|
-
//
|
|
219
|
-
//
|
|
220
|
-
|
|
224
|
+
// v0.13.0: hard-removed legacy verbs. The dispatcher refuses the verb
|
|
225
|
+
// with an actionable replacement hint instead of routing it. Pre-v0.13
|
|
226
|
+
// these were soft-deprecated (banner + still functional); v0.13 removes
|
|
227
|
+
// the routing entirely. Operators upgrading from v0.10.x → v0.13 see
|
|
228
|
+
// the same hint that the deprecation banner previously surfaced, but
|
|
229
|
+
// non-zero exit so scripts noticing pinned-name use fail loudly instead
|
|
230
|
+
// of silently invoking the alias.
|
|
231
|
+
const REMOVED_VERBS = {
|
|
221
232
|
plan: "brief --all",
|
|
222
233
|
govern: "brief <pb> --phase govern",
|
|
223
234
|
direct: "brief <pb> --phase direct",
|
|
224
235
|
look: "brief <pb> --phase look",
|
|
225
236
|
ingest: "run",
|
|
226
|
-
|
|
227
|
-
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
// Renamed but functionally-routed verbs (orchestrator-side dispatch still
|
|
240
|
+
// handles them as of v0.13). Distinct from REMOVED_VERBS — these aren't
|
|
241
|
+
// refused; they're just a soft hint that the rename happened. No banner
|
|
242
|
+
// is emitted post-v0.13.
|
|
243
|
+
const RENAMED_VERBS_HINT = {
|
|
228
244
|
scan: "discover --scan-only",
|
|
229
245
|
dispatch: "discover",
|
|
230
246
|
currency: "doctor --currency",
|
|
231
247
|
verify: "doctor --signatures",
|
|
232
248
|
"validate-cves": "doctor --cves",
|
|
233
249
|
"validate-rfcs": "doctor --rfcs",
|
|
234
|
-
watchlist: "watch",
|
|
235
250
|
prefetch: "refresh --no-network",
|
|
236
251
|
"build-indexes": "refresh --indexes-only",
|
|
237
252
|
};
|
|
@@ -498,40 +513,23 @@ function main() {
|
|
|
498
513
|
process.exit(0);
|
|
499
514
|
}
|
|
500
515
|
|
|
501
|
-
// v0.
|
|
502
|
-
//
|
|
503
|
-
//
|
|
504
|
-
//
|
|
505
|
-
//
|
|
506
|
-
//
|
|
507
|
-
if (
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
const markerFile = path.join(markerDir, `exceptd-deprecation-shown-v${ver}`);
|
|
519
|
-
let alreadyShown = false;
|
|
520
|
-
try { alreadyShown = fs.existsSync(markerFile); } catch { /* tmpdir unwritable; degrade to per-process */ }
|
|
521
|
-
if (!alreadyShown) {
|
|
522
|
-
const haveBrief = ver !== "unknown" && ver.match(/^(\d+)\.(\d+)/) && (parseInt(RegExp.$1, 10) > 0 || parseInt(RegExp.$2, 10) >= 11);
|
|
523
|
-
process.stderr.write(
|
|
524
|
-
`[exceptd] DEPRECATION: \`${cmd}\` is a v0.10.x verb. ` +
|
|
525
|
-
(haveBrief
|
|
526
|
-
? `Prefer \`${LEGACY_VERB_REPLACEMENTS[cmd]}\` (available in this install, v${ver}). `
|
|
527
|
-
: `Upgrade to v0.11.0+ then use \`${LEGACY_VERB_REPLACEMENTS[cmd]}\` (currently installed: v${ver}). `) +
|
|
528
|
-
`Legacy verbs remain functional through this release; they will be removed in v0.13. ` +
|
|
529
|
-
`This banner shows once per exceptd version per host (re-shown on upgrade). Permanent suppress: export EXCEPTD_DEPRECATION_SHOWN=1.\n`
|
|
530
|
-
);
|
|
531
|
-
try { fs.writeFileSync(markerFile, `shown_at=${new Date().toISOString()}\nversion=${ver}\n`, { mode: 0o600 }); }
|
|
532
|
-
catch { /* tmpdir unwritable; the env-var guard below keeps the per-process suppression intact */ }
|
|
533
|
-
}
|
|
534
|
-
process.env.EXCEPTD_DEPRECATION_SHOWN = "1";
|
|
516
|
+
// v0.13.0: hard-refuse the v0.10.x legacy verbs that were
|
|
517
|
+
// deprecation-bannered since v0.11.0. Pre-v0.13 these silently routed
|
|
518
|
+
// to their v0.11+ replacements with a soft banner; v0.13 honors the
|
|
519
|
+
// long-advertised removal. Operators upgrading from v0.10.x get a
|
|
520
|
+
// structured error with the replacement command, suitable for
|
|
521
|
+
// grep / scripted handling.
|
|
522
|
+
if (REMOVED_VERBS[cmd]) {
|
|
523
|
+
emitError(
|
|
524
|
+
`'${cmd}' was removed in v0.13.0. Use \`exceptd ${REMOVED_VERBS[cmd]}\` instead.`,
|
|
525
|
+
{
|
|
526
|
+
verb: cmd,
|
|
527
|
+
removed_in: "0.13.0",
|
|
528
|
+
replacement: REMOVED_VERBS[cmd],
|
|
529
|
+
deprecation_history: "Deprecated in v0.11.0 with a soft banner; slated-for-removal-in-v0.13 announced in v0.12.0; removed in v0.13.0.",
|
|
530
|
+
}
|
|
531
|
+
);
|
|
532
|
+
return;
|
|
535
533
|
}
|
|
536
534
|
|
|
537
535
|
// Seven-phase playbook verbs run in-process — they emit JSON to stdout
|
|
@@ -714,6 +712,16 @@ function emit(obj, pretty, humanRenderer) {
|
|
|
714
712
|
if (obj && obj.ok === false && !process.exitCode) {
|
|
715
713
|
process.exitCode = EXIT_CODES.GENERIC_FAILURE;
|
|
716
714
|
}
|
|
715
|
+
// v0.13.0 envelope harmonization: every emitted body has a top-level
|
|
716
|
+
// `ok` field — defaults to true when not set, matching the symmetric
|
|
717
|
+
// ok:false → exitCode=1 fallback above. Consumers that parse stdout
|
|
718
|
+
// can now assume the envelope shape regardless of which verb produced
|
|
719
|
+
// the body. Per-site `verb: "<name>"` is set at the call site; this
|
|
720
|
+
// helper guarantees the `ok` field's presence but does not synthesize
|
|
721
|
+
// verb (the caller knows its own name).
|
|
722
|
+
if (obj && typeof obj === 'object' && !('ok' in obj)) {
|
|
723
|
+
obj = { ok: true, ...obj };
|
|
724
|
+
}
|
|
717
725
|
const wantJson = !!global.__exceptdWantJson || !!process.env.EXCEPTD_RAW_JSON;
|
|
718
726
|
if (humanRenderer && !wantJson && !pretty) {
|
|
719
727
|
process.stdout.write(humanRenderer(obj) + "\n");
|
|
@@ -4544,7 +4552,7 @@ function cmdAttest(runner, args, runOpts, pretty) {
|
|
|
4544
4552
|
}
|
|
4545
4553
|
|
|
4546
4554
|
if (subverb === "show") {
|
|
4547
|
-
emit({ session_id: sessionId, attestations, attestation_replays: replays }, pretty);
|
|
4555
|
+
emit({ verb: "attest show", session_id: sessionId, attestations, attestation_replays: replays }, pretty);
|
|
4548
4556
|
return;
|
|
4549
4557
|
}
|
|
4550
4558
|
|
package/data/_indexes/_meta.json
CHANGED
|
@@ -1,63 +1,63 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema_version": "1.1.0",
|
|
3
|
-
"generated_at": "2026-05-
|
|
3
|
+
"generated_at": "2026-05-17T23:47:25.094Z",
|
|
4
4
|
"generator": "scripts/build-indexes.js",
|
|
5
5
|
"source_count": 54,
|
|
6
6
|
"source_hashes": {
|
|
7
|
-
"manifest.json": "
|
|
8
|
-
"data/atlas-ttps.json": "
|
|
9
|
-
"data/attack-techniques.json": "
|
|
10
|
-
"data/cve-catalog.json": "
|
|
11
|
-
"data/cwe-catalog.json": "
|
|
7
|
+
"manifest.json": "e4db72d2b307adb316fad1af15322392587c50c4de5b7592c015b93631f6f26b",
|
|
8
|
+
"data/atlas-ttps.json": "1301e6d053be91ac41ec38e64c72ac726e478b7fd6482884c3e2219c8fa16173",
|
|
9
|
+
"data/attack-techniques.json": "4afc226cc7359771a54aab1a1ff53c5530d1ef54eabc1d2fbd3b1caeda2f64a6",
|
|
10
|
+
"data/cve-catalog.json": "d4d2ecc24a0b010d5e83fea9850130278bea120ef130c99dcbb03eff64008f2d",
|
|
11
|
+
"data/cwe-catalog.json": "7a8e01c6f5538125b81ddb29f1b658f0fd407682bc2998aafc6b759e3b1afe48",
|
|
12
12
|
"data/d3fend-catalog.json": "a1fc2827ceb344669e148d55197dbf1b0e5b20bcc618e90517639c17d67ee82d",
|
|
13
13
|
"data/dlp-controls.json": "d2406c482dddd30e49203879999dc4b3a7fd4d0494d6a61d86b91ee76415df19",
|
|
14
14
|
"data/exploit-availability.json": "003a400f5ae5b15527589571679ccdb9b3a62e60073627b5fbdeb2a9fe330a7a",
|
|
15
|
-
"data/framework-control-gaps.json": "
|
|
15
|
+
"data/framework-control-gaps.json": "2c37446ad38270ebe51c0eaf340b26f19367c4eae47886d6310f16a4185354bf",
|
|
16
16
|
"data/global-frameworks.json": "9ba563a85f7f8d6c3c957de64945e20925a89d0ed6ea6fc561cf093811acf558",
|
|
17
17
|
"data/rfc-references.json": "e253a548c8a829d178d5aea601e268724b85c936ccbfa51c2e5d80c5f8efe2b0",
|
|
18
18
|
"data/zeroday-lessons.json": "27d46a0e09a3edbe97dfbb070c3991348567cf93c86a3e94c767c5ad2dfb653e",
|
|
19
|
-
"skills/kernel-lpe-triage/skill.md": "
|
|
20
|
-
"skills/ai-attack-surface/skill.md": "
|
|
21
|
-
"skills/mcp-agent-trust/skill.md": "
|
|
22
|
-
"skills/framework-gap-analysis/skill.md": "
|
|
23
|
-
"skills/compliance-theater/skill.md": "
|
|
24
|
-
"skills/exploit-scoring/skill.md": "
|
|
25
|
-
"skills/rag-pipeline-security/skill.md": "
|
|
26
|
-
"skills/ai-c2-detection/skill.md": "
|
|
27
|
-
"skills/policy-exception-gen/skill.md": "
|
|
28
|
-
"skills/threat-model-currency/skill.md": "
|
|
29
|
-
"skills/global-grc/skill.md": "
|
|
19
|
+
"skills/kernel-lpe-triage/skill.md": "ae4a0af924d0078ffc6cd051a3ef9fce75a6a3f9c0c15d1c07900ae5faf80502",
|
|
20
|
+
"skills/ai-attack-surface/skill.md": "dcca7d92a1ab4d1e4c46356b614a138b1c1f79b65a6a290eccf2095d8d443993",
|
|
21
|
+
"skills/mcp-agent-trust/skill.md": "6821f6d38f6e23bbed953f8f86a279597b0b95a2d0548b5383e851bca7442531",
|
|
22
|
+
"skills/framework-gap-analysis/skill.md": "3b139eaefbedd36b2379cfe22dceef71e97d0e34404b0009b7afbfe0a8dc39e6",
|
|
23
|
+
"skills/compliance-theater/skill.md": "a1387c523f7aa2481a199f6288e0152b94aa5a6644600eb39dbb3ea9ee9af6bd",
|
|
24
|
+
"skills/exploit-scoring/skill.md": "fba9e27722d361cc6ed5992d9aaeaa397598b417fc5a0d6fe0bee2993942e7e8",
|
|
25
|
+
"skills/rag-pipeline-security/skill.md": "ff07e48918090247aef71def4150b0df372a24bcdaa34eb6e11d246b9e71e1ee",
|
|
26
|
+
"skills/ai-c2-detection/skill.md": "3da9f549f5c62e6163cddd70c8edccbef7be622d5a45fa89c90c6550e68c6b2e",
|
|
27
|
+
"skills/policy-exception-gen/skill.md": "a7d886f7fa99a150b040f158b09045ba45e107439315389aea785311b0013395",
|
|
28
|
+
"skills/threat-model-currency/skill.md": "ecc6441cb47ef2bc24547e47be018098228c956a41d61ddb50de7e7b37114a37",
|
|
29
|
+
"skills/global-grc/skill.md": "1dca534cce7612c1d26a7b1bfd088a811081555ecfa25b1f68cff2ca2ba28c98",
|
|
30
30
|
"skills/zeroday-gap-learn/skill.md": "59a0d7cd85b923b3f5633bdc15c1a88eef7dea6332480d93b0bb0ae93a4cd0fe",
|
|
31
|
-
"skills/pqc-first/skill.md": "
|
|
32
|
-
"skills/skill-update-loop/skill.md": "
|
|
33
|
-
"skills/security-maturity-tiers/skill.md": "
|
|
34
|
-
"skills/researcher/skill.md": "
|
|
35
|
-
"skills/attack-surface-pentest/skill.md": "
|
|
36
|
-
"skills/fuzz-testing-strategy/skill.md": "
|
|
37
|
-
"skills/dlp-gap-analysis/skill.md": "
|
|
38
|
-
"skills/supply-chain-integrity/skill.md": "
|
|
31
|
+
"skills/pqc-first/skill.md": "a7131b65d0ceee47887b16679ee4e4b065d32d8751fe59921762388703662913",
|
|
32
|
+
"skills/skill-update-loop/skill.md": "cf2b996cb18a5146614c06e3a50f4734a07d02b5be36bbdf492583f9cdcfed4d",
|
|
33
|
+
"skills/security-maturity-tiers/skill.md": "ed962937c45f3d95f325f231b787d272fe45c4cb91d4c5a2d982493d722c2acf",
|
|
34
|
+
"skills/researcher/skill.md": "b47daaa26fdac07aa23e7becaa18487c5302e65c654f99fecab3689f23ec1bd2",
|
|
35
|
+
"skills/attack-surface-pentest/skill.md": "0d301beb9fb8e247ec80256a7e647804b5f9a41c7156e5724555ca9f93ccb986",
|
|
36
|
+
"skills/fuzz-testing-strategy/skill.md": "51acb746cd63366ca62567588c700a9eb3f37c43250bd9ae4e1477ccb71c5b6d",
|
|
37
|
+
"skills/dlp-gap-analysis/skill.md": "1c4e1d7da2421b82f202eaf2c9e21876af34ab5c76ce1359166842ee473f02dd",
|
|
38
|
+
"skills/supply-chain-integrity/skill.md": "ad69b72f5c5df095f8618b977fbc8f0fbff396eebd4a8448b44c3f93309f63f9",
|
|
39
39
|
"skills/defensive-countermeasure-mapping/skill.md": "e62c71ba3be2b4d0f7dfa529fec007cba6bee3013f76b93756e3e6310f2d22ab",
|
|
40
|
-
"skills/identity-assurance/skill.md": "
|
|
41
|
-
"skills/ot-ics-security/skill.md": "
|
|
40
|
+
"skills/identity-assurance/skill.md": "4ee7096fd82997c66b0f9e825ea3c04c3aa84768b74e6f668c1a9104104138cf",
|
|
41
|
+
"skills/ot-ics-security/skill.md": "9ece7b1fb7f24e37dbdd8618b94b2a4434e182e3426e15f17e26464c0a1fdfd1",
|
|
42
42
|
"skills/coordinated-vuln-disclosure/skill.md": "0e875953bb8a38a89c8ec5d2a9ef967b12e9a9f166dc9356723f10304fd0535e",
|
|
43
|
-
"skills/threat-modeling-methodology/skill.md": "
|
|
44
|
-
"skills/webapp-security/skill.md": "
|
|
45
|
-
"skills/ai-risk-management/skill.md": "
|
|
46
|
-
"skills/sector-healthcare/skill.md": "
|
|
47
|
-
"skills/sector-financial/skill.md": "
|
|
48
|
-
"skills/sector-federal-government/skill.md": "
|
|
49
|
-
"skills/sector-energy/skill.md": "
|
|
50
|
-
"skills/sector-telecom/skill.md": "
|
|
51
|
-
"skills/api-security/skill.md": "
|
|
52
|
-
"skills/cloud-security/skill.md": "
|
|
53
|
-
"skills/container-runtime-security/skill.md": "
|
|
54
|
-
"skills/mlops-security/skill.md": "
|
|
55
|
-
"skills/incident-response-playbook/skill.md": "
|
|
56
|
-
"skills/ransomware-response/skill.md": "
|
|
57
|
-
"skills/email-security-anti-phishing/skill.md": "
|
|
58
|
-
"skills/age-gates-child-safety/skill.md": "
|
|
59
|
-
"skills/cloud-iam-incident/skill.md": "
|
|
60
|
-
"skills/idp-incident-response/skill.md": "
|
|
43
|
+
"skills/threat-modeling-methodology/skill.md": "ac623f61585de66c9ef5ed63e9c6059faef77e525abc672ac6d435c616a7268f",
|
|
44
|
+
"skills/webapp-security/skill.md": "fdb07324b69a3a724e3eaba17bf687d72d4bd9d5c4f440be816bc9b08b8aef04",
|
|
45
|
+
"skills/ai-risk-management/skill.md": "67e62791f60231f2ff53408922fa7137a9060de72097769c630f838a1c227c45",
|
|
46
|
+
"skills/sector-healthcare/skill.md": "a18e11d25524cdbf40df3798f4c2aa3cb51a4db1b088242ea53fa2885e86b64c",
|
|
47
|
+
"skills/sector-financial/skill.md": "023b5440d614e6b83ba7294219bcac3cdbffd28fdfdd5f0ec23abbeea71b8230",
|
|
48
|
+
"skills/sector-federal-government/skill.md": "c63cf1c7c98e920f968cfe60f14e718ea71b120c1b01616af22f64a796963bbe",
|
|
49
|
+
"skills/sector-energy/skill.md": "643fd951359c2602d9b029a244fe66c1e23f726e711141a06c09cc760a479534",
|
|
50
|
+
"skills/sector-telecom/skill.md": "862f9482af88e5409e011a6981a5d719863deeb646e41cd4df63e5d6597c50b1",
|
|
51
|
+
"skills/api-security/skill.md": "2bdfa3dbe534efa3df245e0da37998ad7ab2da4a3171d5000d3346513c10bceb",
|
|
52
|
+
"skills/cloud-security/skill.md": "c9fad9ed3663cf2faec74ad8f06d62eb86e6636f79933560d8c8d50e0e82d1da",
|
|
53
|
+
"skills/container-runtime-security/skill.md": "605a8e8eb1af09835b967ec7179456015ec116c6b9051af3a8d225866cc2f7af",
|
|
54
|
+
"skills/mlops-security/skill.md": "ca3fd922b43fc57aeb5e65c2d5a2823e6bc438167d6afa3a767cee83e4af1f96",
|
|
55
|
+
"skills/incident-response-playbook/skill.md": "2017515d899c1b2bcb878bc6731e4059623ac52345b2cebbd92204583657bf60",
|
|
56
|
+
"skills/ransomware-response/skill.md": "2e4fc488f86ed1ba7791ab0e7021160d8ca5ad33a02cdf92a5b916c8afecaa54",
|
|
57
|
+
"skills/email-security-anti-phishing/skill.md": "e4e9e5a820c0ed3fde9483282e7a0ecaf79284cd2e9923ce66f2b0fb1fc44626",
|
|
58
|
+
"skills/age-gates-child-safety/skill.md": "66e7773d29c179ab62f409007c05e05993e04a19273225a1e520f2481fd9a90d",
|
|
59
|
+
"skills/cloud-iam-incident/skill.md": "6494ee3856edeb212e65fe5cdb208357c1a832eb8ac374b26055586bfc71f629",
|
|
60
|
+
"skills/idp-incident-response/skill.md": "e67a2576e7f1c3bf89f499f5c977bc470ef29e8b3e3e45f4cb5bd45a82674282"
|
|
61
61
|
},
|
|
62
62
|
"skill_count": 42,
|
|
63
63
|
"catalog_count": 11,
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
"handoff_dag_nodes": 42,
|
|
79
79
|
"summary_cards": 42,
|
|
80
80
|
"section_offsets_skills": 42,
|
|
81
|
-
"token_budget_total_approx":
|
|
81
|
+
"token_budget_total_approx": 402643,
|
|
82
82
|
"recipes": 8,
|
|
83
83
|
"jurisdiction_clocks": 29,
|
|
84
84
|
"did_ladders": 8,
|