---
name: ba-audit-screens
description: >
  Audits the screen specs of a `.smartstack/ba/` section — coverage, entity refs,
  SmartComponent coherence, navigation integrity, related-tabs (360 view),
  home-page hierarchy, UC traceability, custom-actions structure, coded-entity
  code fields, attachment screens bound to a metadata entity, list column/filter
  inflation, form field grouping (Section/Onglet), create-form phase discipline,
  mandatory SmartSectionHome on multi-resource sections, observable action
  results, dashboard/entity binding, instance-verb confirmation, use-case
  coverage — every user-goal UC served by a surface, and the shared tab-bar
  budget — inner + related tabs ≤ 7/9, band cartouches excluded (SCR-001..025).
  Reads the section `screen.md` plus the module `entité.md`/`rbac.md` and the
  section `use-case.md`; the related-tab rules (SCR-009/014) and the tab-bar
  budget (SCR-025 ← RTV-009) run DETERMINISTICALLY through the
  derive-related-tabs CLI, the UC-coverage rule (SCR-024) through
  the derive-uc-coverage CLI. Writes a verdict to `_audit/screen.md`.
  Run after `/ba-create-screen` or as part of pre-dev readiness.
allowed-tools: [Read, Write, Glob, Grep, Bash]
---

# ba-audit-screens — Screen specifications audit

You audit the screen specs of a `.smartstack/ba/` project against the rules below
and write a verdict file. The rules are unchanged from the SmartStack convention;
only the I/O is file-based. The twenty-five rules cover the full SmartComponent type
set: `SmartListView`, `SmartForm`, `SmartDashboard`, `SmartKanban`, `SmartCard`,
`SmartAppHome`, `SmartModuleHome`, `SmartSectionHome`. The legacy `SmartFilter`
type is forbidden (covered by SCR-010), the **custom-actions metadata**
introduced by ba-create-screen (SCR-011/012/013) is verified end-to-end so the
downstream pipeline never silently drops a non-CRUD button, the **360
related tabs** (SCR-009/014) and the **shared tab-bar budget** (SCR-025) are
verified deterministically through the
`derive-related-tabs` CLI colocated with `/ba-create-screen`, and the
**use-case coverage** (SCR-024 — every user-goal UC served by ≥ 1 screen,
custom action or scheduled runtime) through its sibling `derive-uc-coverage`
CLI.

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

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 (SCR-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/screen.md (MODULE level now — delete legacy per-section screen.md verdicts, the envelope warns about them)`
(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.

## Scope

- **Section scope** (default): audit one section — apply SCR-001..025 to its
  screens, resolving refs against the parent module's `entité.md`/`rbac.md` and
  the section's `use-case.md`. Navigation targets (SCR-008) resolve against every
  `SCR-…` code in the analysis. The `derive-related-tabs` and `derive-uc-coverage`
  CLIs run at MODULE scope — filter their findings down to the audited section.
- **Module scope**: apply the rules to every section under the module; the
  module-level rules (SCR-001, SCR-007) and the app-level rule (SCR-006) span the
  whole subtree.
- The verdict file lives at the audited section's `_audit/screen.md`.

## Rules

### SCR-001 — At least 1 screen exists per module
- **Severity**: err (if 0), ok (if >= 1)
- Count the `SCR-…` screens across the module's sections.
- Fix: `/ba-create-screen`.

### SCR-002 — Every section has at least 1 screen
- **Severity**: warn (if uncovered sections), ok (if all covered)
- Fix: `/ba-create-screen`.

### SCR-003 — Screen entity references point to existing entities
- **Severity**: err (if broken refs), ok (if all valid)
- Check: screen's entityRef matches an entity code OR entity name in the data model
- Skip when `entityRef` is null AND screen type is `SmartDashboard`/`SmartAppHome`/`SmartModuleHome`/`SmartSectionHome` (these aggregate via widgets)
- Fix: `/ba-create-screen`.

### SCR-004 — Entity-bound screens have an entity reference
- **Severity**: warn (if missing), ok (if all have)
- Check: screenType ∈ {`SmartListView`, `SmartForm`, `SmartCard`} → entityRef must be non-empty
- `SmartKanban` SHOULD have entityRef (workflow entity with status)
- `SmartDashboard`/`SmartAppHome`/`SmartModuleHome`/`SmartSectionHome` do NOT need entityRef on the screen (they aggregate through widgets)
- Fix: `/ba-create-screen`.

### SCR-005 — All screens are linked to at least 1 use case
- **Severity**: warn (if unlinked), ok (if all linked)
- Fix: `/ba-create-screen`.

### SCR-006 — Application landing page (SmartAppHome) exists when ≥2 modules
- **Severity**: warn (if missing), ok (if all multi-module apps have one)
- Check: for each application with ≥2 modules, at least one screen of type `SmartAppHome` exists with that `applicationCode`
- Fix: `/ba-create-screen`.

### SCR-007 — Module landing page (SmartModuleHome) exists when ≥2 sections
- **Severity**: warn (if missing), ok (if all multi-section modules have one)
- Check: for each module with ≥2 sections, at least one screen of type `SmartModuleHome` exists with that `applicationCode`/`moduleCode`
- Fix: `/ba-create-screen`.

### SCR-008 — Navigation targets reference existing screens
- **Severity**: err (if any broken target), ok (if all valid)
- Check every navigation field for an existing screen `code` in this analysis:
  - `SmartListView.config.rowClickTarget`
  - `SmartCard.config.clickTarget`
  - `SmartKanban.config.rowClickTarget`
  - `SmartForm.config.relatedTabs[].screenTarget`
  - `SmartAppHome.config.quickLinks[].screenTarget`
  - `SmartModuleHome.config.quickLinks[].screenTarget`
  - `SmartSectionHome.config.quickLinks[].screenTarget`
- Fix: `/ba-create-screen`.

### SCR-009 — Hub forms expose their relations as related tabs (360 view)
- **Severity**: err (missing on a hub form with no justification), ok otherwise
- Run this check **DETERMINISTICALLY — do NOT eyeball the relation graph**:

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

  Map every **RTV-007** violation to one SCR-009 finding. The CLI raises err
  ONLY when all three hold: (a) the form's entity has ≥1 incoming 1:N relation
  in `entité.md`, (b) the detail/edit `SmartForm` declares zero `Onglet lié`,
  (c) the screen carries no `- **Sans onglets liés** : <raison>` marker.
- The marker IS the sanctioned escape: a portal/read-only module is no longer a
  fuzzy skip — it carries an explicit, greppable justification. Marker present
  → ok (report it under Conforme with the raison).
- Fix: `/ba-create-screen` (add the tabs — or the justification marker).

### SCR-014 — Declared related tabs satisfy their prerequisites
- **Severity**: err (any violation), ok otherwise
- From the SAME CLI run as SCR-009 (mode `validate`): every `violations[]`
  entry with rule ∈ {RTV-001, RTV-002, RTV-003, RTV-005, RTV-006, RTV-008}
  becomes one SCR-014 finding (quote the CLI message verbatim, cite the file +
  screen code + tab key). RTV-004 (permission not found in `rbac.md`) maps to
  a **warn**-severity SCR-014 finding.
  - RTV-001 the related entity exists in the data model
  - RTV-002 the FK exists on the related entity, pointing toward the screen's entity
  - RTV-003 the target resolves to a `SmartListView`/`SmartCard` of the related entity
  - RTV-005 no related tabs on a `create` form
  - RTV-006 unique tab keys within a screen
  - RTV-008 the tab parses against the canonical schema (`lib/page-spec-related-tabs.ts`) — invalid `affichage` (e.g. `report`) fails here
- SCR-008 still covers the broader navigation table (quickLinks, rowClickTarget);
  its `relatedTabs[].screenTarget` sub-case is now CLI-backed via RTV-003.
- Fix: `/ba-create-screen`.

### SCR-010 — No legacy SmartFilter screens remain
- **Severity**: err (if any present), ok (if none)
- Check: no screen has `screenType === "SmartFilter"`. The type is removed; filters live inside `SmartListView.config.filters`.
- Fix: `/ba-create-screen`.
- **migration hint**: for each affected section, fold the SmartFilter into the matching SmartTable/SmartListView (move `config.fields[]` into `SmartListView.config.filters.fields[]`) and re-emit a single `SmartListView` screen.

### SCR-011 — Custom actions carry the mandatory metadata
- **Severity**: err (if any custom action is missing a required field), ok
- Check: for every `- **Actions personnalisées** :` sub-bullet of every screen,
  all of `code`, `kind`, `scope`, `permission`, `label` are present and
  well-formed. The `code` regex is camelCase `^[a-z][a-zA-Z0-9]*$`; the
  `permission` regex accepts 3 segments (section) or 4 segments (resource):
  `^[a-z][a-z0-9-]*\.[a-z][a-z0-9-]*(\.[a-z][a-z0-9-]*)?\.[a-z][a-z0-9-]*$`.
- Then branch on `kind`:
  - `kind: api` requires `endpoint` (kebab `^[a-z][a-z0-9-]*$`) +
    `httpMethod` ∈ {GET,POST,PUT,PATCH,DELETE} + `UC: UC-…`. When `endpoint`
    is absent the default is `kebab(code)` — the audit accepts the absence
    but still verifies kebab-ness once the default is applied.
  - `kind: navigate` requires `targetScreen: SCR-…` OR a `targetRoute`
    string, and MUST NOT carry `endpoint` / `httpMethod` / `payloadDto`.
- This is the gate that catches free-text custom actions silently dropped by
  `ba-create-prd`.
- Fix: `/ba-create-screen`.

### SCR-012 — Custom action endpoints are unique per entity
- **Severity**: err (if any duplicate endpoint within one entity's screens), ok
- Check: across every screen `bound` to the same entity (`entityRef` match) of
  the audited module, no two custom actions of `kind: api` share the
  `(httpMethod, scope, endpoint)` triplet. A duplicate would emit a duplicate
  `[HttpVerb("<endpoint>")]` on the controller (compile error) or two service
  methods of the same name (TypeScript collision).
- Fix: `/ba-create-screen`.

### SCR-013 — Navigate targets resolve to an existing screen
- **Severity**: err (any broken `targetScreen`), ok otherwise
- Check: every custom action with `kind: navigate` AND `targetScreen: SCR-…`
  references a screen code present in this audit's analysis (any module of
  the same application). Reuses the resolution table built for SCR-008.
- Custom actions using `targetRoute` (free-text route helper) are skipped by
  this rule — they are validated later by the per-page contract audit
  (`/ba-audit-prd`, PRD-100) once the route resolution is wired by
  `ba-create-prd`.
- Fix: `/ba-create-screen`.

### SCR-015 — Coded entities never expose an editable `code` field
- **Severity**: err (any violation), ok otherwise
- Check: for every `SmartForm` bound to an entity whose `entité.md` block
  declares a `- **Code pattern** : …` line (DM-017's data-model half — the Code
  is system-allocated by the engine at insert, the user never types it), the
  `code` field must NOT appear as an editable Champ:
  - `create` mode → `code` ABSENT from every Onglet/Champs list — **unless**
    the entity's `**Code pattern**` line declares `surchargeable à la création`
    (`supplied on create`): an OPTIONAL code field is then sanctioned on the
    CREATE surface (the generated SmartCodeField, validated by the socle's
    `ISuppliedCodeGuard` — imports/reprises arrive WITH their number), never a
    required one;
  - `edit`/`detail` mode → `code` absent OR explicitly `readonly`
    (e.g. `code (text, readonly)` — display the allocated code). The facet
    NEVER relaxes edit: a code is immutable after creation.
- Entities WITHOUT a `**Code pattern**` are out of scope: a user-typed
  referential code (small lookup tables) is legitimate and stays editable.
- Downstream net: `ba-create-prd` stamps the `codedEntity` flag (boolean `true` or the enriched object when the line authors `libellé`/`surchargeable` facets) on the pagespecs,
  scaffold-component's validation hard-fails an editable `code`, and audits
  DEV-API-022 / DEV-UI-034 catch residual drift in generated code.
- Fix: `/ba-create-screen` (drop the field or mark it readonly).

### SCR-016 — Attachment screens bind a metadata entity, never a custom-action file upload
- **Severity**: warn (any violation), ok otherwise
- Check: for every screen or related tab with attachment semantics — a
  « Documents » / « Pièces jointes » tab, an upload/download use case, or a
  custom action carrying `payloadParameters[].type: 'file'`:
  - (a) the module's `entité.md` must declare the file-METADATA entity the
    screen binds (attachment shape: `FileName`, `StoredFileName`,
    `ContentType`, `FileSizeBytes` + parent FK — rule C-6/DM-019). A
    « Documents » tab with NO backing entity → **warn**: the screen has
    nothing to render; add the metadata entity via `/ba-create-data-model`.
  - (b) NO custom action declares a `type: 'file'` payload parameter → **warn**
    if one does: the custom-action pipeline posts JSON (a `File` serializes to
    `{}` — not wired for multipart; PRD-107 errs downstream). Uploads are
    dedicated endpoints on the metadata entity (pattern:
    `development/backend/data-layer/references/file-storage.md`), the screen
    only declares the tab.
- The platform ALREADY ships the storage primitive (`IFileStorageService`) —
  never let a screen note say "no file mechanism exists"; steer to the pattern.
- Fix: `/ba-create-screen` (+ `/ba-create-data-model` for a missing metadata
  entity).

### SCR-017 — List screens stay readable (column / filter inflation)
- **Severity**: warn (any violation), ok otherwise
- Check: for every `SmartListView` screen: (a) **Colonnes** lists ≤ 10 entries;
  (b) **Filtres** lists ≤ 8 entries; (c) **Indicateurs** (when authored) lists
  ≤ 4 entries — the KPI row is ONE grid line, beyond 4 it wraps into a wall,
  and a scoped indicator (`count, field = value`) must scope on a declared
  **Filtres** field (that is the wirable server param — PRD-115 gates it
  downstream). Beyond those counts the list is a data
  dump, not a screen: the rendering will show at most ~7 columns by default
  (column picker for the rest) and 3 primary filters (« Plus de filtres » for
  the rest), so the surplus is reachable — but the SOURCE judgment lives here.
  Trim to what the section's use cases actually cite, and remember the
  DECLARATION ORDER matters: it feeds the downstream first-7 visibility
  fallback when the PRD authors no priorities.
- Not a parity break: every declared filter still reaches the pagespec 1:1
  (PRD-082); this rule only flags inflation at its source.
- Fix: `/ba-create-screen` (trim or reorder Colonnes/Filtres per
  `levels/list-screens.md`).

### SCR-018 — Form screens group their fields (Section/Onglet vocabulary)
- **Severity**: warn (any violation), ok otherwise
- Check, for every `SmartForm` screen:
  - (a) **field wall** — ≥ 8 flat `Champs` with NO `**Section « … »**` and NO
    `**Onglet « … »**` bullet → warn. Beyond ~7 fields the generated fiche is
    a wall; group by business meaning into 2-4 sections (one page, titled
    cards) — or tabs (decision table in `levels/form-screens.md`).
  - (b) **section budget** — when `Section` bullets exist: 2 to 4 sections,
    each with ≥ 2 fields, unique labels (a 1-field section is noise; a single
    section is just flat).
  - (c) **no mixing** — `Section` and `Onglet` bullets never coexist at the
    first level of one screen (Section-inside-Tab nesting is not v1).
  - (d) **coverage** — in a grouped screen, every field belongs to exactly one
    group (none left flat outside the groups, none listed in two).
- Counts are deterministic (count the bullets and their fields); the semantic
  quality of the group labels stays conversational.
- Fix: `/ba-create-screen` (decision table in `levels/form-screens.md`).

### SCR-019 — Create forms don't ask later-phase fields
- **Severity**: warn (heuristic — the remedy is a BA decision, never an auto-fix),
  ok otherwise
- Check, for every `SmartForm` screen whose entity carries a state-semantics
  attribute in `entité.md` (same definition as XD-001: name contains
  status/statut/state/état/phase/step, or a lifecycle-looking enum):
  - (a) **editable state field** — the state attribute is listed as an editable
    `Champ` (no `readonly`, no `readonlyOn`) with no `- **Cycle de vie**` bullet
    naming it as `statut` → warn (the status is the lifecycle anchor, not a
    free input on the create form).
  - (b) **later-phase lexicon** — a listed field whose name matches the
    later-phase lexicon (`payment*`/`paid*`, `departure*`/`sortie*`, `exit*`,
    `termination*`, `closure*`/`closed*`, `cancel*`, `resolution*`, `archiv*`,
    `end*`) while a matching later status value exists in the state enum, and
    NO `- **Cycle de vie**` phase owns it → warn. The invoice create form
    asking the payment date is exactly this finding.
- Why it matters: the generated form serves create AND edit — an un-phased
  later-phase field is asked at CREATION, where the business cannot answer it
  (and, worse, could type it).
- Fix: `/ba-create-screen` — add the `- **Cycle de vie**` bullet
  (`levels/form-screens.md` § Cycle de vie), or drop the field from the screen.
  The deterministic downstream twins are PRD-120/121 (`derive-lifecycle
  --mode check`); the deep coherence with the Flow rules is XD-007.

### SCR-020 — A section of sibling resources declares its SmartSectionHome
- **Severity**: err (a section whose screens ALL attach to child resources has
  no section-level screen), ok otherwise — the mirror of SCR-006 (app hub) and
  SCR-007 (module hub) one level down.
- Check: for each section holding ≥1 resource node, when every `SCR-…` of the
  subtree binds at the RESOURCE level and none at the section level, the
  section must declare a `SmartSectionHome` (quickLinks — one per resource).
- The bug it closes: `referentiels` seeded as a navigation section with 8
  sibling resources and no root page — the menu proposed the URL, nothing was
  registered behind it (blank screen), and the 8 leaves were reachable only by
  typing their URL. The runtime net is run-smoke's registry↔menu coverage
  (every menu componentKey must resolve a `PageRegistry.register`).
- Fix: `/ba-create-screen` (the home-screens level proposes it) — then
  `/ba-create-prd` emits the `section-home` pagespec and scaffold-routes
  registers the `{app}.{module}.{section}` root key.

### SCR-021 — A read-shaped action declares an observable result
- **Severity**: warn (heuristic — the remedy is an authoring decision), ok
  otherwise.
- Check: a screen action whose name/code matches a READ shape
  (`preview|forecast|simulat|calcul|comput|histor|analys|projection|-at$` — or
  the FR equivalents `prévision|historique|simulation|aperçu|bilan`) but
  declares no visible output (no result screen, no response DTO downstream) →
  « probable action de lecture : déclarez ce qu'elle retourne ». The
  deterministic downstream gate is PRD-124 (err on the pagespec).
- The smell it catches early: a use case authored as « le système calcule … »
  whose screen action ships as a fire-and-forget button — the computed value
  never reaches the user.

### SCR-022 — A SmartDashboard lives on an entity
- **Severity**: warn (a `SmartDashboard` in a section with no dominant
  entity), ok otherwise.
- Check: every `SmartDashboard` screen binds an entity (the endpoint host —
  the dev chain generates the dashboard endpoint per host entity). A section
  without one: bind the dominant entity, or re-model the surface as a
  `section-home` (widgets/quickLinks — the platform's KPI seam). Deterministic
  downstream gate: PRD-125 (err on the pagespec).
- The class it closes: two dashboards shipped as frontend pages with NOTHING
  to call — no table, no controller, 12 AC against a surface with no server.

### SCR-023 — An instance verb in header scope is a confirmed decision
- **Severity**: warn (a demand for a decision, never an interdiction), ok
  otherwise.
- Check: a screen action whose code matches `INSTANCE_STATE_VERBS`
  (lib/page-spec-actions — freeze/close/validate/approve/suspend/archive/…)
  declared at HEADER scope without any parameter designating ONE instance →
  « ce verbe vise UNE instance : confirmez le traitement de masse assumé, ou
  passez l'action en scope row ». The client's `freeze` sans paramètre froze
  every complete record at once.

### SCR-024 — Every user-goal use case is served by a surface
- **Severity**: err (any uncovered user-goal UC), ok otherwise.
- Until this rule, NOTHING anywhere required « chaque UC est servi par ≥ 1
  écran, ≥ 1 action custom ou le runtime scheduled » — SCR-005 checks the
  REVERSE direction (screen → UC, warn), so a fully-specified UC with no
  surface at all passed every gate green and its `[Fact]`s failed later with
  nothing to point at (the phantom-UC shape).
- Run this check **DETERMINISTICALLY — never recount by eye** (module scope;
  filter findings down to the audited section when running section-scoped):

  ```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.ucs[]` entry with `ba: "uncovered"` to one SCR-024 err
  finding (cite the UC code + title + its `sourceFile`). Semantics the CLI
  applies:
  - a `scheduled` UC is covered by the scheduled surface (derive-job-specs →
    runtime, DEV-API-028);
  - `subfunction`/`summary` levels are exempt (reached through their callers'
    surfaces) — declared via the heading parenthetical or a `- **Niveau** :`
    bullet; an UNDECLARED level counts as user-goal (fail-closed);
  - only the sanctioned screen.md channels count (`- **Cas d'usage liés** :`
    field, `UC: UC-…` action tag) — loose prose mentions never cover.
- The PRD-side leg of the same run (`prd: "uncovered"`) belongs to
  `/ba-audit-prd` **PRD-131** — do not double-report it here.
- Fix: `/ba-create-screen` (link the UC on its owning screen or action), mark
  the UC `scheduled`, or declare its level in `use-case.md`.

### SCR-025 — The shared tab bar stays within budget (inner + related)
- **Severity**: warn (> 7 shared-bar tabs), err (> 9), ok otherwise.
- The symmetric term of SCR-009: that rule makes « zero related tab » an err,
  NOTHING bounded the accumulation — a fiche can reach 12 triggers with every
  gate green. Inner `**Onglet « X »**` bullets and `**Onglet lié**` bullets
  render on ONE TabStrip (form-screens.md: « count both »); an `affichage
  summary` bullet is band-bound (count cartouche above the strip) and never
  counts.
- Run this check **DETERMINISTICALLY** — it rides the SAME `derive-related-tabs`
  validate run as SCR-009/SCR-014: map every **RTV-009** violation verbatim
  (warn→warn, err→err; quote its message — it names the remedies). A
  detail-mode screen with a create-form sibling is counted as the unified
  fiche (field-tab term 0); a later `direct` opt-out under-counts here and is
  caught by the PRD leg (PRD-133 ← RTV-108) — fail-open in the safe direction.
- The remedy is NEVER dropping an authored tab (PRD-103 blocks the loss):
  switch inert satellites to `affichage summary` and/or regroup own fields
  with `**Section « … »**` bullets (decision table in
  `levels/form-screens.md`).
- Fix: `/ba-create-screen`.

## Output

Write `_audit/screen.md` per the doc-templates skeleton:
- Header `# Audit screen — <APP> / <MODULE> / <section>` + `_<date> · Verdict : <emoji> N warn · M err · K ok_`.
- `## ✅ Conforme`, `## ⚠️ Avertissements`, `## ❌ Bloquants` sections; one bullet
  per finding. For `warn`/`err`: what's wrong (offending codes **bold**), why it
  matters, and a `→` fix naming `/ba-create-screen`.
- 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 screens 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/screen.md` as usual — the orchestrator reads these files.
