---
name: ba-audit-sources
description: >
  Audits the client-sources registry (`.smartstack/sources/`, SIBLING root of
  the BA tree) and the `SRC-NNN §n` citations the BA specs carry — registry
  coherence, source completeness, web-extract contract, citation resolution,
  scope coverage, dead and superseded sources (SRC-001..007, all mechanical,
  fail-closed: « no citation » is only acceptable when no in-scope source
  exists). Reads the registry through the shared engine, writes verdicts to
  `_audit/sources.md` (project root) and `<APP>/<MODULE>/_audit/sources.md`.
  Run after `/ba-create-sources` or as part of pre-dev readiness.
allowed-tools: [Read, Write, Glob, Grep, Bash]  # Bash: the audit-ba engine (deterministic mechanical rules)
---

# ba-audit-sources — Client-sources audit

You audit the sources registry and the citations the BA specs carry against
the rules below. The registry is written ONLY by `/ba-create-sources`'
`cli/ingest`; this audit is the verdict on both the registry AND every
`- **Sources** : SRC-NNN §n` line in the tree.

## Deterministic engine — how this audit runs

Every rule of this dimension is MECHANICAL, 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), and never by
opening `raw/` or the whole registry.

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","dimensions":["sources"]}'
   ```

2. **Exit 3 = parsing suspect → STOP.** The registry has its own control
   counter (`ba:source` anchors on disk vs docs parsed): a gap means the
   sources corpus could not be read — fix the doc's form or report the parser
   bug, then re-run. No green verdict may be born from a silent parser.
3. **No judgment rules in this dimension** — a single engine run suffices;
   the verdict is final.
4. **Chat summary** (3-6 lines, business terms): registry size and health,
   citations verified/broken counts, uncited in-scope sources, blocked
   sources awaiting an export.

Verdicts: project-grain findings (SRC-001/002/003/006/007 and the per-app
SRC-004) land in `.smartstack/ba/_audit/sources.md`; the per-module coverage
(SRC-005) lands in `<APP>/<MODULE>/_audit/sources.md`. The rule texts below
remain the AUTHORITATIVE spec — the CLI registry is drift-tested against them.

## The registry (contract recap)

`.smartstack/sources/` — sibling root, COMMITTED, written only by the ingest
CLI: `index.json` (entries `SRC-NNN`: fingerprint, status, tags, scopes,
counts) + one `SRC-NNN/source.md` per source (anchor, `## Résumé`,
`## Points saillants` with `§n` sections, verbatim blockquote extracts) +
`raw/` byte copies. Statuses: `ingested`, `blocked/needs-export`,
`blocked/unreadable` (typed admissions — code reserved, content unread),
`superseded`. Citation grammar, whole-word: `SRC-NNN` or `SRC-NNN §n`.

## Rules

### SRC-001 — Registry coherent (index ↔ disk reconciled)
- `err` when the registry exists but diverges: unreadable/invalid
  `index.json`, an index entry without its `SRC-NNN/source.md`, a folder
  missing from the index, duplicate fingerprints (one content = one code),
  a `nextSeq` ≤ the max allocated (a code could be reused), an anchor code
  that contradicts its folder, or a root-level `index.md` citation that does
  not resolve. `ok` when reconciled — and `ok` (« sans objet ») when NO
  registry exists at all: its absence is a legitimate state, never a defect.
- Why `err`: while index and disk diverge, no citation is trustworthy — every
  other SRC rule reads through this reconciliation.
- Fix: repair through `/ba-create-sources` (`cli/status` names the issues;
  the ingest CLI is the only writer — never hand-edit `index.json`).

### SRC-002 — Ingested source complete (summary + tags + §-sections)
- `err` for an `ingested` source with an empty `## Résumé`, zero tags or zero
  `§n` sections — « ingéré, 0 extrait » must not exist: an empty summary can
  feed no phase, and untagged sources cannot be routed to a scope.
- `warn` (nominative) for every `blocked/*` source: the client document is on
  record but UNEXPLOITED — ask for an export (PDF/MD/CSV) and re-attach via
  ingest `"as":"SRC-NNN"`.
- `warn` for every ingested source whose `scopes` entry resolves to NO node of
  the menu tree (only checked once apps exist — scopes are « pressenties » and
  may precede the menu). This is the `/ba-reconcile-menu` blind spot: a menu
  rename rewrites the downstream BA codes but NOT the registry, and an orphan
  scope makes SRC-005 vacuously ok (fail-open) — re-point the scopes via
  `/ba-create-sources`.
- Fix: `/ba-create-sources` (re-ingest with a real analysis / correct the
  scopes).

### SRC-003 — Web source carries a retained extract
- `err` for a `kind=web` ingested source with zero verbatim extract. The
  contract: a web search enters the registry ONLY if information was actually
  retained (≥1 verbatim blockquote). The ingest CLI refuses this at write
  time — this rule is the net for hand-edited or legacy registries.
- Fix: add the verbatim extract that justified retaining the finding, or
  remove the entry through `/ba-create-sources` (supersede).

### SRC-004 — Every citation resolves (code AND anchor)
- `err` when any `SRC-NNN [§n]` cited in the app's documents (app `index.md`,
  `acteur.md`, and every module's `index.md`, section `index.md`,
  `use-case.md`, `règles-métier.md`, `rbac.md`, `screen.md`, `entité.md`)
  fails to resolve: unknown code, unknown `§n` anchor (an anchored citation on
  an unparsable source.md is UNVERIFIABLE, hence broken), or any citation at
  all when no registry exists. A citation that does not resolve is an
  INVENTED provenance — worse than none.
- The evidence always carries the counts: « N citation(s) vérifiée(s),
  M irrésolvable(s) » — and `ok` states the N it verified.
- Fix: correct the citation in the owning doc (re-run the authoring phase),
  or restore/re-ingest the missing source.

### SRC-005 — In-scope sources are actually consumed
- For each module: `err` when ≥1 ingested source declares scope
  `APP/MODULE` and its code is cited NOWHERE in the module's documents — the
  spec ignores client material declared relevant to it. `warn` when the
  source is scoped `APP` (whole app) only. `ok` — explicitly « spec sans
  citation acceptable » — when the registry is absent or NO ingested source
  covers the module: **zero searchable sources never reads as « nothing to
  cite »** (the DM-022 doctrine).
- Fix: cite the source where it grounds an item (re-run the phase that owns
  the doc), or correct the source's `scopes` via `/ba-create-sources` if the
  declaration was wrong.

### SRC-006 — No dead source (ingested but never cited)
- `warn` when an `ingested` source is cited by NO document in the whole tree:
  either cite it where it actually grounded decisions, or mark it
  `superseded` — the anti-dead-data rule applies to the registry side too (a
  registry entry nobody reads is the `Règles liées` failure inverted).
- Fix: `/ba-create-sources`.

### SRC-007 — Superseded source no longer cited
- `warn` when a `superseded` source is still cited somewhere: the provenance
  points at outdated material — re-ground the item on the replacing source
  (`supersededBy`).
- Fix: re-run the owning phase on the affected items.

## Used by the readiness orchestrator

`/ba-audit-pre-dev` reads `_audit/sources.md` (project grain, like actors)
and every `<APP>/<MODULE>/_audit/sources.md`. Any `err` blocks the GO.
