Self-updating audit skill for the CaseDive project. Scans API security, test coverage, legal data quality, config hygiene, and performance. Appends findings to a persistent audit log with diff-against-history tracking.
Resources
1Install
npx skillscat add alasdairnc/casedive/casedive-audit Install via the SkillsCat registry.
CaseDive Project Audit
Invoke with
/casedive-audit. Audit only — never fix anything.
Overview
This skill performs a comprehensive audit of the CaseDive codebase across five domains: API/Security, Testing, Legal Data, Config/Docs, and Performance. It tracks findings over time in a persistent append-only log and diffs each run against previous results to surface what is new, what is still open, and what has been fixed.
When to Use This Skill
Activate this skill when:
- Running a periodic health check of the CaseDive codebase
- Preparing for a deploy and wanting a pre-flight audit
- Checking whether previously logged issues have been resolved
- Reviewing security posture of all API endpoints
Model and Effort
- Recommended model: Opus 4.6
- Effort level: high
- Budget: 3-5 minutes
Constraints
- Audit only — do not fix, refactor, or modify any application code
- Never overwrite previous entries in
AUDIT_LOG.md— only append - Use Explore subagent at "very thorough" level for Phase 2 investigation
- Report file + line number for every finding
- Do not invent issues not actually found in the code
Execution Phases
Phase 1 — Load History
- Read
.claude/skills/casedive-audit/AUDIT_LOG.mdfrom the project root. - Parse all previously logged issues and their status tags:
FIXED,OPEN,WONT_FIX. - Build an internal tracking list of prior findings keyed by issue description.
Phase 2 — Investigate
Launch an Explore subagent at very thorough level. Run the following checks in parallel where possible. For every finding, record the file path and line number.
API / Security
- Rate limiting buckets: Verify every
api/*.jsfile uses rate limiting with a named bucket (not a default/unnamed bucket). Check the_rateLimit.jsimport and the bucket string argument. - CORS import: Verify every
api/*.jsfile imports CORS handling fromapi/_cors.js(not inline CORS headers). Flag any file that sets CORS headers directly. - Security headers: Verify every
api/*.jsfile sets all three security headers:X-Content-Type-Options,X-Frame-Options,Referrer-Policy, and aContent-Security-Policyheader. - vercel.json coverage: Verify
vercel.jsonhas afunctionsconfig entry for every.jsfile in theapi/directory (excluding_-prefixed internal modules). - Fetch timeouts: Verify no
api/*.jsfile makes an externalfetch()call withoutAbortSignal.timeout()or an equivalent abort controller with a timeout. - Model ID source: Verify every
api/*.jsfile that calls the Anthropic API imports the model ID fromapi/_constants.js— flag any file where the model string is hardcoded inline. - Component env reads: Verify no
src/components/*.jsxfile readsprocess.envdirectly — all model/API calls must be server-side only.
Testing
- Component E2E coverage: List every
src/components/*.jsxfile that has zero corresponding E2E test coverage (no test file references the component). - Lib unit coverage: List every
src/lib/*.jsfile that has zero corresponding unit test file. - Playwright mobile profiles: Check
playwright.config.js(or equivalent) for whether mobile device profiles (e.g.,iPhone,Pixel, or Playwrightdevices[...]) are configured.
Legal Data
- Criminal Code placeholders: Scan
src/lib/criminalCodeData.jsfor entries whose summary or description contains placeholder text (e.g.,"TODO","placeholder","TBD","...", or suspiciously short/generic descriptions). - Civil law placeholders: Same check on
src/lib/civilLawData.js. - Charter placeholders: Same check on
src/lib/charterData.js.
Config / Docs
- Stale root .md files: Identify any root-level
.mdfiles that appear to be stale audit reports, migration logs, or deployment checklists (by name or content). - Unlinked skills: Check whether any files in the
.claude/skills/folder tree are not referenced or linked from.claude/skills/index orCLAUDE.md. - CLAUDE.md roadmap accuracy: Compare the "Roadmap Status" section in
CLAUDE.mdagainst actual code state — flag any item marked "Completed" that appears missing in code, or any shipped feature not reflected in the roadmap. - package.json package manager: Check whether the
packageManagerfield inpackage.jsonis present and matches the lock file actually in the repo (package-lock.json,yarn.lock,pnpm-lock.yaml). - A11y ARIA Labels: Verify that all interactive
<button>and<a>tags insrc/components/*.jsxhave proper semantic text oraria-labelattributes for accessibility.
Performance
- Uncached endpoints: Identify which
api/*.jsendpoints (excluding_-prefixed internal modules) have no Redis caching (get/setcalls via Upstash or similar). - Redis operation timeouts: Check
_rateLimit.jsfor whether Redis operations have explicit timeouts (e.g.,AbortSignal.timeout(),Promise.racewith a timeout, or a library-level timeout config). - Strict Cache TTLs: Verify that every Redis caching call in
api/*.jsexplicitly enforces a.setex(Time-To-Live) rather than a boundless.set, preventing persistent database bloat. - Vite Chunk Configuration: Check
vite.config.jsto ensuremanualChunksremains declared, maintaining strict vendor splitting for React dependencies rather than compiling them into the main entrypoint.
Phase 3 — Diff Against History
Compare every finding from Phase 2 against the history loaded in Phase 1:
- If a finding matches an issue previously logged as
OPENand it still exists → tag it[STILL OPEN] - If an issue was previously logged as
OPENbut the problem is no longer present in the code → tag it[FIXED -- auto-detected] - If a finding is not in the history at all → tag it
[NEW]
Phase 4 — Output Prioritized Action Plan
Group all findings by severity using this rubric:
| Severity | Criteria |
|---|---|
| Critical | Security vulnerability or production outage risk |
| High | Correctness bug or missing test for a core flow |
| Medium | Maintainability issue or operational risk |
| Low | Cleanup, docs, or tooling improvement |
Output a single markdown table with all findings:
| # | Status | Issue | File:Line | Severity |
|---|---|---|---|---|
| 1 | [NEW] | Missing rate limit bucket name in export-pdf.js | api/export-pdf.js:14 | Critical |
| 2 | [STILL OPEN] | No E2E test for CaseSummaryModal | src/components/CaseSummaryModal.jsx | High |
(The above are examples only — use actual findings.)
Phase 5 — Append to AUDIT_LOG.md
Open .claude/skills/casedive-audit/AUDIT_LOG.md and append (never overwrite) a new dated section at the end of the file:
## Audit — YYYY-MM-DD
### Fixed since last run
- [item description]
### New findings
- [item description] | severity | file:line
### Still open
- [item description] | severity | file:lineUse today's date. If there are no items in a subsection, write - None.
Best Practices
Do
- Run this audit before major deploys or after large feature merges
- Review the action plan table and triage items into your backlog
- Use the AUDIT_LOG.md history to track resolution velocity over time
- Re-run after fixing issues to auto-detect resolutions
Don't
- Don't use this skill to make code changes — it is read-only
- Don't manually edit AUDIT_LOG.md entries from previous runs
- Don't skip Phase 1 history loading — the diff tracking is the core value
- Don't treat Low-severity items as ignorable — they compound
This skill was created for the CaseDive project (casedive.ca). Maintained by Alasdair NC.