---
name: ba-audit-cross-dimension
description: >
  Cross-dimension coherence audit of one `.smartstack/ba/` module — verifies that
  data-model fields with state semantics have matching business rules, use cases
  and screens, that use-case actors exist in RBAC, that screen entity refs
  resolve, and that a kanban is a view of its list and not its own section
  (XD-001..006). Reads the module's `entité.md`, `règles-métier.md`,
  `use-case.md`, `rbac.md` and its section `screen.md` files together, writes a
  verdict to `_audit/cross-dimension.md`. Run after the per-dimension audits or as
  part of pre-dev readiness.
allowed-tools: [Read, Write, Glob, Grep, Bash]  # Bash: the audit-ba engine (deterministic mechanical rules)
---

# ba-audit-cross-dimension — Cross-dimension coherence audit

You audit ONE business module of a `.smartstack/ba/` project for coherence
**between** its dimensions (data model ↔ rules ↔ use cases ↔ screens ↔ RBAC) and
write a verdict file. The rules are unchanged from the SmartStack convention; only
the I/O is file-based. This audit is inherently cross-doc — a single dimension in
isolation cannot tell you whether a state field is missing its transition rule, so
you read several docs of the module together and cross-check them.

## 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":["cross-dimension"]}'
   ```

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 (XD-008) 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/cross-dimension.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.

## Rules

State semantics, throughout: an attribute carries **state semantics** when its
name contains `status`, `state`, `phase` or `step`, **or** its type is an `enum`
whose values look like a lifecycle (e.g. `NOUVELLE/GAGNEE/PERDUE`,
`DRAFT/APPROVED/REJECTED`). Identify these per entity first, then apply XD-001..003.

### XD-001 — State fields have transition rules
- `warn` if a state field is missing a transition rule; `ok` if covered.
- Check: for each entity attribute with state semantics, verify at least one
  business rule of type `state-transition` (or whose condition governs the
  status/state change) references that entity. List the uncovered entities.
- Why it matters: without a transition rule the allowed status changes are
  undefined — FluentValidation has nothing to enforce and the UI cannot gate
  illegal transitions.
- Fix: `/ba-create-business-rules`.

### XD-002 — State fields have corresponding use cases
- `warn` if a state field has no use case describing its change; `ok` if covered.
- Check: for each entity with a state field, at least one use case should describe
  the action of changing that status — its title contains `change`, `update`,
  `transition`, `approve`, `reject`, `validate`, `cancel`, or the entity name plus
  a status action. List the uncovered entities.
- Why it matters: a status that nothing in the use cases ever moves is dead state;
  the workflow behind it was never specified.
- Fix: `/ba-create-use-case`.

### XD-003 — Workflow entities have Kanban or workflow screens
- `warn` if a state-bearing entity has no workflow screen; `ok` if covered.
- Check: for each entity with a state field, at least one screen of type
  `SmartKanban` (or an equivalent workflow board) should bind that entity —
  authored as a second screen in the entity's `*-list` section (see XD-006), not
  its own section. List the uncovered entities.
- Why it matters: lifecycle entities are best operated on a board; otherwise users
  have no view that surfaces the workflow.
- Fix: `/ba-create-screen`.

### XD-004 — Use-case actors exist in RBAC
- `warn` if a use-case primary actor has no permission in the module; `ok` if all
  matched.
- Check: for each use case's primary actor code, verify it appears in the module's
  `rbac.md` with at least one permission entry (or is referenced by a business
  rule for the module). List the orphan actor codes.
- Why it matters: an actor that performs use cases but holds no permission cannot
  actually be authorised to do anything — the RBAC matrix is incomplete.
- Fix: `/ba-create-rbac`.

### XD-005 — Screen entity references match the data model
- `err` on a broken reference; `ok` if all valid.
- Check: for each screen that binds an entity, verify the referenced entity code
  exists in the module's `entité.md`. List the broken references (screen → entity).
- Mirror of SCR-003 — the SAME predicate (`screen-blocks.unresolvedEntityRefs`),
  never a second implementation: skip `SmartDashboard` / `SmartAppHome` /
  `SmartModuleHome` / `SmartSectionHome` whatever their `Entité` line says
  (they aggregate via widgets; the template writes `— (chaque widget porte la
  sienne)`). The two rules can never disagree on a screen.
- Why it matters: a screen pointing at a non-existent entity cannot be scaffolded —
  it breaks downstream page generation.
- Fix: `/ba-create-data-model` (add the missing entity) or `/ba-create-screen`
  (correct the screen's binding), depending on which side is wrong.

### XD-006 — A Kanban is a representation, never a section
- `err` when a `SmartKanban` is NOT co-located with a `SmartListView` of the SAME
  entity in the SAME section (i.e. the kanban stands as the sole/primary screen of
  its own section). A section must denote a business workspace; "kanban / board /
  pipeline" is a presentation, not a business concept, so it must never define a
  section.
- Check: build the module index (entity → list of {section, SmartComponent type}).
  For each `SmartKanban` bound to entity E in section S_k, require a `SmartListView`
  bound to E in that SAME section S_k. If E's `SmartListView` lives in another
  section S_l ≠ S_k, OR no `SmartListView` for E exists at all, flag the kanban —
  list its `SCR-…`, its section S_k, and the list section S_l it should join (if any).
- Why it matters: the generator renders the kanban as a viewMode of the list PAGE
  (one route `/…/list` with a Table ⇄ Kanban toggle, one permission, one section —
  the PRD folds the SmartKanban into the list pagespec). Splitting it
  into a `-board`/`-workflow`/`-pipeline` section fabricates a duplicate menu node, a
  duplicate permission and a duplicate route for one entity (the split SCR-010
  removes for filters), and the two views silently drift apart.
- Fix: `/ba-create-screen` — re-author the kanban inside E's `*-list` `screen.md` as
  a second screen (same entity, same permission, next `NNN`); if E has no list at
  all, add its `SmartListView` there first so the section is a real business
  workspace. Then drop the standalone `*-board` section via `/ba-create-menu`.

### XD-007 — Transition-captured attributes are not asked at creation
- `warn` when a create-serving form collects an attribute a workflow rule captures
  at a transition; `ok` otherwise.
- Check: parse every `- **Flow**` line of the module's `workflow`/`state-transition`
  rules and the linked custom actions' parameters (`payloadParameters[].field` ??
  `name`, else `workflowTransition.flowParameters`). For each entity attribute so
  captured, verify the entity's form screens either phase it (a `- **Cycle de vie**`
  bullet whose phase owns the field) or don't list it at all. List the offending
  (screen, field, transition) triples. Also verify, for every declared phase, that
  its statuses are enum values of the entity AND that ≥ 1 Flow line REACHES one of
  them (a phase gated on a status no transition produces can never open).
- Why it matters: a field the workflow captures later (an invoice's paymentDate on
  CREATE) duplicates the capture point and lets creation smuggle in state no
  transition ever validated — the guard/BR chain is bypassed at birth.
- Fix: `/ba-create-screen` (add the `- **Cycle de vie**` bullet or remove the field
  from the create surface); a status no Flow reaches → `/ba-create-business-rules`.

## Output

Write `_audit/cross-dimension.md` per the doc-templates skeleton:
- Header `# Audit cross-dimension — <APP> / <MODULE>` + `_<date> · Verdict :
  <emoji> N warn · M err · K ok_`.
- `## ✅ Conforme`, `## ⚠️ Avertissements`, `## ❌ Bloquants` sections; one bullet
  per finding. For each `warn`/`err`: what's wrong (offending codes — entities,
  actors, screen/entity refs — in **bold**), why it matters, and a `→` fix naming
  the owning phase skill (`/ba-create-business-rules`, `/ba-create-use-case`,
  `/ba-create-screen`, `/ba-create-rbac` or `/ba-create-data-model`, per the rule).
- Rule codes (`XD-001`, …) stay **bold** so they remain greppable, but are
  explained in business terms — no label codes, no JSON.
- 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` (a broken screen → entity reference, or a kanban modeled as its
own section), state clearly that the module's coherence must be fixed before moving on.

## Used by the readiness orchestrator

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

### XD-008 — A dated child has a birth for its FIRST period
- **Severity**: warn, ok otherwise.
- Check: an entity carrying a PERIOD pair (`StartDate`/`EndDate`,
  `ValidFrom`/`ValidTo`, `DateDebut`/`DateFin` in `entité.md`) that the
  screens expose only as a list / related tab, whose ONLY creating action is a
  renewal/transition (`reconduct`/`renew`/`transfer`/`changer`), leaves the
  FIRST period unbornable: opening a vehicle's first registration required
  « changer de canton », its first site attachment « le transférer » — the
  data take-on had to lie about the act it performed. Add the initial creation
  action (or a form) alongside the transition.
- Fix: `/ba-create-screen` — an explicit « ouvrir la première période » action
  or a creation form on the child.
