Audit triage
How to run the periodic standing-codebase-health audit in the whiteboard repo — fan out auditors across health dimensions, adversarially verify, triage into Tasks/tmp-issues. Use when scheduling or running a periodic review (after a fold, weekly, pre-milestone) for unwired/incomplete features, architecture debt, maintainability, contract drift, test gaps, and dev-experience friction. Not for reviewing a single diff (that is the review workflow).From its SKILL.md
npx -y skills add kamiazya/whiteboard --skill audit-triageAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 5 stars5 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
7.4 KB, as published. Nobody here has run it
Audit-Triage (whiteboard)
The per-diff review workflow only sees a change. Standing problems — a feature that builds but isn't wired (the Cloudflare-shell class), a god module, a contract defined twice, a critical path with no test, onboarding that breaks on a clean clone — never show up in a diff. audit-triage is the recurring sweep that finds them and turns them into tickets.
Run it
Workflow({ scriptPath: '.claude/workflows/audit-triage.workflow.mjs',
args: { scope?, dimensions?, cwd?, auditorAgent?, verifyFloor? } })
- scope: free-text area to focus (e.g.
"apps/web and its migration") or omit for the whole repo. Narrow the scope for a faster, deeper pass on a hot area. - dimensions: defaults to the six below. Pass a subset to focus, or supply
{name, content}objects to inject externalized criteria (see below). Legacy plain-string dimensions are still supported. - auditorAgent: defaults to
Explore(read-only, always registered). The tunedcodebase-auditoragent is NOT registered until a session reload (see theworkflow-authoringskill's mid-session-agent-registration gotcha) — passauditorAgent: 'codebase-auditor'only after a reload. - verifyFloor: lowest severity that gets an adversarial verify pass (default
HIGH). Verification kills false positives — the audit favors recall, verify restores precision.
It returns triaged.items[] (read-only), plus coverage-honesty fields: dimensionsAudited (dimensions that actually produced a result), failedDimensions (a dimension's auditor agent returned nothing — a LOW coverage-gap advisory finding is also injected into triaged so a silent gap can't hide), and notApplicable (an auditor explicitly opted out via notApplicable:true because the dimension doesn't apply to this scope). Check failedDimensions before trusting a clean run. The workflow cannot create Tasks — the integrator (main session) files the survivors.
The six dimensions
wiring-gaps (looks-done-isn't) · architecture (seams/coupling) · maintainability (size/dup/dead-code) · contract-drift (hand-written-vs-Zod, casts) · test-gaps (untested critical paths, skips) · dev-experience (clean-clone friction).
A seventh, ai-assets (drift within the .claude/ asset ecosystem itself —
stale cross-references, frontmatter validity, skill/agent overlap, naming
consistency, coverage gaps), is available as an opt-in resources/*.md
dimension (see below). It is not part of the embedded six-dimension default
in audit-triage.workflow.mjs — pass it explicitly via the externalized
{name, content} mechanism when auditing the tooling itself.
Externalized criteria (resources/*.md)
Each dimension's detailed criteria lives in .claude/skills/audit-triage/resources/<dimension>.md (Title-Case # <Name> heading + ## Criteria + numbered checks), not embedded only in .claude/agents/codebase-auditor.md. To run with the authoritative externalized criteria:
Glob('.claude/skills/audit-triage/resources/*.md').Readeach file; derivenamefrom the filename (kebab-case, minus.md— e.g.contract-drift.md->contract-drift), not the Title-Case#heading. This keepsnamematching the canonical kebab-case dimension identifiers used everywhere else (the default dimension list, theFINDING.kindvalues,dimensionsAudited/failedDimensions/notApplicable). Use the full file body ascontent.- Pass
args.dimensions = [{name, content}, ...](a subset is fine — narrow to the dimensions relevant to this run).
Workflow scripts have no filesystem access — the workflow cannot glob/read resources/*.md itself. The launching session (this skill's caller) must do the glob+read and pass content through args; that is why the mechanism accepts {name, content} objects rather than a directory path.
.claude/agents/codebase-auditor.md still carries its own embedded summary of the six dimensions as a legacy fallback (used when a caller passes plain dimension strings, or omits dimensions entirely). This is a deliberate duplication, not an oversight: resources/*.md is authoritative when content is supplied; the agent's embedded text is only the safety-net default.
Ad-hoc dimensions
The launching session is not limited to the resource pack. For a run scoped
to something the standing dimensions don't cover well (e.g. "audit only the
websocket reconnection logic" or "audit the release-please config"),
synthesize a target-specific {name, content} dimension on the fly — same
# <Name> + ## Criteria + numbered-checks shape as a resources/*.md
file — and pass it in args.dimensions alongside (or instead of) the base
resource dimensions.
After the run, review triaged.items[] grouped by dimension: an ad-hoc
dimension that produced real, verified findings (survived verifyFloor) is
a candidate worth keeping for future runs. Offer it to the user for
persistence as a new .claude/skills/audit-triage/resources/<name>.md file
using the same structure. Only persist on explicit user approval —
an ad-hoc dimension that found nothing this run, or that duplicates an
existing resource, should not be added.
Severity rubric (precision over recall)
| Severity | Means | Default track |
|---|---|---|
| CRITICAL | broken/unwired user capability, data-loss/security risk | task |
| HIGH | real bug, missing critical test, architecture decision causing ongoing pain | task |
| MEDIUM | maintainability/clarity debt | issue |
| LOW | minor | issue (or drop) |
A wall of LOWs buries the HIGHs — do not inflate. A false HIGH wastes triage; that's why HIGH+ is adversarially verified before it reaches the backlog.
Filing the result (integrator)
For each triaged.items[i]:
track: "task"→TaskCreateon the live board (setblockedBy/relatedTofrom the item). Do soon.track: "issue"→ atmp/issues/<slug>.mdwith the ticketing frontmatter (see theticketingskill). Durable backlog.- Skip dupes of existing Tasks / tmp-issues (the triage agent flags
relatedTo, but check the board yourself — it can't see it). - Quick wins (effort
S, a few lines) that are safe and in-scope: per the resolve-on-the-spot discipline, just fix them now instead of filing.
Cadence
Run it after each fold/merge of a substantial slice, and/or weekly, and before a milestone/release. It can be scheduled with CronCreate (autonomous loop) or ScheduleWakeup, but keep a human in the loop on the filing step — auto-creating dozens of tasks unattended is noise. Prefer: scheduled run → integrator reviews triaged → files the real ones.
Discipline
- Read-only: auditors and verifiers never edit.
- Don't double-file: reconcile against the existing Task list +
tmp/issues/before creating. - Trust runtime: if an audit finding disagrees with what the running app/test actually does, the runtime wins — verify before filing.