@lhi/tdd-audit 1.18.0 → 1.20.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/README.md CHANGED
@@ -1,41 +1,124 @@
1
1
  # @lhi/tdd-audit
2
- ![Coverage](https://img.shields.io/badge/coverage-95%25-brightgreen)
2
+ ![Coverage](https://img.shields.io/badge/coverage-98%25-brightgreen)
3
3
  [![tdd-audit](https://img.shields.io/badge/tdd--audit-passing-brightgreen)](https://www.npmjs.com/package/@lhi/tdd-audit) <!-- tdd-audit-badge -->
4
4
 
5
- > **v1.18.0** AI-powered security audit skill for **Claude Code, Gemini CLI, Cursor, Codex, and OpenCode**. Four output depth tiers let you choose between a fast scan report, a rich findings report, copy-ready patches, or fully automated patch applicationall backed by an agentic LLM with tool use.
5
+ > **Your AI-generated code is probably vulnerable right now.** SQL injection. Hardcoded secrets. Prompt injection backdoors. The same assistant that built your feature in 30 minutes didn't think twice about security. `tdd-audit` finds the holes, proves they're real, and closes them every fix backed by a failing test before and a passing test after.
6
+
7
+ ## One command. Proven secure.
8
+
9
+ ```bash
10
+ npx @lhi/tdd-audit --local --claude
11
+ ```
12
+
13
+ That's it. In seconds you get:
14
+
15
+ - A severity-ranked findings report (CRITICAL → LOW) with the exact file and line
16
+ - Exploit tests that **prove the vulnerability is real** — not theoretical
17
+ - Patches that close each hole, verified by a passing test suite
18
+ - ≥ 95% test coverage enforced, a README security badge, and a `SECURITY.md` ready for auditors
19
+
20
+ No security expertise required. No config needed to start.
21
+
22
+ ---
23
+
24
+ ## Why this exists
25
+
26
+ Vibecoders move fast. AI assistants hallucinate security. The result: apps with SQL injection in the ORM layer, JWT algorithm confusion, hardcoded API keys one `git log` away from leaking, and LLM prompt injection that hands your backend to anyone who knows the trick.
27
+
28
+ PMs and security officers feel it too — "is this thing actually secure?" has no good answer when there are no tests proving it.
29
+
30
+ `tdd-audit` gives you the answer. Every vulnerability is proven closed by a test, not just patched and hoped for the best.
31
+
32
+ ---
6
33
 
7
34
  ## Install
8
35
 
9
36
  ```bash
10
- npx @lhi/tdd-audit
37
+ # Claude Code (recommended)
38
+ npx @lhi/tdd-audit --local --claude
39
+
40
+ # Gemini CLI / Codex / OpenCode / Cursor
41
+ npx @lhi/tdd-audit --local
11
42
  ```
12
43
 
13
44
  On first run the installer:
14
45
 
15
- 1. Scaffolds `__tests__/security/` with a framework-matched exploit test boilerplate
46
+ 1. Scaffolds `__tests__/security/` with framework-matched exploit test boilerplate
16
47
  2. Adds `test:security` to `package.json`
17
- 3. Creates `.github/workflows/security-tests.yml` with SHA-pinned actions and `npm audit`
18
- 4. Installs the `/tdd-audit` skill for your AI agent
48
+ 3. Creates `.github/workflows/security-tests.yml` SHA-pinned actions, `npm audit` on every PR
49
+ 4. Installs the `/tdd-audit` skill in your AI agent
19
50
 
20
- ### Flags
51
+ Then open your agent and type `/tdd-audit`. It handles the rest.
21
52
 
22
- | Flag | Description |
53
+ ### Install flags
54
+
55
+ | Flag | What it does |
23
56
  |---|---|
24
- | `--local` | Install into the current project instead of `~` |
25
- | `--claude` | Use `.claude/` instead of `.agents/` |
26
- | `--with-hooks` | Add a pre-commit hook that blocks commits on failing security tests |
27
- | `--skip-scan` | Skip the vulnerability scan on install |
28
- | `--config <path>` | Load config from an explicit file path |
57
+ | `--local` | Install into the current project (recommended) |
58
+ | `--claude` | Use `.claude/` for Claude Code |
59
+ | `--with-hooks` | Block commits that break security tests |
60
+ | `--skip-scan` | Skip the initial vulnerability scan |
61
+ | `--config <path>` | Load config from a specific path |
29
62
 
30
- ### Platform
63
+ ---
31
64
 
32
- | Platform | Command |
33
- |---|---|
34
- | Claude Code | `npx @lhi/tdd-audit --local --claude` |
35
- | Gemini CLI / Codex / OpenCode | `npx @lhi/tdd-audit --local` |
65
+ ## What gets caught
66
+
67
+ 100+ patterns across Node.js, Python, Go, React, React Native, Flutter, and Expo — including the AI-specific vulnerabilities that most scanners miss entirely:
68
+
69
+ **Standard OWASP holes** — SQL/NoSQL/Command injection · Path traversal · Broken auth · XSS · IDOR · Mass assignment · SSRF · Open redirect · XXE · Insecure deserialization · Prototype pollution · Weak crypto · Hardcoded secrets · TLS bypass
70
+
71
+ **AI / LLM-specific** (the ones that will actually get you hacked in 2025) — LLM prompt injection · Eval of model output · LangChain ShellTool / ExecChain · Unbounded agent loops · MCP credential leakage · GitHub Actions expression injection · Hardcoded provider keys (OpenAI, Anthropic, Gemini, Cohere, Mistral, HuggingFace) · Missing `max_tokens` · Dynamic require from user input · VM sandbox escape · Electron `nodeIntegration: true`
72
+
73
+ **Vibecoding anti-patterns** — `localStorage` token storage · `Math.random()` for session IDs · `process.env.SECRET || "hardcoded-fallback"` · Silent exception swallowing · Insecure WebSocket URLs
74
+
75
+ ---
76
+
77
+ ## How it works
78
+
79
+ The full `/tdd-audit` skill run follows Red-Green-Refactor for every finding:
80
+
81
+ 1. **Detect** — scans your stack, scopes patterns to what's actually relevant
82
+ 2. **Report** — presents a CRITICAL → LOW findings table with plain-language risk and effort estimate. Waits for your sign-off before touching anything
83
+ 3. **Red** — writes an exploit test that **fails** (proves the hole is real)
84
+ 4. **Green** — applies the patch (test now passes)
85
+ 5. **Refactor** — runs the full suite (zero regressions)
86
+ 6. **Harden** — security headers, rate limiting, `npm audit`, secret scan, production error handling
87
+ 7. **Coverage gate** — pushes test coverage to ≥ 95% line and branch
88
+ 8. **Badge + SECURITY.md** — updates your README badge, creates `SECURITY.md` in GitHub Security Advisory format
89
+
90
+ Nothing is marked done until a test proves it.
91
+
92
+ ---
93
+
94
+ ## For PMs and security officers
95
+
96
+ You need evidence, not promises. `tdd-audit` produces:
97
+
98
+ - **Exploit tests** — a failing test per vulnerability, committed to source, proves the hole existed
99
+ - **Passing tests** — the fix is proven by the test suite, not just code review
100
+ - **`--format report`** — a markdown compliance report with findings table, fix evidence, patch commits, and coverage gate result; ready to attach to SOC 2, ISO 27001, or vendor security questionnaire
101
+ - **`--sbom`** — CycloneDX Software Bill of Materials (required for US federal contracts under EO 14028)
102
+ - **`SECURITY.md`** — GitHub Security Advisory format with your security contact, supported versions, and hardening summary
103
+ - **Webhook + Slack notifications** — findings summary delivered to your security channel on every scan
104
+
105
+ Configure your security contact in `.tdd-audit.json`:
106
+
107
+ ```json
108
+ {
109
+ "security_name": "Alice Smith",
110
+ "security_email": "security@yourorg.com"
111
+ }
112
+ ```
113
+
114
+ Both fields are optional — use one, both, or neither. When set, they appear in SECURITY.md, the compliance report, and webhook payloads.
115
+
116
+ ---
36
117
 
37
118
  ## AI Audit (`--ai`)
38
119
 
120
+ Let the LLM explore and report on your codebase directly:
121
+
39
122
  ```bash
40
123
  npx @lhi/tdd-audit --ai \
41
124
  --provider anthropic \
@@ -44,32 +127,27 @@ npx @lhi/tdd-audit --ai \
44
127
  --format json
45
128
  ```
46
129
 
47
- The `--ai` flag triggers a full agentic audit: the LLM explores your codebase using `read_file`, `list_files`, and `search_in_files` tool calls, then produces a structured findings report shaped by `--depth`.
48
-
49
130
  ### Depth tiers
50
131
 
51
- | Tier | Mode | Output | Billing unit |
132
+ | Tier | Mode | What you get | Billing unit |
52
133
  |---|---|---|---|
53
- | `tier-1` | scan-only | `name`, `severity`, `file`, `line`, `snippet` | per report |
54
- | `tier-2` | scan-only | + `risk`, `effort`, `cwe`, `owasp`, `references` | per report |
55
- | `tier-3` | full audit, read-only | + `patch` (copy-ready), `testSnippet` | per report |
56
- | `tier-4` | full audit, writes enabled | LLM applies patches via `write_file`; `patchesApplied` in envelope | per applied patch |
134
+ | `tier-1` | Scan only | File, line, severity, snippet | per report |
135
+ | `tier-2` | Scan only | + risk explanation, effort estimate, CWE, OWASP, references | per report |
136
+ | `tier-3` | Full audit, read-only | + copy-ready patches and test snippets — you apply manually | per report |
137
+ | `tier-4` | Full audit, writes | LLM applies every patch via `write_file` | per applied patch |
57
138
 
58
139
  ```bash
59
- # Minimal scan report
140
+ # Fast scan — just the findings
60
141
  npx @lhi/tdd-audit --ai --depth tier-1 --format json
61
142
 
62
- # Rich report with CWE/OWASP/references no changes made
143
+ # Full report with context, no changes made
63
144
  npx @lhi/tdd-audit --ai --depth tier-2 --format json
64
145
 
65
- # Copy-ready patches in every finding — apply manually
146
+ # Copy-ready patches — apply yourself
66
147
  npx @lhi/tdd-audit --ai --depth tier-3 --format json
67
148
 
68
- # Let the LLM apply the patches for you
149
+ # Let the LLM fix everything
69
150
  npx @lhi/tdd-audit --ai --depth tier-4 --allow-writes
70
-
71
- # Targeted apply: apply one specific patch from a prior tier-3 report
72
- # (via REST API — see docs/rest-api.md)
73
151
  ```
74
152
 
75
153
  ### AI flags
@@ -77,132 +155,129 @@ npx @lhi/tdd-audit --ai --depth tier-4 --allow-writes
77
155
  | Flag | Description |
78
156
  |---|---|
79
157
  | `--ai` | Enable LLM agentic audit |
80
- | `--depth tier-1\|tier-2\|tier-3\|tier-4` | Output depth tier (default: `tier-1`) |
158
+ | `--depth tier-1\|2\|3\|4` | Output depth tier (default: `tier-1`) |
81
159
  | `--allow-writes` | Permit the LLM to write files (auto-enabled for `tier-4`) |
82
160
  | `--provider <name>` | `anthropic` \| `openai` \| `gemini` \| `ollama` |
83
161
  | `--api-key <key>` | Provider API key |
84
162
  | `--model <name>` | Model override (e.g. `claude-opus-4-6`, `gpt-4o`) |
85
- | `--base-url <url>` | Base URL for any OpenAI-compatible service |
86
- | `--format json\|sarif` | Structured output format (default: streaming text) |
163
+ | `--base-url <url>` | Any OpenAI-compatible service |
164
+ | `--format json\|sarif\|report` | Structured output format |
87
165
  | `--verbose` | Print tool call details to stderr |
88
166
 
89
- ## Config file
167
+ ---
168
+
169
+ ## CI integration
170
+
171
+ ### PR gate — block merges on new findings
172
+
173
+ ```yaml
174
+ - run: npx @lhi/tdd-audit@latest --pr --threshold HIGH
175
+ ```
176
+
177
+ Exits non-zero if any finding meets or exceeds the threshold. Sub-second — no AI, no agents, pure static scan. Wire into branch protection rules to stop vulnerable code from merging.
178
+
179
+ ### Org-wide posture scan
180
+
181
+ ```bash
182
+ npx @lhi/tdd-audit@latest --org my-github-org --format report
183
+ ```
184
+
185
+ Scans every repo in the org, produces a cross-org summary and a compliance report. Fires your webhook/Slack with the aggregate payload.
90
186
 
91
- Scaffold a starter config with a single command:
187
+ ---
188
+
189
+ ## Config file
92
190
 
93
191
  ```bash
94
- npx @lhi/tdd-audit init
95
- # or at a custom path:
96
- npx @lhi/tdd-audit init ~/configs/my-audit.json
192
+ npx @lhi/tdd-audit init # scaffold .tdd-audit.json
193
+ npx @lhi/tdd-audit init --provider anthropic # with Anthropic defaults
97
194
  ```
98
195
 
99
- `.tdd-audit.json` — all CLI flags settable here, loaded automatically from your project root:
196
+ `.tdd-audit.json` — everything settable here, CLI flags always win:
100
197
 
101
198
  ```json
102
199
  {
103
- "provider": "openai",
104
- "model": "gpt-4o",
105
- "apiKeyEnv": "OPENAI_API_KEY",
106
- "baseUrl": null,
107
- "output": "json",
108
- "severityThreshold": "LOW",
109
- "port": 3000,
110
- "serverApiKey": null,
111
- "trustProxy": false,
112
- "ignore": ["node_modules", "dist", "build", "coverage"]
200
+ "provider": "anthropic",
201
+ "model": "claude-opus-4-6",
202
+ "apiKeyEnv": "ANTHROPIC_API_KEY",
203
+ "severityThreshold": "HIGH",
204
+ "ignore": ["node_modules", "dist", "coverage"],
205
+
206
+ "security_name": "Alice Smith",
207
+ "security_email": "security@yourorg.com",
208
+
209
+ "webhook_url": "https://hooks.yourorg.com/security",
210
+ "slack_webhook": "https://hooks.slack.com/services/...",
211
+ "slack_channel": "#security-alerts",
212
+
213
+ "severity_overrides": {
214
+ "CORS Wildcard": "CRITICAL"
215
+ }
113
216
  }
114
217
  ```
115
218
 
116
- Point to a config anywhere with `--config`:
219
+ Full schema [docs/configuration.md](docs/configuration.md)
117
220
 
118
- ```bash
119
- npx @lhi/tdd-audit serve --config ~/configs/prod-audit.json
120
- ```
221
+ ---
121
222
 
122
223
  ## REST API
123
224
 
124
225
  ```bash
125
- # Start the API server
126
226
  npx @lhi/tdd-audit serve --port 3000 --api-key YOUR_SECRET
127
-
128
- # AI audit — returns jobId immediately
129
- curl -X POST http://localhost:3000/audit/ai \
130
- -H "Authorization: Bearer YOUR_SECRET" \
131
- -H "Content-Type: application/json" \
132
- -d '{"provider": "anthropic", "apiKey": "sk-ant-...", "depth": "tier-2"}' \
133
- | jq '.jobId'
134
-
135
- # Poll job status
136
- curl http://localhost:3000/jobs/<jobId>
137
-
138
- # Or stream real-time LLM output via SSE
139
- curl -N http://localhost:3000/jobs/<jobId>/stream
140
-
141
- # Targeted apply: re-apply a specific patch from a tier-3 report
142
- curl -X POST http://localhost:3000/audit/ai \
143
- -H "Authorization: Bearer YOUR_SECRET" \
144
- -H "Content-Type: application/json" \
145
- -d '{
146
- "provider": "anthropic",
147
- "apiKey": "sk-ant-...",
148
- "depth": "tier-4",
149
- "findings": [{ "name": "SQL Injection", "file": "src/db.js", "line": 10, "patch": "..." }]
150
- }'
151
-
152
- # Use any OpenAI-compatible service (Groq, OpenRouter, Together AI, etc.)
153
- npx @lhi/tdd-audit serve \
154
- --provider openai \
155
- --base-url https://api.groq.com/openai/v1 \
156
- --api-key $GROQ_API_KEY \
157
- --model llama-3.3-70b-versatile
158
227
  ```
159
228
 
160
- Supported providers: `anthropic` · `openai` · `gemini` · `ollama` (local) · **any OpenAI-compatible endpoint via `--base-url`**
161
-
162
- ### Endpoints
163
-
164
229
  | Method | Path | Auth | Description |
165
230
  |---|---|---|---|
166
- | `GET` | `/health` | No | Version + liveness check |
167
- | `POST` | `/audit/ai` | Yes | Agentic LLM audit with depth tiers; returns `jobId` |
231
+ | `GET` | `/health` | No | Liveness check |
232
+ | `POST` | `/audit/ai` | Yes | LLM audit with depth tiers; returns `jobId` |
233
+ | `POST` | `/scan` | Yes | Static scan; returns findings immediately |
168
234
  | `POST` | `/remediate` | Yes | AI-fix a provided findings list; returns `jobId` |
169
- | `POST` | `/audit` | Yes | Static scan + AI remediation pipeline; returns `jobId` |
170
235
  | `GET` | `/jobs/:id` | Yes | Poll job status |
171
- | `GET` | `/jobs/:id/stream` | Yes | SSE stream real-time job progress |
236
+ | `GET` | `/jobs/:id/stream` | Yes | SSE stream live LLM output |
172
237
 
173
- ## Agent skill
238
+ ```bash
239
+ # Start an AI audit
240
+ curl -X POST http://localhost:3000/audit/ai \
241
+ -H "Authorization: Bearer YOUR_SECRET" \
242
+ -H "Content-Type: application/json" \
243
+ -d '{"provider": "anthropic", "apiKey": "sk-ant-...", "depth": "tier-2"}'
174
244
 
175
- ```text
176
- /tdd-audit
245
+ # Stream results live
246
+ curl -N http://localhost:3000/jobs/<jobId>/stream
177
247
  ```
178
248
 
179
- The agent detects your stack, presents a CRITICAL LOW findings report, waits for confirmation, then works through each vulnerability one at a time using Red-Green-Refactor (prove the hole exists, apply the fix, prove it's closed). Enforces ≥ 95% test coverage, README badge, and SECURITY.md on every audit.
249
+ Supported providers: `anthropic` · `openai` · `gemini` · `ollama` · **any OpenAI-compatible endpoint via `--base-url`**
180
250
 
181
- ## Testing
251
+ ---
182
252
 
183
- 791 tests across unit, E2E, and security suites:
253
+ ## Testing
184
254
 
185
255
  ```bash
186
- npm test # full suite
187
- npm run test:unit # unit tests with coverage (95.6% branch coverage)
256
+ npm test # full suite (841 tests)
257
+ npm run test:unit # unit tests with coverage
188
258
  npm run test:security # security regression tests only
189
259
  npm run test:e2e # end-to-end REST API tests
190
260
  ```
191
261
 
192
- Security tests cover prompt injection, path traversal, rate limiting, timing-safe auth, job store bounds, SARIF schema, and more. See [__tests__/security/](__tests__/security/) for all regression tests.
262
+ Security tests cover: prompt injection · path traversal · SSRF via webhook and baseUrl · rate limiting · timing-safe auth · XFF bypass · job store bounds · SARIF schema · AI key redaction · coverage skip detection · and more. Every past vulnerability is a permanent regression test.
263
+
264
+ ---
193
265
 
194
266
  ## Documentation
195
267
 
196
268
  | | |
197
269
  |---|---|
270
+ | [Configuration](docs/configuration.md) | Full schema — all fields, CLI equivalents, payload schemas |
198
271
  | [REST API](docs/rest-api.md) | Endpoints, auth, rate limiting, depth tiers, targeted apply |
199
- | [AI Remediation](docs/ai-remediation.md) | Provider setup, `--base-url` for compatible APIs, config file |
200
- | [Vulnerability Patterns](docs/vulnerability-patterns.md) | All 79 patterns — descriptions, grep signatures, fix pointers |
272
+ | [AI Remediation](docs/ai-remediation.md) | Provider setup, `--base-url` for compatible APIs |
273
+ | [Vulnerability Patterns](docs/vulnerability-patterns.md) | All 100+ patterns — descriptions, grep signatures, fix pointers |
201
274
  | [TDD Protocol](docs/tdd-protocol.md) | Red-Green-Refactor in full, with framework templates for all 6 stacks |
202
275
  | [Agentic AI Security](docs/agentic-ai-security.md) | ASI01–ASI10 — prompt injection, MCP supply chain, Actions injection |
203
276
  | [Hardening](docs/hardening.md) | Phase 4 controls — Helmet, CSP, CSRF, rate limiting, gitleaks, SRI |
204
277
  | [CI/CD](docs/ci-cd.md) | Workflow templates, existing pipeline integration, secret leak prevention |
205
278
 
279
+ ---
280
+
206
281
  ## License
207
282
 
208
283
  MIT
@@ -0,0 +1,236 @@
1
+ # Configuration Reference
2
+
3
+ All `tdd-audit` behaviour is controlled by `.tdd-audit.json` at your repo root. CLI flags override file config; file config overrides built-in defaults.
4
+
5
+ Generate a starter file:
6
+ ```bash
7
+ npx @lhi/tdd-audit@latest init
8
+ npx @lhi/tdd-audit@latest init --provider anthropic
9
+ ```
10
+
11
+ ---
12
+
13
+ ## Full schema
14
+
15
+ ```jsonc
16
+ {
17
+ // ── Core ──────────────────────────────────────────────────────────────────
18
+ "output": "text", // "text" | "json" | "sarif" | "report"
19
+ "severityThreshold": "LOW", // minimum severity to include: "LOW" | "MEDIUM" | "HIGH" | "CRITICAL"
20
+ "ignore": [], // path prefixes to skip: ["node_modules", "dist"]
21
+ "port": 3000, // port for `tdd-audit serve`
22
+ "serverApiKey": null, // required on REST API calls; falls back to TDD_AUDIT_API_KEY env var
23
+
24
+ // ── AI provider ───────────────────────────────────────────────────────────
25
+ "provider": "anthropic", // "anthropic" | "openai" | "gemini" | "ollama"
26
+ "model": "claude-opus-4-6",
27
+ "apiKeyEnv": "ANTHROPIC_API_KEY", // env var to read the key from
28
+ "baseUrl": null, // override for OpenAI-compatible providers
29
+
30
+ // ── Branding ──────────────────────────────────────────────────────────────
31
+ // For wrapper/rebranded distributions. See docs/extensibility.md.
32
+ "org": "Daily Caller",
33
+ "project": "my-project",
34
+ "badge_label": "dc-audit", // replaces "tdd-audit" in the shields.io badge
35
+ "tdd_site": "https://security.example.com", // replaces npm link in badge + SARIF
36
+ "security_name": "Alice Smith", // name of the security contact — stamped into SECURITY.md, compliance reports, and webhook payloads
37
+ "security_email": "security@example.com", // email for the vulnerability reporting address in SECURITY.md and payloads
38
+
39
+ // ── Policy as code ────────────────────────────────────────────────────────
40
+ // Override the default severity for any named pattern.
41
+ // Useful when a pattern's default severity doesn't match your org's risk model.
42
+ "severity_overrides": {
43
+ "CORS Wildcard": "CRITICAL", // default: MEDIUM
44
+ "Sensitive Log": "HIGH", // default: MEDIUM
45
+ "Cleartext Traffic": "HIGH" // default: MEDIUM
46
+ },
47
+
48
+ // ── Notifications ─────────────────────────────────────────────────────────
49
+ // Fired when a scan completes. Both can be set simultaneously.
50
+ "webhook_url": "https://hooks.example.com/tdd-audit",
51
+ // POST body: { project, timestamp, summary: { critical, high, medium, low }, findings: [...] }
52
+
53
+ "slack_webhook": "https://hooks.slack.com/services/...",
54
+ "slack_channel": "#security", // optional override; uses webhook default if absent
55
+
56
+ // ── Workflow integration ───────────────────────────────────────────────────
57
+ "open_pr": true, // open a GitHub PR per finding instead of committing directly
58
+ "github_token": null, // falls back to GITHUB_TOKEN env var
59
+ "github_repo": null, // "owner/repo" — auto-detected from git remote if null
60
+
61
+ // ── CI / scheduled modes ──────────────────────────────────────────────────
62
+ "pr_mode": false, // lightweight static scan only — fast, designed for PR gates
63
+ "org_scan": null, // "my-github-org" — scan all repos in the org
64
+ "schedule": null, // cron expression for external schedulers: "0 2 * * *"
65
+
66
+ // ── Output additions ──────────────────────────────────────────────────────
67
+ "sbom": false, // generate CycloneDX SBOM alongside the audit
68
+ "report": false, // generate human-readable compliance report (markdown)
69
+ "watch": false, // re-scan affected files on save (watch mode)
70
+
71
+ // ── Secret rotation ───────────────────────────────────────────────────────
72
+ "rotate_secrets": false, // when a hardcoded key is detected, prompt to rotate via provider API
73
+
74
+ // ── Extensibility ─────────────────────────────────────────────────────────
75
+ // See docs/extensibility.md for full documentation.
76
+ "pattern_repos": [],
77
+ "extra_skill_dirs": [],
78
+ "extra_repos": [],
79
+ "mcp_services": [],
80
+ "extra_domains": []
81
+ }
82
+ ```
83
+
84
+ ---
85
+
86
+ ## CLI flag equivalents
87
+
88
+ | Config key | CLI flag |
89
+ |---|---|
90
+ | `output: "json"` | `--json` or `--format json` |
91
+ | `output: "sarif"` | `--format sarif` |
92
+ | `output: "report"` | `--format report` |
93
+ | `pr_mode: true` | `--pr` |
94
+ | `org_scan: "myorg"` | `--org myorg` |
95
+ | `open_pr: true` | `--open-pr` |
96
+ | `sbom: true` | `--sbom` |
97
+ | `watch: true` | `--watch` |
98
+ | `report: true` | `--report` |
99
+ | `rotate_secrets: true` | `--rotate-secrets` |
100
+ | `provider: "openai"` | `--provider openai` |
101
+ | `model: "gpt-4o"` | `--model gpt-4o` |
102
+ | `severityThreshold: "HIGH"` | `--threshold HIGH` |
103
+
104
+ CLI flags always win over file config.
105
+
106
+ ---
107
+
108
+ ## Policy as code
109
+
110
+ `severity_overrides` lets you redefine what severity means for your org without forking the scanner. The key is the exact pattern name from the [vulnerability patterns reference](./vulnerability-patterns.md).
111
+
112
+ ```json
113
+ "severity_overrides": {
114
+ "CORS Wildcard": "CRITICAL"
115
+ }
116
+ ```
117
+
118
+ This is applied before findings are reported, before notifications fire, and before PR gates are evaluated. A pattern overridden to `CRITICAL` will block a PR merge just like any built-in CRITICAL.
119
+
120
+ ---
121
+
122
+ ## Notifications
123
+
124
+ Both `webhook_url` and `slack_webhook` fire after every scan (CLI, `--ai`, and `POST /scan`).
125
+
126
+ **Webhook payload:**
127
+ ```json
128
+ {
129
+ "project": "my-project",
130
+ "org": "My Org",
131
+ "timestamp": "2026-03-26T12:00:00Z",
132
+ "duration_ms": 4200,
133
+ "summary": { "critical": 1, "high": 3, "medium": 2, "low": 0 },
134
+ "findings": [ ... ]
135
+ }
136
+ ```
137
+
138
+ **Slack message format:**
139
+ ```
140
+ 🔴 tdd-audit — my-project
141
+ 1 critical · 3 high · 2 medium
142
+ Run /caller-audit to remediate.
143
+ ```
144
+
145
+ ---
146
+
147
+ ## PR mode (`--pr`)
148
+
149
+ Designed for CI PR gates. Runs only the static scanner — no AI agents, no RAG, no fixes. Completes in under a second.
150
+
151
+ ```yaml
152
+ - run: npx @lhi/tdd-audit@latest --pr --threshold HIGH
153
+ ```
154
+
155
+ Exits non-zero if any finding meets or exceeds `severityThreshold`. Wire into your branch protection rules to block merges automatically.
156
+
157
+ Use `severity_overrides` to tune what counts as a blocker for your stack.
158
+
159
+ ---
160
+
161
+ ## Auto-fix PR (`--open-pr`)
162
+
163
+ Instead of committing fixes directly to the working branch, opens a GitHub PR per finding. Each PR contains:
164
+ - The exploit test (Red)
165
+ - The patch (Green)
166
+ - A description linking to the vulnerability pattern
167
+
168
+ Requires `GITHUB_TOKEN` in the environment or `github_token` in config.
169
+
170
+ ---
171
+
172
+ ## Watch mode (`--watch`)
173
+
174
+ ```bash
175
+ npx @lhi/tdd-audit@latest --watch
176
+ ```
177
+
178
+ Re-runs the static scanner on any modified file on save. Reports new findings immediately in the terminal. Does not run agents or apply fixes — use `/caller-audit` for that.
179
+
180
+ ---
181
+
182
+ ## SBOM (`--sbom`)
183
+
184
+ Generates a [CycloneDX](https://cyclonedx.org/) Software Bill of Materials in JSON format alongside the audit report. Output to `sbom.json` in the project root.
185
+
186
+ Required for US federal contracts (EO 14028), increasingly required in enterprise vendor questionnaires.
187
+
188
+ ---
189
+
190
+ ## Compliance report (`--format report` / `--report`)
191
+
192
+ Generates a markdown report suitable for attaching to a SOC 2 audit, ISO 27001 evidence package, or vendor security questionnaire. Includes:
193
+
194
+ - Findings summary table (severity, location, status)
195
+ - Fix evidence (exploit test name, patch commit, suite result)
196
+ - Coverage gate result
197
+ - Hardening controls applied
198
+ - SBOM reference (if generated)
199
+ - Timestamp and auditor (org/project from config)
200
+
201
+ ---
202
+
203
+ ## Org scan (`--org`)
204
+
205
+ ```bash
206
+ npx @lhi/tdd-audit@latest --org my-github-org --format report
207
+ ```
208
+
209
+ Discovers all repos in a GitHub org, runs `--pr` mode on each, and produces a cross-org summary:
210
+
211
+ ```
212
+ my-github-org security posture — 2026-03-26
213
+
214
+ ✅ repo-a 0 critical · 0 high
215
+ ⚠️ repo-b 0 critical · 2 high
216
+ 🔴 repo-c 1 critical · 4 high
217
+
218
+ 3 repos scanned · 1 critical · 6 high total
219
+ ```
220
+
221
+ Fires `webhook_url` and `slack_webhook` with the aggregate payload if configured.
222
+
223
+ ---
224
+
225
+ ## Secret rotation (`--rotate-secrets`)
226
+
227
+ When a hardcoded API key is detected, prompts to rotate it via the provider's API. Supported providers:
228
+
229
+ | Secret type | Rotation method |
230
+ |---|---|
231
+ | OpenAI key (`sk-...`) | OpenAI API — revoke + generate new key |
232
+ | Anthropic key (`sk-ant-...`) | Anthropic console link + clipboard |
233
+ | GitHub token | GitHub API — revoke token |
234
+ | Supabase service key | Supabase API — regenerate |
235
+
236
+ After rotation, updates the relevant `.env` file and removes the hardcoded value from source. The old key is invalidated whether you commit the change or not.
package/lib/auditor.js CHANGED
@@ -16,6 +16,7 @@ function loadSkillSuite(packageDir) {
16
16
  ['hardening-phase.md', path.join(packageDir, 'prompts', 'hardening-phase.md')],
17
17
  ['ai-security.md', path.join(packageDir, 'prompts', 'ai-security.md')],
18
18
  ['node-advanced-security.md', path.join(packageDir, 'prompts', 'node-advanced-security.md')],
19
+ ['security-test-patterns.md', path.join(packageDir, 'prompts', 'security-test-patterns.md')],
19
20
  ];
20
21
  const suite = {};
21
22
  for (const [name, filePath] of entries) {