---
name: ba-audit-run
description: >
  ONE deterministic pass over the whole `.smartstack/ba/` corpus — the
  audit-ba CLI loads every doc once, runs the ~115 MECHANICAL audit rules of
  all 11 dimensions (menu, sections, actors, use-cases, rules, rbac,
  data-model, screens, cross-dimension, cross-ref-code, sources), publishes the parse
  totals, writes every `_audit/<dim>.md` verdict and `_audit/audit-ba.json`,
  and FAILS CLOSED on parser/control divergence (exit 3 « parsing suspect »).
  The LLM's only job here is arbitrating the compact `judgmentNeeded[]`
  excerpts (~9 judgment rules + hybrid arbitrations) — NEVER re-reading the
  corpus. Use for « audite le BA », « audit complet », « relance l'audit
  après mise à jour des skills ». Replaces the per-module LLM audit campaign
  (394M tokens on ImmoHub) for every mechanical rule.
argument-hint: "[APP[/MODULE]] [--strict] [--project-root <dir>]"
allowed-tools: [Read, Write, Glob, Bash]
---

# ba-audit-run — deterministic whole-project BA audit

## The iron rule — NEVER audit by reading the corpus

**You MUST NOT apply audit rules by reading `use-case.md` / `entité.md` /
`règles-métier.md` / `rbac.md` / `screen.md` yourself, and you MUST NOT spawn
subagents to do it per module.** That is the 394-million-token incident shape:
21 agents × 240k context per call for rules a CLI evaluates in seconds. The
CLI is the ONLY sanctioned evaluator of the mechanical rules; your judgment is
needed ONLY on the `judgmentNeeded[]` excerpts it hands you.

## Workflow

1. **Run the CLI** (whole project by default; scope with `{"scope":{"app":…,"module":…}}`):

   ```bash
   npx --prefer-offline tsx skills/business-analyse/audit-run/cli/audit-ba/index.ts \
     --spec '{"baRoot":".smartstack/ba","projectRoot":"."}' [--workdir <dir>]
   ```

   Pass `projectRoot` whenever the generated app lives in the working
   directory — without it the cross-ref-code scan legs surface a warn
   (« code non scanné »), never a false green.

2. **Read the envelope** (stdout JSON). Exit codes:
   - `0` conforme · `1` warn-only · `2` ≥1 err — the audit RAN, findings are
     in `report.findings[]` and the verdicts are written;
   - `3` **parsing suspect** — STOP. A control counter disagrees with the
     parser (`report.parseControl.perDoc`). NEVER « complete by hand », never
     read the corpus to compensate: fix the doc's form or report the parser
     bug, then re-run. No green verdict may be born from a silent parser.
   - `4` usage/spec error.

   Read `warnings[]` too. **`audit.rule-contradiction`** means the run
   disagrees with ITSELF: a finding whose `dedupOf` names a primary rule
   (same evaluator, two ids) is `err` while that primary is `ok` on the same
   scope. That is a defect of this CLI, never of the corpus — do NOT edit
   the document (nor invent an entity) to silence the mirror: record the
   blocker as `audit.rule-contradiction` and hand the envelope to
   `/support-report`, which classifies it `rule-contradiction` from the same
   detector (lib/rule-contradictions) and bundles the corpus for reproduction.

3. **Arbitrate the judgments** — for each `report.judgmentNeeded[]` entry,
   decide from its `question` + `excerpts` ONLY (they are complete by
   contract; if they are not enough, that is a CLI bug to report, not a
   license to read the corpus). Write your decisions to a scratchpad file:

   ```json
   { "decisions": [ { "ruleId": "UC-011", "dimension": "use-cases",
       "scope": { "app": "CRM", "module": "PIPELINE" },
       "resolution": "ok|warn|err", "message": "…", "evidence": ["…"] } ] }
   ```

4. **Re-run with the decisions** — the CLI merges them, consumes the pending
   items and rewrites the final verdicts itself (the LLM never writes verdict
   markdown):

   ```bash
   npx --prefer-offline tsx skills/business-analyse/audit-run/cli/audit-ba/index.ts \
     --spec '{"baRoot":".smartstack/ba","projectRoot":".","judgments":"<path>"}'
   ```

5. **Chat summary** (3–6 lines, business terms): parse totals (say the counts
   — that is how a « 0 erreur » is verifiable), err/warn counts, conventions
   detected (CONV-001/002), remaining judgments, and the next step
   (`/ba-create-*` skills named by the findings, or `/ba-audit-pre-dev`).

## What the CLI writes (atomic, only under `_audit/`)

- `.smartstack/ba/_audit/audit-ba.json` — the machine record: totals,
  findings, judgmentNeeded, parseControl, conventions, `rulesetVersion` +
  `sourcesHash` (STALENESS: a verdict whose anchor carries an older ruleset
  or a different sources hash predates the current corpus/rules — re-run,
  it costs a minute).
- Per-dimension `_audit/<dim>.md` verdicts at the existing locations
  (actors at the project root, menu per app, the rest per module — screens
  now MODULE-level; delete legacy per-section `screen.md` verdicts, the
  envelope warns about them).
- `.smartstack/ba/_audit/audit-ba.md` — project summary (conventions,
  project-scope findings).

## Conventions (requirement: the tooling adapts to the corpus)

A ≥90 % measured corpus convention (lowercase UC section segments, flat-kebab
error codes) is ONE project-scoped warn (CONV-001/002), never an error per
occurrence — BR-011 defers to CONV-002. `--strict` (spec `"strict":true`)
restores the per-occurrence letter of the rules.

## Relationship with the per-dimension skills

The `/ba-audit-*` skills remain the JUDGMENT layer: invoked on one dimension,
they run THIS CLI scoped (`"dimensions":["use-cases"]`), arbitrate their
dimension's `judgmentNeeded[]`, and finalize via `judgments`. They never
re-evaluate a mechanical rule. `/ba-audit-pre-dev` keeps reading the written
verdicts unchanged.
