---
name: audit-fix
description: >
  Closes the loop the audits leave open: runs them, attaches each finding's
  REMEDY from the shared registry (`lib/remediation.ts`), executes the
  correctors that already exist (the `derive-*` CLIs in write mode, the audit
  CLIs' own `--mode apply`), re-runs the audits, and reports the delta —
  closed / persisting / INTRODUCED. It implements no fix of its own and never
  guesses: a finding that needs a business decision is handed off to the
  `create-*` skill that owns the document, by name. Use for « corrige l'audit »,
  « applique les corrections », « ferme les findings », or right after
  `/ba-audit-run` or an `audit-dev-*` gate.
argument-hint: "[APP/MODULE] [--plan] [--lanes derive,rewrite] [--rules RBAC-008,...]"
allowed-tools: [Read, Glob, Grep, Bash]  # Bash: the audit-fix CLI (deterministic router)
---

# /audit-fix — the remediation router

The audits say WHAT is broken. Three families of corrector already know how to
repair parts of it. Nothing connected them. This skill is that connection —
**it is a router, not a fixer**: every correction it applies is performed by a
CLI that already existed.

## What it runs, and what it refuses to run

| Lane | Executed | What happens |
|---|---|---|
| `derive` | ✅ 1st | A `derive-*` CLI in write mode. Idempotent splice of an anchored machine block; human content preserved. |
| `scaffold` | ❌ reported | Re-running the generator IS the right remedy — but a scaffolder's spec (entity, views, fields, permission) cannot be synthesised from a finding. The router names the `fixSkill` and the scope; you run it. |
| `rewrite` | ✅ 3rd | The PRODUCING audit's own `--mode apply` — today `audit-dev-frontend`, the one audit CLI whose apply really rewrites source. Keyed by the audit, never by `fixSkill`: `autoFixable` means *the CLI that found this can repair it*, while `fixSkill` names a generator to re-run. |
| `authoring` | ❌ routed | A content decision. Handed to the `create-*` skill that owns the document's grammar. A router that edited the markdown itself would re-introduce the form drift those skills exist to prevent. |
| `manual` | ❌ named | No known remedy. Listed, never hidden. |

**The order is a constraint, not a preference.** A mechanical rewrite applied
before a regeneration is simply overwritten by it.

## Non-negotiables

- **Never destroys.** No recursive delete, no `git clean`, no directory
  removal. Deleting BA content belongs to `/ba-reconcile-menu`, which validates
  interactively.
- **Never commits.** It mutates the tree; you review `git diff` and commit
  through `/gitflow commit`.
- **Never guesses.** Every `derive-*` CLI fails closed on the cases it must not
  invent (`needsJudgment` / `unresolved` / `blocked`). The router forwards that
  refusal — it becomes an authoring hand-off, not a silent write.
- **Never reports a skipped surface as clean.** A source that could not run
  comes back `skipped`/`failed` with a reason and exit 3, never as "0 finding".
- **Refuses a dirty worktree** when writing (`allowDirty` to override): the git
  diff is the guardrail, and a diff mixing this run with pre-existing edits is
  not reviewable.

## How to run it

Always: **audit → apply → read the diff.**

```bash
# 1. See the plan without writing anything (safe on any tree)
npx --prefer-offline tsx skills/audit-fix/cli/audit-fix/index.ts \
  --spec '{"baRoot":".smartstack/ba","scope":{"app":"<APP>","module":"<MODULE>"}}'

# 2. Apply, then re-audit and report the delta (clean worktree required)
npx --prefer-offline tsx skills/audit-fix/cli/audit-fix/index.ts \
  --spec '{"baRoot":".smartstack/ba","scope":{"app":"<APP>","module":"<MODULE>"},"apply":true}'

# 3. With the generated app, to add the audit-dev-* sources
npx --prefer-offline tsx skills/audit-fix/cli/audit-fix/index.ts \
  --spec '{"baRoot":".smartstack/ba","projectRoot":"<abs path>","scope":{"app":"<APP>","module":"<MODULE>"},"apply":true}'
```

### Spec

| Field | Meaning |
|---|---|
| `baRoot` | BA corpus root. Enables the `audit-ba` source and the PRD check engines. |
| `projectRoot` | Generated app root. Enables the four `audit-dev-*` sources (they also need `scope.app` + `scope.module`). |
| `webRoot` | Web root override; defaults to `<projectRoot>/web/<app>-web`. |
| `scope` | `{app, module}`. Required by every dev + PRD source. |
| `apply` | Write. **Defaults to false** — a bare invocation shows the plan. |
| `lanes` | Restrict execution, e.g. `["derive"]`. |
| `rules` | Restrict to given rule codes. |
| `allowDirty` | Write into a dirty worktree. |
| `skipReaudit` | Skip the second pass (no delta). |

### Exit codes

`0` nothing left this router could execute · `1` work remains (hand-offs, or a
plan-only pass) · `2` a REGRESSION was introduced or a corrector run failed ·
`3` a source failed — a surface was not audited · `4` usage.

## Reading the result

Work through the envelope's `nextSteps` in order. Three things deserve real
attention:

1. **`report.delta.introduced`** — findings that did NOT exist before the run.
   This is the point of re-auditing. Inspect them before committing; a remedy
   that opens a new hole is worse than the hole it closed.
2. **`report.sources[]` with `status: "failed"`** — that surface was never
   looked at. Do not read the rest of the report as coverage.
3. **`report.routed[]`** — the authoring hand-offs. Run the named `create-*`
   skill on that scope in ENRICH mode, feeding it the findings and their
   evidence from `report.findings` — **never the raw corpus** (re-reading the
   documents to re-apply rules by hand is the 394M-token shape the
   `ba-audit-guard` hook blocks).

Then: `git diff`, and `/gitflow commit`.

## What it does not cover (v1)

- `audit-dev-core` / `-data` / `-domain` have no CLI, so their findings cannot
  reach the router. Their rules do carry a `fixSkill` in prose.
- The `rewrite` lane is limited to what `audit-dev-frontend --mode apply`
  already does mechanically — there is no AST editor for C# or for fenced
  pagespec blocks. `ui-polish` is reached through `/ui-components`, not here.
- On the PRD side only the rules backed by a `derive-* --mode check` engine are
  reachable; `report.sources[]` names the ones deliberately not probed.
