@blamejs/exceptd-skills 0.10.0 → 0.10.2
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 +51 -0
- package/CHANGELOG.md +95 -0
- package/bin/exceptd.js +445 -12
- package/data/_indexes/_meta.json +2 -2
- package/data/playbooks/ai-api.json +400 -90
- package/data/playbooks/containers.json +406 -94
- package/data/playbooks/cred-stores.json +374 -89
- package/data/playbooks/crypto-codebase.json +1387 -0
- package/data/playbooks/crypto.json +369 -87
- package/data/playbooks/framework.json +376 -86
- package/data/playbooks/hardening.json +357 -84
- package/data/playbooks/kernel.json +325 -78
- package/data/playbooks/library-author.json +1792 -0
- package/data/playbooks/mcp.json +407 -92
- package/data/playbooks/runtime.json +345 -81
- package/data/playbooks/sbom.json +497 -111
- package/data/playbooks/secrets.json +352 -83
- package/lib/framework-gap.js +17 -1
- package/lib/playbook-runner.js +126 -11
- package/lib/schemas/playbook.schema.json +5 -0
- package/manifest-snapshot.json +1 -1
- package/manifest.json +39 -39
- package/package.json +1 -1
- package/sbom.cdx.json +6 -6
package/AGENTS.md
CHANGED
|
@@ -77,6 +77,57 @@ Operator asks: "is this host vulnerable to Copy Fail?" AI invokes `node lib/play
|
|
|
77
77
|
|
|
78
78
|
Schema reference: `lib/schemas/playbook.schema.json`. Reference playbook (read this before authoring a new one): `data/playbooks/kernel.json`.
|
|
79
79
|
|
|
80
|
+
### feeds_into threshold matrix
|
|
81
|
+
|
|
82
|
+
Each playbook's `_meta.feeds_into[]` declares downstream playbooks the host AI should consider chaining into after this run, and the condition that fires the chain. The condition expressions evaluate at `close()` against `analyze` + `validate` + `agentSignals` context. AI assistants surface the suggested next playbook to the operator but never auto-execute; the operator decides.
|
|
83
|
+
|
|
84
|
+
The current (v0.10.x) matrix:
|
|
85
|
+
|
|
86
|
+
| From | Triggers | To | Why |
|
|
87
|
+
|---|---|---|---|
|
|
88
|
+
| ai-api | `analyze.compliance_theater_check.verdict == 'theater'` | framework | dotfile-cred-exposure theater pattern |
|
|
89
|
+
| ai-api | `analyze.blast_radius_score >= 4` | sbom | broad blast radius → inventory check |
|
|
90
|
+
| ai-api | `finding.includes_mcp_server_credential_exposure == true` | mcp | MCP creds leaked → MCP fleet audit |
|
|
91
|
+
| containers | `finding.severity >= 'high'` | kernel | container escape → kernel surface |
|
|
92
|
+
| containers | `always` | secrets | manifests routinely embed secrets |
|
|
93
|
+
| cred-stores | `finding.severity >= 'high'` | secrets | leaked creds in store → repo grep |
|
|
94
|
+
| cred-stores | `finding.severity == 'critical'` | runtime | critical exposure → listening-surface audit |
|
|
95
|
+
| crypto | `analyze.compliance_theater_check.verdict == 'theater'` | framework | FIPS-claim vs reality |
|
|
96
|
+
| crypto | `analyze.blast_radius_score >= 4` | sbom | crypto blast → SBOM-cve match |
|
|
97
|
+
| framework | `any compliance_theater_check.verdict == 'theater' AND blast_radius_score >= 4` | sbom | theater + breadth → inventory |
|
|
98
|
+
| hardening | `always` | kernel | hardening is corroborator for kernel finding |
|
|
99
|
+
| hardening | `finding.severity >= 'high'` | runtime | weak hardening → check actual exposure |
|
|
100
|
+
| kernel | `finding.severity == 'critical' OR analyze.blast_radius_score >= 4` | sbom | critical kernel → SBOM cross-ref |
|
|
101
|
+
| kernel | `analyze.compliance_theater_check.verdict == 'theater'` | framework | patch-SLA theater |
|
|
102
|
+
| mcp | `finding.severity == 'critical' OR analyze.blast_radius_score >= 4` | sbom | broad MCP impact → inventory |
|
|
103
|
+
| mcp | `analyze.compliance_theater_check.verdict == 'theater'` | framework | MCP-trust theater |
|
|
104
|
+
| mcp | `finding.includes_credential_exposure == true` | ai-api | MCP cred → AI-API cred audit |
|
|
105
|
+
| runtime | `always` | kernel | listener finding always informs kernel triage |
|
|
106
|
+
| runtime | `always` | hardening | runtime exposure pairs with hardening posture |
|
|
107
|
+
| runtime | `finding.severity == 'critical' OR analyze.blast_radius_score >= 3` | cred-stores | critical runtime → check cred stores |
|
|
108
|
+
| sbom | `analyze.compliance_theater_check.verdict == 'theater'` | framework | SBOM-signing theater |
|
|
109
|
+
| sbom | `any matched_cve.attack_class == 'kernel-lpe'` | kernel | kernel CVE in inventory → kernel playbook |
|
|
110
|
+
| sbom | `any matched_cve.attack_class == 'mcp-supply-chain'` | mcp | MCP CVE in inventory → MCP playbook |
|
|
111
|
+
| sbom | `any matched_cve.attack_class IN ['ai-c2', 'prompt-injection']` | ai-api | AI CVE → AI-API playbook |
|
|
112
|
+
| secrets | `finding.severity >= 'high'` | cred-stores | leaked secret in repo → check store posture |
|
|
113
|
+
|
|
114
|
+
Cross-cutting playbook `framework` is the natural correlation layer — many playbooks chain into it on a theater verdict. `sbom` is the breadth-of-impact follow-up most playbooks suggest when blast radius crosses 4. `kernel` + `hardening` + `runtime` form a tightly-coupled triangle (any one finding raises questions in the other two). When a playbook lists `always` as a feeds_into condition, the chain runs unconditionally — the AI should always at least offer the next playbook to the operator.
|
|
115
|
+
|
|
116
|
+
### CLI reference
|
|
117
|
+
|
|
118
|
+
| Verb | What it does |
|
|
119
|
+
|---|---|
|
|
120
|
+
| `exceptd plan` | Default: grouped-by-scope summary of all 13 playbooks. `--scope <type>` filters. `--directives` expands directive IDs/titles per playbook. `--flat` for non-grouped. |
|
|
121
|
+
| `exceptd govern <pb>` | Phase 1 — jurisdiction obligations, theater fingerprints, framework gaps, skills to preload. |
|
|
122
|
+
| `exceptd direct <pb>` | Phase 2 — threat context, RWEP thresholds, skill chain, token budget. |
|
|
123
|
+
| `exceptd look <pb>` | Phase 3 — typed artifact-collection spec + `preconditions` array + submission-shape hint. |
|
|
124
|
+
| `exceptd run <pb>` | Phases 4-7 from agent evidence. Auto-detect cwd when no playbook positional. `--scope <type>` or `--all` for multi-playbook. `--vex <file>` to drop CycloneDX/OpenVEX `not_affected` CVEs. `--ci` for exit-code gating. `--diff-from-latest` for drift mode. `--force-stale` to override currency hard-block. |
|
|
125
|
+
| `exceptd ingest` | Alias for `run`; submission JSON may carry `playbook_id` + `directive_id`. |
|
|
126
|
+
| `exceptd reattest [<sid> \| --latest]` | Replay prior session, diff evidence_hash. `--latest [--playbook <id>] [--since <ISO>]` finds the most recent attestation automatically. |
|
|
127
|
+
| `exceptd list-attestations` | Inventory `.exceptd/attestations/<sid>/` — every prior session, newest first. `--playbook <id>` filters. |
|
|
128
|
+
|
|
129
|
+
All verbs support `--help` for per-verb usage. JSON output by default; `--pretty` for indented.
|
|
130
|
+
|
|
80
131
|
---
|
|
81
132
|
|
|
82
133
|
## Recurring Drift Rules
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,100 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.10.2 — 2026-05-12
|
|
4
|
+
|
|
5
|
+
**Patch: v0.10.1 deferred set — framework-gap filter fix, VEX consumption, CI gating, drift mode, 2 new playbooks (13 total), feeds_into matrix.**
|
|
6
|
+
|
|
7
|
+
### Bug fix (carried from v0.9.x)
|
|
8
|
+
|
|
9
|
+
**`exceptd framework-gap NIST-800-53 <cve-id>` returned 0 matches** while `framework-gap all <cve-id>` correctly found the same gap. Root cause: catalog stores `g.framework = "NIST SP 800-53 Rev 5"` (spaces) but operators pass `NIST-800-53` (hyphens), and `.includes()` is case + format sensitive. Fix: normalize both sides via `.toLowerCase().replace(/[\s_-]/g, '')` then substring-match against `g.framework` value AND prefix-match against the gap KEY (e.g. `NIST-800-53-SI-2`).
|
|
10
|
+
|
|
11
|
+
### New CLI flags
|
|
12
|
+
|
|
13
|
+
- **`run --vex <file>`** — load a CycloneDX or OpenVEX document. CVEs marked `not_affected | resolved | false_positive` (CycloneDX) or `not_affected | fixed` (OpenVEX) drop out of `analyze.matched_cves`. Dropped CVEs surface under `analyze.vex.dropped_cves` so the disposition is preserved for the audit trail.
|
|
14
|
+
- **`run --ci`** — machine-readable verdict for CI gates. Exits 2 when `phases.detect.classification === 'detected'` OR (`classification === 'inconclusive'` AND `rwep.adjusted >= rwep_threshold.escalate`). Logs PASS/FAIL reason to stderr. Pure not_detected runs exit 0 even when the playbook's catalogued CVEs carry high baseline RWEP — the gate is about the host-specific verdict, not the catalog.
|
|
15
|
+
- **`run --diff-from-latest`** — compare evidence_hash against the most recent prior attestation for the same playbook in `.exceptd/attestations/`. Drift mode for cron baselines. Result includes `prior_session_id`, `prior_captured_at`, `prior_evidence_hash`, `new_evidence_hash`, `status: unchanged | drifted | no_prior_attestation_for_playbook`.
|
|
16
|
+
- **`reattest --latest [--playbook <id>] [--since <ISO>]`** — find the most-recent attestation automatically. No session-id required.
|
|
17
|
+
|
|
18
|
+
### New playbooks (12 → 13)
|
|
19
|
+
|
|
20
|
+
- **`crypto-codebase`** (scope: code, attack_class: pqc-exposure) — complements the host-side `crypto` playbook. Walks the codebase for in-source crypto choices: weak hash imports (MD5/SHA1), `Math.random()` in security context, PBKDF2 iteration counts, ECDSA curve choices, RSA bit-size constants, PQC adoption signals. Theater fingerprints include `pqc-ready-feature-flag-without-ml-kem` (config toggle with zero ML-KEM call sites), `fips-validated-by-linking-openssl` (link-time vs runtime FIPS provider), `pbkdf2-iterations-set-in-2015` (10k defaults in published packages).
|
|
21
|
+
- **`library-author`** (scope: code, attack_class: supply-chain) — audits what you SHIP, not what you run. Vendored deps, SBOM signing posture, SLSA provenance attestation, VEX issuance, npm provenance, Rekor entries, cosign signing, branch protection, OIDC vs static publish tokens, EU CRA Art.13/14 conformity. Distinct from `sbom` (install-side); this is publish-side. Mutex with `secrets` since both compete for repo-walk cycles.
|
|
22
|
+
|
|
23
|
+
### feeds_into threshold matrix (v0.10.2 doc pass)
|
|
24
|
+
|
|
25
|
+
AGENTS.md now ships the full feeds_into matrix — 25 chains across 12 playbooks. Documents what triggers what, so operators understand the suggested-next-playbook routing rather than treating it as opaque magic. Highlights:
|
|
26
|
+
|
|
27
|
+
- `framework` is the natural correlation layer — many playbooks chain into it on `analyze.compliance_theater_check.verdict == 'theater'`.
|
|
28
|
+
- `sbom` is the breadth-of-impact follow-up most playbooks suggest when `analyze.blast_radius_score >= 4`.
|
|
29
|
+
- `kernel + hardening + runtime` form a tightly-coupled triangle (any one raises questions in the other two).
|
|
30
|
+
- `always` conditions on `hardening → kernel`, `runtime → kernel`, `runtime → hardening`, `containers → secrets` — the AI should always at least offer the next playbook to the operator.
|
|
31
|
+
|
|
32
|
+
### Internal
|
|
33
|
+
|
|
34
|
+
- **kernel.json feeds_into typo fix** — `compliance-theater` referent (no such playbook ID) corrected to `framework` (the playbook carrying the compliance-theater attack class). Test updated to assert the corrected chain.
|
|
35
|
+
- **`vexFilterFromDoc` helper** in `lib/playbook-runner.js` — parses CycloneDX VEX or OpenVEX documents into a `Set<string>` of CVE IDs whose disposition is "not_affected" or equivalent.
|
|
36
|
+
- **AGENTS.md** — new "feeds_into threshold matrix" section + "CLI reference" table.
|
|
37
|
+
|
|
38
|
+
### Still deferred (next pass)
|
|
39
|
+
|
|
40
|
+
- crypto-codebase playbook ships `eu-ai-act` and `cmmc` in `frameworks_in_scope` but doesn't thread either into `framework_gap_mapping` — Hard Rule #4 (no orphaned references) tidy. Either drop the entries or add concrete mapping in a follow-up.
|
|
41
|
+
- Crypto-codebase byte size (95 KB) is above the 50-60 KB target for new playbooks — load-bearing content but worth a depth audit.
|
|
42
|
+
- `_meta.feeds_into[].condition` parser supports a limited DSL — some playbooks use expressions like `any matched_cve.attack_class IN ['ai-c2', 'prompt-injection']` that the current parser doesn't fully support. Conditions degrade silently to false. Worth a parser pass to either expand the DSL or warn on unknown shapes.
|
|
43
|
+
|
|
44
|
+
## 0.10.1 — 2026-05-12
|
|
45
|
+
|
|
46
|
+
**Patch: operator-reported bugs from v0.10.0 first contact + scope-aware `run` default.**
|
|
47
|
+
|
|
48
|
+
### New: `_meta.scope` + scope-aware multi-playbook `run`
|
|
49
|
+
|
|
50
|
+
Pre-0.10.1, `exceptd run` required a single explicit `<playbook>`. Operators had to know which of the 11 playbooks fit their context. Now:
|
|
51
|
+
|
|
52
|
+
- `exceptd run` (no args) auto-detects cwd: `.git/` → code playbooks; `/proc` + `/etc/os-release` → system playbooks. Always includes `cross-cutting`.
|
|
53
|
+
- `exceptd run --scope <type>` runs all playbooks matching `system | code | service | cross-cutting | all`.
|
|
54
|
+
- `exceptd run --all` runs every playbook.
|
|
55
|
+
- `exceptd run <playbook>` (explicit) keeps its existing behavior.
|
|
56
|
+
|
|
57
|
+
Each shipped playbook now carries `_meta.scope`:
|
|
58
|
+
- **system**: kernel · hardening · runtime · sbom · cred-stores
|
|
59
|
+
- **code**: secrets · containers
|
|
60
|
+
- **service**: mcp · ai-api · crypto
|
|
61
|
+
- **cross-cutting**: framework
|
|
62
|
+
|
|
63
|
+
Multi-playbook runs share one `session_id`; per-playbook attestations land under `.exceptd/attestations/<session_id>/<playbook_id>.json`. Aggregate output reports `summary.{succeeded, blocked, detected, inconclusive}`.
|
|
64
|
+
|
|
65
|
+
`exceptd plan` now groups output by scope by default with a `scope_summary` count. `--flat` returns the old flat list. `--scope <type>` filters.
|
|
66
|
+
|
|
67
|
+
### Bug fixes from operator first-contact
|
|
68
|
+
|
|
69
|
+
1. **Per-verb `--help` printed missing-arg errors.** `exceptd run --help` returned `{"ok":false,"error":"run: missing <playbookId> positional argument."}` instead of usage. Now every playbook verb (`plan`/`govern`/`direct`/`look`/`run`/`ingest`/`reattest`) honors `--help`/`-h` before positional validation and emits per-verb usage with flag descriptions, invocation modes, and `precondition_checks` submission shape.
|
|
70
|
+
|
|
71
|
+
2. **Preconditions were invisible to the host AI.** Neither `govern` nor `look` surfaced `_meta.preconditions`, so the AI couldn't see what facts to declare in its submission. `run` would then halt with `precondition_unverified` and the AI was blind. Fix: `look` response now includes `preconditions: [{id, check, on_fail, description}]` plus a `precondition_submission_shape` field giving the literal JSON shape (`{ "precondition_checks": { "<id>": true } }`) and an example. AGENTS.md updated.
|
|
72
|
+
|
|
73
|
+
3. **`precondition_checks` submission shape was undocumented in errors.** Preflight halt now returns a `remediation` field with the exact submission hint per failed precondition.
|
|
74
|
+
|
|
75
|
+
4. **`matched_cves` violated AGENTS.md Hard Rule #1.** Pre-0.10.1 output emitted `[{cve_id, rwep, cisa_kev, active_exploitation, ai_discovered}]` only — missing CVSS score/vector, KEV due date, PoC availability, AI-assisted-weaponization flag, patch availability, live-patch availability, EPSS, affected_versions, ATLAS/ATT&CK refs. The framework's own hard rule (every CVE reference must carry CVSS + KEV + PoC + AI-discovery + active-exploitation + patch/live-patch availability — theoretical-only is refused) was violated by the runner itself. Fix: `analyze.matched_cves[]` entries now carry all 15 required + optional Hard Rule #1 fields populated from the catalog. Null only when the catalog lacks the value, never when the runner forgot to forward.
|
|
76
|
+
|
|
77
|
+
5. **`detect.classification` ignored `signals.detection_classification`.** Agent could submit `{"detection_classification":"clean"}` with all-miss `signal_overrides` and still get `inconclusive`. Fix: agent override honored when set to `detected | inconclusive | not_detected | clean` (alias). Engine-computed classification used as fallback.
|
|
78
|
+
|
|
79
|
+
6. **`compliance_theater_check.verdict` stuck at `pending_agent_run` when classification was clear.** When the framework playbook ran with clean `detect.classification = not_detected`, the theater verdict still came back as pending instead of `clear`. Fix: when agent didn't submit `theater_verdict`, engine derives one from classification (`not_detected` → `clear`; otherwise `pending_agent_run`). Aliases `clean` / `no_theater` map to `clear`.
|
|
80
|
+
|
|
81
|
+
7. **No directive discoverability.** `exceptd plan` showed directive counts but not IDs/titles. Fix: `exceptd plan --directives` expands each playbook entry with `directives: [{id, title, applies_to}]`.
|
|
82
|
+
|
|
83
|
+
8. **No attestation inventory command.** Operators accumulated attestations under `.exceptd/attestations/` with no inventory verb; discovery required shell-globbing. Fix: new `exceptd list-attestations [--playbook <id>]` enumerates every prior session, sorted newest-first, with truncated evidence_hash + capture timestamp + file path.
|
|
84
|
+
|
|
85
|
+
### Deferred from operator report
|
|
86
|
+
|
|
87
|
+
These were noted in the same report and are scoped to v0.10.2 / v0.11:
|
|
88
|
+
|
|
89
|
+
- `framework-gap <framework> <cve-id>` named-framework filter doesn't match by gap-id prefix (carried over from v0.9.x).
|
|
90
|
+
- Crypto-codebase / library-internal playbook variant (new attack class for library authors).
|
|
91
|
+
- Framework-author operator persona (audit what you ship, not what you run).
|
|
92
|
+
- `reattest --latest <playbook>` / `--since <date>` (no need to know session-id).
|
|
93
|
+
- `run --diff-from-latest` for cron-driven baselines.
|
|
94
|
+
- `run --ci` exit-code-based gating for `.github/workflows/`.
|
|
95
|
+
- VEX consumption in sbom (`run sbom --vex vex.cdx.json` drops `known_not_affected` from analyze output).
|
|
96
|
+
- feeds_into threshold matrix documentation.
|
|
97
|
+
|
|
3
98
|
## 0.10.0 — 2026-05-11
|
|
4
99
|
|
|
5
100
|
**Minor: seven-phase playbook contract. exceptd becomes a knowledge layer that AI assistants consume, not a parallel scanner.**
|