---
name: ba-audit-use-cases
description: >
  Audits the use cases of a `.smartstack/ba/` module — completeness, step
  quality, vague language, scope respect, actor references, redundancy,
  acceptance-criteria contract, exception ↔ AC parity, and — at app/project
  scope only — cross-application similarity (warn) (UC-001..023).
  Reads the section `use-case.md` files + the app `acteur.md` + the module
  `entité.md` (for AC entity refs); the exception-parity rule (UC-022) runs
  DETERMINISTICALLY through the derive-uc-coverage CLI. Writes a verdict to
  `<MODULE>/_audit/use-case.md`. Run after `/ba-create-use-case` or as part
  of pre-dev readiness.
allowed-tools: [Read, Write, Glob, Grep, Bash]
---

# ba-audit-use-cases — Use Cases audit

You audit the use cases of a `.smartstack/ba/` module against the rules below and
write a verdict file. The rules are unchanged from the SmartStack convention;
only the I/O is file-based.

## Deterministic engine — how this audit runs

The MECHANICAL rules of this dimension are evaluated by the shared `audit-ba`
CLI (see `/ba-audit-run`) — **never by reading the corpus yourself, never by
spawning per-module subagents** (the 394M-token incident shape). Your only
job here is the judgment residue.

1. **Run the engine, scoped to this dimension**:

   ```bash
   npx --prefer-offline tsx skills/business-analyse/audit-run/cli/audit-ba/index.ts \
     --spec '{"baRoot":".smartstack/ba","scope":{"app":"<APP>","module":"<MODULE>"},"dimensions":["use-cases"]}'
   ```

2. **Exit 3 = parsing suspect -> STOP.** A control counter disagrees with the
   parser (`report.parseControl.perDoc`): fix the doc's form or report the
   parser bug, then re-run. Never « complete by hand » — no green verdict may
   be born from a silent parser.
3. **Arbitrate** every `report.judgmentNeeded[]` entry of this dimension (UC-007 (vague-verb arbitration), UC-011, UC-015 (noun-phrase side), UC-023) from its `question` + `excerpts` ONLY (they are complete by contract — needing more is a CLI bug to report, never a license to read the corpus). Write the decisions JSON to the scratchpad and re-run with `\"judgments\":\"<path>\"` — the CLI merges, consumes the pending items and rewrites the verdict itself (you never write verdict markdown).
4. **Chat summary** (3-6 lines, business terms): the PARSE TOTALS (say the
   counts — that is how a « 0 erreur » stays verifiable), err/warn counts,
   remaining judgments, and the fix skill each finding names.

The CLI writes the verdict to `.smartstack/ba/<APP>/<MODULE>/_audit/use-case.md`
(existing format — anchor, `Verdict :` header, emoji sections; `0 err` =
pass for the downstream gate). The rule texts below remain the AUTHORITATIVE
spec — the CLI registry is drift-tested against them.

A field is **empty** when its bullet is absent or carries only an em-dash / "—" /
"(aucun)" placeholder. Treat such a field as empty for the rules below; never
infer content that is not written.

## Scoping

Audit ONLY the use cases of the active module (`.smartstack/ba/<APP>/<MODULE>/`).
Use cases from other modules are out of scope and MUST NOT be counted, flagged,
or compared.

In particular: **UC-010 (redundancy) compares ONLY UCs of the same module**. Two
UCs with similar titles in different modules (e.g. "Créer un brouillon" in
`BILLING/INVOICES` and `BILLING/CREDIT_NOTES`) are legitimate. Never flag
inter-module redundancy.

**Application / project scope** (opt-in — the user asks for an app-wide or
project-wide audit): run the module rules per module exactly as above (one
verdict per module), **plus UC-023** (cross-application similarity, warn).
UC-023 is the ONLY rule allowed to look at other applications, and it READS
them only — it never audits, counts, or fixes their UCs. When scope = module
(the default), skip UC-023 — emit zero cross-app findings.

## Verdict

A single `err` finding makes the verdict fail (`N err` with N ≥ 1 in the header),
which **blocks the next phase** (business rules). The user must correct the
offending UCs and re-audit. UC-001..013 and UC-019 emit only `err` or `ok`
(blocking gates). UC-014..018 (acceptance-criteria contract) and UC-020..022
may emit `warn` (non-blocking quality signals); UC-023 emits `warn` only.
Emit one finding per applicable rule, even when `ok`.

## Rules

### UC-001 — At least 1 use case exists per module
- **Severity**: err if 0 UCs in the audited module, ok else.
- Fix: `/ba-create-use-case`.

### UC-002 — Every section has at least 1 use case
- **Severity**: err if any section has 0 UCs, ok else.
- Fix: `/ba-create-use-case`.

### UC-003 — Every UC has a non-empty main flow
- **Severity**: err if any UC has an empty **Flux principal**, ok else.
- Fix: `/ba-create-use-case`.

### UC-004 — Every UC has at least 1 precondition
- **Severity**: err if any UC has empty **Préconditions**, ok else.
- Fix: `/ba-create-use-case`.

### UC-005 — Every UC has at least 1 postcondition
- **Severity**: err if any UC has empty **Postconditions**, ok else.
- Fix: `/ba-create-use-case`.

### UC-006 — Every UC has at least 1 alternative OR exception flow
- **Severity**: err if any UC has BOTH empty **Flux alternatifs** AND empty
  **Exceptions**, ok else.
- Fix: `/ba-create-use-case`.

### UC-007 — No vague language and no placeholder steps
Scan every step in **Flux principal**, **Préconditions**, **Postconditions**,
alternative/exception flow steps:

- **Vague verbs (anywhere in a step)**: `gere`, `gère`, `traite`, `handle`, `manage`, `process`, `facilement`, `easily`, `rapidement`, `quickly`, `efficacement`, `efficiently`, `correctement`, `correctly`, `fait`, `does`. A vague verb passes only if followed by a precise object phrase (e.g. "gérer le rapprochement bancaire" passes; "gérer la facture" fails).
- **Placeholder steps (whole step matches)**: `TODO`, `tbd`, `fixme`, `à compléter`, `a completer`, `à faire`, `…`, `...`, single-character entries.
- **Severity**: err if any UC contains at least one vague-verb or placeholder occurrence, ok else.
- Fix: `/ba-create-use-case`.

### UC-008 — All actor references point to existing actors
Check **Acteur principal** and every code in **Acteurs secondaires** against the
app `acteur.md` (`.smartstack/ba/<APP>/acteur.md`). Grep the `BA-{NNN}-AC-{NNN}`
code there — if it is not found, the reference is orphan.
- **Severity**: err if any reference is orphan, ok else.
- Fix: `/ba-create-actors`.

### UC-009 — Every UC's main flow has at least 3 imperative steps
A 1- or 2-step main flow is not a flow; it is a stub.
- **Severity**: err if any UC's **Flux principal** has fewer than 3 steps, ok else.
- Fix: `/ba-create-use-case`.

### UC-010 — No redundancy WITHIN the audited module
Two UCs of the **same module** are redundant if either holds:
- Their normalised titles are identical (lowercase, accents removed, leading articles `le/la/les/un/une/the/a/an` stripped, trailing punctuation trimmed).
- ≥ 80 % of their main-flow steps are textually equivalent after the same normalisation.

Compare ONLY UCs that share the same module. Never compare across modules — same
title in two modules is legitimate.
- **Severity**: err if any redundant pair is detected, ok else.
- Fix: `/ba-create-use-case`.
- **solution** template: `Fusionne ou supprime le doublon entre <UC-A> et <UC-B>. Garde le plus complet et redirige les références.`

### UC-011 — Every UC stays within its module's business scope
The title and every step (in **Flux principal**, alt/exception flows,
**Préconditions**, **Postconditions**) of each UC MUST describe activities
consistent with the parent module's `## Contexte` (read from the module
`index.md`).

Out-of-scope examples:
- A UC under `BILLING` that talks about salary management or absences (HR territory)
- A UC under `HR` that adjusts inventory levels (STOCK territory)
- A UC under `STOCK` that schedules meals (RESTAURATION territory)

Anchor on the module's `## Contexte` text (always present in the module
`index.md`). When a step or title introduces a concept that the module's context
does not name and that does not chain logically from the section's purpose, flag
it. The burden of proof falls on the foreign concept, not on the auditor — when
in doubt, flag and let the user decide.

- **Severity**: err if any UC drifts outside its module's domain, ok else.
- Fix: `/ba-create-use-case`.
- **solution** template: `<UC-code> sort du périmètre du module <module>. Soit supprime-le, soit déplace-le vers <module-cible>, soit recadre titre et étapes dans le contexte de <module>.`

### UC-012 — Acceptance criteria populated for `user-goal` UCs
Every UC at `user-goal` level MUST have acceptance criteria (≥ 1 entry) under a
`**Acceptance Criteria**` field. Subfunctions and summary-level UCs are exempt.
(When the UC level is not stated, treat a UC bound to a primary actor goal as
`user-goal`.) The AC field must be present and contain ≥ 1 `- [ ] AC-NN — …` bullet.
- **Severity**: err if any user-goal UC has empty acceptance criteria, ok else.
- Fix: `/ba-create-use-case`.

### UC-013 — AC id format & locality
Every acceptance criterion id matches `^AC-\d{2}$` (zero-padded 2 digits, local to
its UC — globally unique form is `<UC-code>#AC-NN`). The bullet shape is
`- [ ] AC-NN — <assertion>`. Catches drift from the legacy `AC-US{n}-{m}` global
scheme and accidental `AC-1`/`AC-001` typos.
- **Severity**: err if any AC bullet does not match, ok else.
- Fix: `/ba-create-use-case`.

### UC-014 — AC ids unique within UC, sequential, no gaps
Within each UC, the `NN` indices of `AC-NN` are unique, start at `01`, and have
no gap. Gaps break the test-scaffolder's `[Fact]` numbering and make AC
references in business rules ambiguous.
- **Severity**: warn if a gap or duplicate is found, ok else.
- Fix: `/ba-create-use-case`.

### UC-015 — Each AC is a single assertion (no compound)
Each `- [ ] AC-NN — …` line is a single sentence with one assertion. Lines chaining
two independent clauses with ` and / et / or / ou ` (outside a noun phrase) must
be split into separate AC ids — `scaffold-tests-from-ac` emits one `[Fact]` per
AC, so a compound AC silently collapses two test cases into one.
- **Severity**: warn if any AC chains two independent clauses, ok else.
- Fix: `/ba-create-use-case`.

### UC-016 — AC uses testable verbs (indicative, not modal)
Each AC uses an **imperative testable verb** (`renvoie`, `rejette`, `affiche`,
`persiste`, `émet`, `returns`, `rejects`, `displays`, `persists`, `emits`) in the
indicative; modal phrasing (`devrait`, `peut`, `should`, `might`, `may`) is
banned because it is not testable. Also reject vague verbs (`gère`, `traite`,
`handles`, `manages`, `supports`) without a concrete observable outcome.
- **Severity**: warn if any AC uses a modal or vague verb, ok else.
- Fix: `/ba-create-use-case`.

### UC-017 — AC has no unspecified non-functional adjective
Reject AC that include `rapidement`, `intuitif`, `performant`, `user-friendly`,
`fast`, `scalable`, `responsive` without a concrete numeric threshold (e.g.
`< 200 ms`, `≥ 60 fps`, `≤ 1 MB`). Vague non-functional claims are not testable.
- **Severity**: warn if any AC contains a banned adjective with no concrete
  threshold, ok else.
- Fix: `/ba-create-use-case`.

### UC-018 — AC entity references resolve upstream
When an AC names an entity (PascalCase token that does not equal the UC's own
section name and is not a HTTP verb / status code / common noun), that entity
exists in the module's `entité.md` (PascalCase name or BA `ENT-…` code). Catches
ACs that assert against an entity nobody declared.
- **Severity**: warn if any AC names an undeclared entity, ok else.
- Fix: `/ba-create-data-model` (declare the entity) or `/ba-create-use-case`
  (rephrase the AC).

### UC-019 — UC code section exists in the menu tree
Every UC's code is `UC-{APP}-{MOD}-{SEC}-NNN`. The `{SEC}` segment MUST
correspond to a section folder currently present in the menu tree —
`<baRoot>/<APP>/<MOD>/<sec-folder>/index.md` MUST exist, with the section
code derived from the kebab folder name (uppercase + `-` → `_`,
`opportunites` → `OPPORTUNITES`, `exchange-history` → `EXCHANGE_HISTORY`).
Catches orphan UCs left behind when the menu was edited (`/ba-create-menu`)
after the use cases were generated. The block is greppable but `/ba-develop`
crashes on invalid section codes during scaffolding.
- **Severity**: err if any UC code references a deleted/renamed section, ok
  else.
- Fix: `/ba-reconcile-menu` (preflight that renames or deletes orphans with
  user validation), then re-run `/ba-loop` to re-enrich.

## Output

Write `_audit/use-case.md` per the doc-templates audit-verdict skeleton:
- Anchor `<!-- ba:audit dimension=use-case scope=<APP>/<MODULE> -->`.
- Header `# Audit cas d'usage — <APP> / <MODULE>` + `_<date> · Verdict : <emoji>
  N warn · M err · K ok_` (UC-014..018 and UC-020..022 may emit `warn`;
  UC-001..013 and UC-019 emit only `err` or `ok`).
- `## ✅ Conforme`, `## ⚠️ Avertissements`, `## ❌ Bloquants` sections; one bullet
  per finding. For each finding: what's wrong (offending UC codes **bold**, AC
  ids when applicable), why it matters, and a `→` fix naming `/ba-create-use-case`
  (or `/ba-create-actors` for UC-008 — a missing actor; or `/ba-create-data-model`
  for UC-018 — a missing entity declaration; or `/ba-reconcile-menu` for UC-019
  — a stale section reference). Cite the offending UC codes and AC ids verbatim
  from the files.
- Rule codes (`UC-001`, …) stay **bold** so they remain greppable, but explain
  them in business terms.
- Re-Write the whole file each run (overwrite — it's a fresh verdict).

Then a 3–6 line chat summary in the user's language — business terms, not rule
codes. If any `err`, state clearly that the use cases must be fixed before moving
on to the business rules.

## Used by the readiness orchestrator

`/ba-audit-pre-dev` runs every dimension and aggregates the verdicts. When invoked
by it, still write `_audit/use-case.md` as usual — the orchestrator reads these
files.

### UC-020 — An AC cites only error codes that exist in the module
- **Severity**: warn, ok otherwise.
- Check: every error code an AC names (dotted `module.entity.cas` form, or a
  legacy bare code, usually in backticks after a 4xx status) resolves to a rule
  in the module's `regles-metier.md`. An AC asserting
  `400 + parc.vehicule.immat-unique` against a code no rule declares tests a
  contract nobody implements — the generated test pins a string the API will
  never return.
- Fix: `/ba-create-business-rules` (declare the rule) or `/ba-create-use-case`
  (cite the right code).

### UC-021 — A scheduled UC declares its idempotence acceptance criterion
- **Severity**: warn, ok otherwise.
- Check: every UC whose execution model is `scheduled` carries at least one AC
  of the shape « relancer la même période n'émet rien de nouveau » (a replay
  emits 0 new rows) — the contract the generated `Run{X}Async(runDate)` pass
  and its emission entity implement (derive-job-specs / DEV-API-028). Without
  the AC, the idempotence is untested and a double-fire double-notifies.
- Fix: `/ba-create-use-case` — add the AC; `scaffold-tests-from-ac` then
  covers it automatically.

### UC-022 — Every exception flow has a corresponding AC
- **Severity**: warn (promotion to `err` planned after an observation period
  on real projects), ok otherwise.
- The authoring guidance always said « un AC par chemin EXC-N » — nothing
  counted it: a UC with 5 exceptions and 1 happy-path AC passed every gate
  (EXC-N flows were terminal after the BA, with no consumer at all). Run
  this check **DETERMINISTICALLY — never recount by eye**:

  ```bash
  npx --prefer-offline tsx skills/business-analyse/create-screen/cli/derive-uc-coverage/index.ts \
    --spec '{"baRoot":".smartstack/ba","app":"<APP>","module":"<MODULE>"}'
  ```

  Map every `report.exceptionFindings[]` entry to one UC-022 warn finding
  (cite the UC code + the uncovered `EXC-N` ids + the CLI's detail verbatim).
  Correspondence tiers the CLI applies: (1) explicit — an AC citing the
  exception id verbatim (`EXC-2`, word-bounded); (2) counted pool — the
  remaining flows are covered when the UC has at least as many NEGATIVE ACs
  (4xx/5xx status or refusal/error outcome) not already claimed by tier 1.
  Which AC tests which flow stays the author's judgment — the CLI counts, it
  never guesses semantics. Only `user-goal` UCs are checked (subfunction and
  summary levels legitimately carry no AC contract — UC-012).
- Fix: `/ba-create-use-case` — one AC per EXC-N (cite the id, e.g.
  « … (EXC-2) », or assert its 4xx/error outcome); `scaffold-tests-from-ac`
  then emits its `[Fact]` automatically.

### UC-023 — Cross-application UC similarity (app/project scope only)
- **Severity**: `warn` only — never `err`, never blocking (`/ba-audit-pre-dev`
  counts only `err` findings).
- **Gate**: apply ONLY when the audit scope is application or project. When
  scope = module (the default), skip — emit zero UC-023 findings.
- Compare the audited module's UC titles against the `### UC-` headings of the
  OTHER applications (Grep; whole-token, case/accent-insensitive matching —
  never substring).
- **Contextual analysis REQUIRED** — a lexical hit is not a finding. TRUE
  duplicate: the two UCs pursue the same business goal for the same kind of
  actor on the same concept (the same approval flow re-modelled in two apps).
  Contextually different: same words, different business object or outcome
  (« Clôturer un dossier » in CRM vs in SUPPORT is legitimate). Do NOT use a
  hardcoded whitelist — analyze the business semantics.
- Finding: written in the verdict of the module OWNING the flagged UC — cite
  both codes (local `UC-…` + foreign `UC-…`) and one line on the overlap.
  Fix: user arbitration (keep both, reword the local one, or consolidate by
  hand) — NEVER an edit of the other application's docs; there is no automated
  fix path.
