/audit
Runs the multi-agent fan-out + adversarial-verify audit pattern that produced `ide/docs/internal/optimization-audit-2026-06.md` — codified as a reusable, parameterizable Workflow (`.claude/workflows/forensic-audit.js`), so it no longer has to be re-derived by hand each time.
$ npx -y skills add joewinke/jat --agent claude-codeHow it fires
How this command gets triggered: by you, by Claude, or both.
- Fires itselfClaude auto-loads it when your prompt matches the work.
- You can call itInvoke it directly when you want it.
- Slash command
/audit
Context preview
What this command does when you run it.
Runs the multi-agent fan-out + adversarial-verify audit pattern that produced `ide/docs/internal/optimization-audit-2026-06.md` — codified as a reusable, parameterizable Workflow (`.claude/workflows/forensic-audit.js`), so it no longer has to be re-derived by hand each time.
Command definition
audit.mdargument-hint: [target|task-id] [--scope epic|project|task] [--depth quick|standard|deep] [--auto-scope] [--no-verify] [--file-tasks] [--label NAME] [--dimensions N] [--report-dir DIR] [--focus TEXT]
/jat:audit — Forensic Fan-Out Audit
Runs the multi-agent fan-out + adversarial-verify audit pattern that produced `ide/docs/internal/optimization-audit-2026-06.md` — codified as a reusable, parameterizable Workflow (`.claude/workflows/forensic-audit.js`), so it no longer has to be re-derived by hand each time. Scoped reviewers each forensically read code in one dimension and cite file:line evidence for every claim; adversarial verifiers then re-open every cited file and try to refute each finding before it counts. Survivors get themed, scored, written up as a report, and (optionally) filed as tracked tasks through the audit intake.
**Use this when:** the user wants a deep, evidence-based audit of a codebase area (performance, architecture, security, dead capability, or a custom set of dimensions) — not a lint pass, not `/jat:hygiene` (dead-code cleanup), not `/jat:security` (stack-specific security-only sweep).
**This is a Workflow-tool call, not a from-scratch investigation.** The whole point of codifying the pattern is that invoking it here is the sanctioned opt-in path (see the Workflow tool's own admission rule: "the user invoked a skill or slash command whose instructions tell you to call Workflow"). Compose the args below and call `Workflow`; do not hand-roll the fan-out yourself.
**Two callers, one command.** A human types a path; the in-app "Audit / Review this" launcher (`jat-yh7f8.5`) spawns an agent straight onto this command, where the target is a task/epic/project ID rather than a path. STEP 1 handles both — do not assume the positional is a directory.
⚠️ The launcher's argv is not what the launcher composed
`buildAuditCommand()` produces `/jat:audit <targetId> --scope S --depth D`, but the spawner **appends the agent name and the minted task ID** to whatever command it is given (`spawn/+server.js` → ``${taskCmd} ${agentName} ${taskId}``, the same convention that makes `/jat:start AgentName task-id` work). So what actually arrives is:
/jat:audit jat-yh7f8 --scope epic --depth standard DimCove891 jat-3k9x2
└ target ┘ └──── flags ─────────────┘ └─ agent ─┘ └─ task ─┘
appended by the spawnerRead it that way: **first** positional is the audit target; the **last two** trailing bare words (when present) are your agent name and the minted audit task, not additional targets. That is convenient rather than annoying — they are exactly the `$AGENT_NAME` and `$TASK_ID` STEP 0A needs. Treating them as targets, however, sends reviewers hunting for a directory named after an agent.
---
STEP 0 — Are you the session, or a step inside one?
| Situation | What you own | |---|---| | This is the **first prompt of the session** (the launcher or a spawner booted you onto this command instead of `/jat:start`) | The **whole task lifecycle**. Do STEP 0A below, then the audit, then finish with a `review` signal per STEP 6. | | You are **already working a task** and are calling this as a tool | Just the audit. Emit **no** lifecycle signals for it — you are mid-task, and a stray `review` would flip your session state. Skip STEP 0A and STEP 6's signal; report inline instead. |
STEP 0A — Lifecycle (spawned-onto case only)
The launcher already minted the task and wrote the parameters into its description, so read them rather than inferring from argv alone — the brief carries `Focus` and the depth's own description, and argv carries neither:
jt show "$TASK_ID" --json # $TASK_ID = the minted audit task you were spawned for
Then declare scope and announce, the same as `/jat:start` Round 3 — the report path is the file you will write, so declare that:
jt update "$TASK_ID" --status in_progress --assignee "$AGENT_NAME" --files "<report-dir>/**"
jat-signal working '{"taskId":"'"$TASK_ID"'","taskTitle":"...","approach":"Forensic fan-out audit of <target>, <N> reviewers, verify on/off","files":["<report-dir>/**"]}'An audit **reports; it does not fix.** Do not change code under this command. Fixes leave as filed tasks or `suggestedTasks`, never as edits.
STEP 1 — Resolve the target
The positional is either a repo-relative path (human invocation) or a JAT ID (launcher invocation, always accompanied by `--scope`).
**If `--scope` is absent and the positional looks like a path** (contains `/`, or names a real directory) → it *is* the target. Skip to STEP 2.
**Otherwise resolve the ID to a filesystem target:**
| `--scope` | How to resolve | |---|---| | `task` | `jt show <id> --json` → `.reserved_files` (comma-separated) or `.file_footprint`. That is the target. If both are empty, fall back to the paths named in the description; if the description names none, the audit has no footprint to read — say so and ask before auditing the whole repo. | | `epic` | `jt show <id> --json` → collect `reserved_files` / `file_footprint` from the epic **and every child** in `.blocked_by`. Union them. Same fallback rule. | | `project` | The positional is a project key. `jt show` is not the right tool — read `project_path` from any task in that project, or `~/.config/jat/projects.json`. Target is that repo root. |
Pass the union as `target` when it is a single path, or as a newline-joined list inside one `target` string when it is several — the reviewers read it as "audit these paths". Set `label` from the ID (`jat-yh7f8` → `jat-yh7f8`) so the report filename traces back to what was audited.
⚠️ **A resolved-to-nothing target is not an empty audit.** If resolution produces no paths, stop and say so — running the default `ide/` target instead would produce a confident report about code the user did not ask about.
STEP 2 — Parse the remaining arguments
| Flag | Default | Meaning | |---|---|---|
Read more
argument-hint: [target|task-id] [--scope epic|project|task] [--depth quick|standard|deep] [--auto-scope] [--no-verify] [--file-tasks] [--label NAME] [--dimensions N] [--report-dir DIR] [--focus TEXT]
/jat:audit — Forensic Fan-Out Audit
Runs the multi-agent fan-out + adversarial-verify audit pattern that produced `ide/docs/internal/optimization-audit-2026-06.md` — codified as a reusable, parameterizable Workflow (`.claude/workflows/forensic-audit.js`), so it no longer has to be re-derived by hand each time. Scoped reviewers each forensically read code in one dimension and cite file:line evidence for every claim; adversarial verifiers then re-open every cited file and try to refute each finding before it counts. Survivors get themed, scored, written up as a report, and (optionally) filed as tracked tasks through the audit intake.
**Use this when:** the user wants a deep, evidence-based audit of a codebase area (performance, architecture, security, dead capability, or a custom set of dimensions) — not a lint pass, not `/jat:hygiene` (dead-code cleanup), not `/jat:security` (stack-specific security-only sweep).
**This is a Workflow-tool call, not a from-scratch investigation.** The whole point of codifying the pattern is that invoking it here is the sanctioned opt-in path (see the Workflow tool's own admission rule: "the user invoked a skill or slash command whose instructions tell you to call Workflow"). Compose the args below and call `Workflow`; do not hand-roll the fan-out yourself.
**Two callers, one command.** A human types a path; the in-app "Audit / Review this" launcher (`jat-yh7f8.5`) spawns an agent straight onto this command, where the target is a task/epic/project ID rather than a path. STEP 1 handles both — do not assume the positional is a directory.
⚠️ The launcher's argv is not what the launcher composed
`buildAuditCommand()` produces `/jat:audit <targetId> --scope S --depth D`, but the spawner **appends the agent name and the minted task ID** to whatever command it is given (`spawn/+server.js` → ``${taskCmd} ${agentName} ${taskId}``, the same convention that makes `/jat:start AgentName task-id` work). So what actually arrives is:
/jat:audit jat-yh7f8 --scope epic --depth standard DimCove891 jat-3k9x2
└ target ┘ └──── flags ─────────────┘ └─ agent ─┘ └─ task ─┘
appended by the spawnerRead it that way: **first** positional is the audit target; the **last two** trailing bare words (when present) are your agent name and the minted audit task, not additional targets. That is convenient rather than annoying — they are exactly the `$AGENT_NAME` and `$TASK_ID` STEP 0A needs. Treating them as targets, however, sends reviewers hunting for a directory named after an agent.
---
STEP 0 — Are you the session, or a step inside one?
| Situation | What you own | |---|---| | This is the **first prompt of the session** (the launcher or a spawner booted you onto this command instead of `/jat:start`) | The **whole task lifecycle**. Do STEP 0A below, then the audit, then finish with a `review` signal per STEP 6. | | You are **already working a task** and are calling this as a tool | Just the audit. Emit **no** lifecycle signals for it — you are mid-task, and a stray `review` would flip your session state. Skip STEP 0A and STEP 6's signal; report inline instead. |
STEP 0A — Lifecycle (spawned-onto case only)
The launcher already minted the task and wrote the parameters into its description, so read them rather than inferring from argv alone — the brief carries `Focus` and the depth's own description, and argv carries neither:
jt show "$TASK_ID" --json # $TASK_ID = the minted audit task you were spawned for
Then declare scope and announce, the same as `/jat:start` Round 3 — the report path is the file you will write, so declare that:
jt update "$TASK_ID" --status in_progress --assignee "$AGENT_NAME" --files "<report-dir>/**"
jat-signal working '{"taskId":"'"$TASK_ID"'","taskTitle":"...","approach":"Forensic fan-out audit of <target>, <N> reviewers, verify on/off","files":["<report-dir>/**"]}'An audit **reports; it does not fix.** Do not change code under this command. Fixes leave as filed tasks or `suggestedTasks`, never as edits.
STEP 1 — Resolve the target
The positional is either a repo-relative path (human invocation) or a JAT ID (launcher invocation, always accompanied by `--scope`).
**If `--scope` is absent and the positional looks like a path** (contains `/`, or names a real directory) → it *is* the target. Skip to STEP 2.
**Otherwise resolve the ID to a filesystem target:**
| `--scope` | How to resolve | |---|---| | `task` | `jt show <id> --json` → `.reserved_files` (comma-separated) or `.file_footprint`. That is the target. If both are empty, fall back to the paths named in the description; if the description names none, the audit has no footprint to read — say so and ask before auditing the whole repo. | | `epic` | `jt show <id> --json` → collect `reserved_files` / `file_footprint` from the epic **and every child** in `.blocked_by`. Union them. Same fallback rule. | | `project` | The positional is a project key. `jt show` is not the right tool — read `project_path` from any task in that project, or `~/.config/jat/projects.json`. Target is that repo root. |
Pass the union as `target` when it is a single path, or as a newline-joined list inside one `target` string when it is several — the reviewers read it as "audit these paths". Set `label` from the ID (`jat-yh7f8` → `jat-yh7f8`) so the report filename traces back to what was audited.
⚠️ **A resolved-to-nothing target is not an empty audit.** If resolution produces no paths, stop and say so — running the default `ide/` target instead would produce a confident report about code the user did not ask about.
STEP 2 — Parse the remaining arguments
| Flag | Default | Meaning | |---|---|---|
Agents ship, suggest, repeat. You supervise — or they run on their own. JAT is the complete, self-contained environment for agentic development. Task management, agent orchestration, code editor, git integration, terminal access—all unified in a single IDE.
Repo: joewinke/jat
Other commands on jat.
- /adapt
/home/jw/code/jat/.agents/skills/adapt//SKILL.md
Open command - /animate
/home/jw/code/jat/.agents/skills/animate//SKILL.md
Open command - /arrange
/home/jw/code/jat/.agents/skills/arrange//SKILL.md
Open command - /bolder
/home/jw/code/jat/.agents/skills/bolder//SKILL.md
Open command - /clarify
/home/jw/code/jat/.agents/skills/clarify//SKILL.md
Open command - /colorize
/home/jw/code/jat/.agents/skills/colorize//SKILL.md
Open command

