---
name: ba-audit-prd
description: >
  Audits the on-disk PRD of ONE module in a `.smartstack/ba/` project — checks
  across 7 dimensions: structure, completeness, clarity, consistency, traceability,
  feasibility, slices + per-page contract + custom-action contract. Reads `prd.md`,
  the three `prd.*.md` slices and the `pagespecs/*.md` blocks against the upstream
  BA docs, then writes a verdict to `_audit/prd.md` carrying the dev-readiness
  gate (`GO|NO-GO`). GO is the gate `/ba-develop` reads. User Story / Acceptance
  Criteria checks live in `/ba-audit-use-cases` (UC-012..018) — the PRD no longer
  carries US/AC sections; AC live under each UC in `use-case.md`. Run after
  `/ba-create-prd`.
allowed-tools: [Read, Write, Glob, Grep]
---

# ba-audit-prd — PRD quality audit (per module)

You audit the **PRD of ONE module** against the checks below and write a
verdict file. The checks keep their original intent and codes; only the I/O is
file-based.

> **No US/AC checks here.** User Stories and Acceptance Criteria are NOT in the
> PRD — they live under each UC in `<section>/use-case.md` as
> `**Acceptance Criteria**` fields, audited by `/ba-audit-use-cases` (UC-012..018).
> Legacy PRD rules that targeted `## User Stories` / `## Acceptance Criteria` /
> `AC-US{n}-{m}` ids were deleted (PRD-002/003/004/012/013/014/021/027/032/033/047/062/063/085)
> or migrated to `/ba-audit-use-cases` (PRD-022/023/024/031/034/048 → UC-014..018).

There is **no database, no Studio, no injected JSON envelope, no
`structured`/`markdown`/`slices` blocks** — the PRD lives on disk as `.md` files
and the `.md` verdict IS the record. The verdict header carries the dev-readiness
gate that `/ba-develop` reads.

## File model — how to audit

1. **Read the PRD subtree** `.smartstack/ba/<APP>/<MODULE>/`:
   - `prd.md` — `## Context`, `## Goals`, `## Non-goals`, `## MoSCoW`,
     `## Technical constraints`. (No `## User Stories` / `## Acceptance Criteria`
     — those live under each UC in `<section>/use-case.md`.)
   - `prd.entities.md`, `prd.api.md`, `prd.frontend.md` — the three `# Phase:`
     slices (self-contained + disjoint, one per dev sub-agent).
   - `pagespecs/<Entity>.<view>.md` — one per screen; each a fenced ```json
     pageSpec block + a human body. These are the contract feeding `scaffold-component`.
   - `claude.md` — the generated module CLAUDE.md (read for PRD-052).
2. **Read the upstream BA docs** in the same / parent folders, so traceability and
   coverage checks resolve (codes are Grepped on the tree — if a code is not found
   there, it does not exist; do not invent it):
   - `<MODULE>/entité.md` (entities `ENT-…` + PascalCase names, attributes, relationships, computed),
   - `<MODULE>/rbac.md` (permission matrix),
   - `<MODULE>/<section>/screen.md` (screens `SCR-…`, SmartComponent type, columns/filters/actions),
   - `<MODULE>/<section>/use-case.md` (use cases `UC-…`),
   - `<MODULE>/<section>/règles-métier.md` (business rules `BR-…`, valid/invalid examples),
   - `<APP>/acteur.md` (actor roles `BA-…-AC-…`),
   - the `index.md` **out-of-scope cascade** (project root → `<APP>` → `<MODULE>`,
     the `## Hors-périmètre` bullets).
3. **Apply** the checks below.
4. **Write** the verdict to `.smartstack/ba/<APP>/<MODULE>/_audit/prd.md` (skeleton
   in `_workflow/doc-templates.md`), with the dev-readiness gate header. Overwrite
   each run. Then print a concise GO / NO-GO chat summary in business terms.

There is **no `[ACTION]` envelope, no `[QUESTION]` block, no `persist:`, no
`--- CURRENT … ---` state, no i18n label codes, no fix-finding handler, no
targeted-regen endpoint, no `GET /prds`, no sidecar/frontend, no fan-out arrays**.
This audit is read-only — it never patches the PRD; each non-ok finding routes to
the owning phase skill to re-run.

## Scope

- **Module scope** (always): audit exactly one module's PRD. Resolve every cross
  reference against that module's upstream docs (+ the app `acteur.md` and the
  out-of-scope cascade). Do not re-audit a sibling module's PRD.
- If `prd.md` (or all three slices, or `pagespecs/`) is absent, the PRD has not
  been generated for this module — report a single blocking finding "PRD not
  generated → run `/ba-create-prd`", emit NO-GO, and stop.

---

## Dimension 1 — Structure & the contract gate (PRD-001, 005..010)

Schema and ID conformity. Failures here mean the PRD cannot be processed downstream.

- **PRD-001′** `err` — *(was: "`structured` parses against the Zod schema". Re-targeted —
  this is the new contract gate between the `.md` tree and `scaffold-component`.)*
  **Every** `pagespecs/*.md` file contains exactly one fenced ```json block, that
  block parses as valid JSON, and it carries every required field, each non-empty:
  `screenCode`, `appCode`, `module`, `section`, `entity`, `view`, `permission`,
  `screenType`. A pagespec whose JSON does not parse, or that drops any required
  field, breaks `scaffold-component`. → `/ba-create-prd`.
- **PRD-005** `err` — `prd.md` is non-empty and contains all five `##` anchor
  sections, verbatim: `## Context`, `## Goals`, `## Non-goals`, `## MoSCoW`,
  `## Technical constraints`. *(structural-file check — US/AC sections were
  removed; the test contract lives in each UC's `**Acceptance Criteria**` field
  in `use-case.md`.)* → `/ba-create-prd`.
- **PRD-006** `err` — All three slice files exist and are non-empty:
  `prd.entities.md`, `prd.api.md`, `prd.frontend.md`. (3 slices since 2026-04 —
  `entities` is the combined domain+data view; there is no separate `domain`/`data`
  file.) *(structural-file check)* → `/ba-create-prd`.
- **PRD-007** `warn` — `prd.md` declares a `## Technical constraints` section (may
  be empty, but the heading must be present). → `/ba-create-prd`.
- **PRD-008** `warn` — Every entity referenced in `prd.entities.md` has a non-empty,
  unique name (no duplicate entity lines). → `/ba-create-prd`.
- **PRD-009** `warn` — Every `screenCode` across the `pagespecs/*.md` blocks is
  non-empty and unique (no two pagespecs share a `screenCode`). → `/ba-create-prd`.
- **PRD-010** `warn` — Every `permission` value across the pagespec blocks is
  non-empty (uniqueness not required — many views legitimately share `…read`). → `/ba-create-prd`.

---

## Dimension 2 — Completeness (PRD-011, 015..020)

Minimum content levels. An incomplete PRD leads Claude to invent filler.

- **PRD-011** `err` — `## Non-goals` lists ≥ 3 bullets. Non-goals prevent feature
  hallucination downstream. → `/ba-create-prd`.
- **PRD-015** `warn` — `## MoSCoW` lists ≥ 1 **Must** item. → `/ba-create-prd`.
- **PRD-016** `warn` — `## MoSCoW` populates at least one of **Should** / **Could**
  (a PRD with nothing beyond Must is probably under-scoped). → `/ba-create-prd`.
- **PRD-017** `warn` — `## Goals` lists ≥ 2 goals (a single goal usually hides scope). → `/ba-create-prd`.
- **PRD-018** `info` — `prd.entities.md` declares ≥ 1 entity (pure-UI modules may
  legitimately have 0 — informational only). → `/ba-create-prd`.
- **PRD-019** `info` — `pagespecs/` holds ≥ 1 pagespec (background-only modules may
  have 0). → `/ba-create-prd`.
- **PRD-020** `info` — `prd.api.md` lists ≥ 1 permission (same exception). → `/ba-create-prd`.

---

## Dimension 3 — Clarity (PRD-025, 026, 028..030)

Phrasing that can be acted on without reinterpretation. Logic UNCHANGED, new input.

- **PRD-025** `warn` — Each goal starts with an action verb (allow / enable /
  produce / guarantee / reduce / surface) rather than a noun phrase. → `/ba-create-prd`.
- **PRD-026** `warn` — Each non-goal is a **negated** sentence ("we will NOT",
  "out of scope:", "explicitly excludes"). Descriptive non-goals are ambiguous. → `/ba-create-prd`.
- **PRD-028** `info` — Sentences in `## Context` stay under ~40 words; longer ones
  get split. → `/ba-create-prd`.
- **PRD-029** `info` — Acronyms are expanded on first use in `prd.md` (e.g.
  "RBAC (role-based access control)"). → `/ba-create-prd`.
- **PRD-030** `info` — `## Context` names which other modules are touched — or
  states "standalone". → `/ba-create-prd`.

---

## Dimension 4 — Consistency (PRD-035..040, PRD-064)

Cross-field invariants — the document must not contradict itself.

- **PRD-035** `warn` — Every entity named in a `pagespecs/*.md` block (`entity`
  field) also appears in `prd.entities.md` (screens can't render an entity the PRD
  doesn't declare). → `/ba-create-prd`.
- **PRD-036** `warn` — Every pagespec `permission` is the
  `module.section[.resource].action` shape (3 or 4 segments, lowercase kebab, no
  app prefix), matching the `rbac.md` matrix shape. → `/ba-create-prd`.
- **PRD-037** `warn` — Every role named in `prd.api.md` / pagespec actions also
  appears as an actor upstream (`acteur.md`). No role materialises in the API
  slice without being defined upstream. → `/ba-create-rbac`.
- **PRD-038** `warn` — `## MoSCoW` **Must** items do not also appear under
  **Won't**. → `/ba-create-prd`.
- **PRD-039** `warn` — Every `## MoSCoW` **Won't** item is echoed in `## Non-goals`
  (a won't-have is a non-goal). → `/ba-create-prd`.
- **PRD-040** `info` — `prd.md` mentions every entity, screenCode and permission
  from the slices/pagespecs at least once (low-fidelity render flag). → `/ba-create-prd`.
- **PRD-064** `warn` — Every non-empty `## Hors-périmètre` line in the **out-of-scope
  cascade** (project root `index.md` + `<APP>/index.md` + `<MODULE>/index.md`) is
  reflected by at least one **semantically equivalent** non-goal in `## Non-goals`.
  Paraphrases are fine; the meaning MUST be preserved. Missing or contradicting an
  upstream out-of-scope warns (raises feature-hallucination risk downstream). → `/ba-create-menu` (fix the cascade) or `/ba-create-prd` (recopy it).

---

## Dimension 5 — Traceability (PRD-041..046, 049, 050)

Every piece of the PRD must connect to something upstream. Logic UNCHANGED, new input.

- **PRD-041** `err` — Every entity in `prd.entities.md` resolves to an `ENT-…`
  entity in the module `entité.md`, matched by either the PascalCase **name** or
  the BA stable **code**. No phantom entities. → `/ba-create-data-model`.
- **PRD-042** `err` — Every `screenCode` in a pagespec resolves to a `SCR-…`
  heading in some `screen.md` of the module. → `/ba-create-screen`.
- **PRD-043** `err` — Every pagespec `permission` resolves to a permission in
  `rbac.md`. The 4-seg vs 5-seg (resource-scoped) shapes are NOT interchangeable —
  a permission missing the `.{resource}.` segment must not resolve to one that has
  it (and vice-versa), since the resource segment changes the RBAC scope. → `/ba-create-rbac`.
- **PRD-044** `warn` — Every entity has at least one screen that displays it.
  **Skip** when the entity's `entité.md` classification is lookup / reference /
  junction / component (those surface inside parent screens, never as standalone
  pages). Orphan aggregate-root / full-module entities still warn. → `/ba-create-screen`.
- **PRD-045** `warn` — Every screen (`SCR-…` in `screen.md`) is covered by at least
  one permission (read / create / update / delete). → `/ba-create-rbac`.
- **PRD-046** `warn` — Every permission in `rbac.md` maps to at least one use case
  upstream (a `UC-…` whose flow uses that action verb). Disconnected permissions warn. → `/ba-create-use-case`.
- **PRD-049** `info` — Every `## Goals` statement is backed by at least one UC in
  the module's `use-case.md` files (a UC whose title or main flow speaks to that
  goal). → `/ba-create-use-case`.
- **PRD-050** `info` — Every `## Non-goals` statement is traced by an explicit
  exclusion (it is itself the exclusion list — flag a non-goal that contradicts a
  goal or a Must item). → `/ba-create-prd`.

---

## Dimension 6 — Feasibility (PRD-051..055)

Technical constraints must fit the generated-project stack.

- **PRD-051** `warn` — `## Technical constraints` only references the generated
  stack (`.NET 10`, `EF Core 10`, `React 18`, `Vite`, `Tailwind`, `Shoelace`,
  `SignalR`, `PostgreSQL / SQL Server / Azure SQL`). Anything outside belongs in a
  custom CLAUDE.md rule, not the PRD. **SQLite must never appear** (it is the
  Studio's dev DB, not a generated-app target). → `/ba-create-prd`.
- **PRD-052** `warn` — No `## Technical constraints` entry merely repeats a rule
  already in the module `claude.md` (the PRD adds module-specific constraints, not
  repeats). → `/ba-create-prd`.
- **PRD-053** `warn` — Entity attribute types in `prd.entities.md` are EF-Core-
  mappable primitives (`string`, `int`, `long`, `DateTime`, `decimal`, `bool`,
  `Guid`, `enum`). → `/ba-create-data-model`.
- **PRD-054** `info` — Each pagespec `screenType` / `view` maps to one of the
  SmartComponent patterns (list, detail, form, dashboard, kanban, card + the home
  views). → `/ba-create-screen`.
- **PRD-055** `info` — Permissions in `prd.api.md` respect the 11-action SmartStack
  vocabulary (read, create, update, delete, approve, reject, export, import,
  access, manage, admin). → `/ba-create-rbac`.

---

## Dimension 7 — Slices, per-page contract & vibecoding readiness (PRD-056..088)

The three slices must let a sub-agent develop one phase without the rest;
`prd.entities.md` carries the combined domain + data view (entities, attributes,
relationships, business rules, migrations, indices, FKs). The pagespec blocks must
satisfy everything `scaffold-component` expects.

### Slice self-containment & disjointness (PRD-056..061, 094)

- **PRD-056** `err` — `prd.entities.md` covers every entity from the upstream
  `entité.md` AND, for every non-reference entity, an inline **domain invariants**
  section listing each scope-matched `BR-…` from `règles-métier.md` (with code +
  ≥ 1 valid + ≥ 1 invalid example). No UI references in this slice. → `/ba-create-prd`.
- **PRD-057** `err` — `prd.entities.md` describes migrations, indices and FK
  relationships for every declared entity — derivable from the entity list alone,
  no screen references. → `/ba-create-prd`.
- **PRD-058** `err` — `prd.api.md` lists every permission and maps each to an HTTP
  method + route — derivable from `rbac.md` alone. → `/ba-create-prd`.
- **PRD-059** `err` — `prd.frontend.md` lists every screenCode + route; it may
  reference entity names but never EF / repository implementation detail. → `/ba-create-prd`.
- **PRD-060** `warn` — Slices are **disjoint**: no slice duplicates another's
  content (`prd.entities.md` must not declare routes from `prd.api.md`;
  `prd.frontend.md` must not contain the SQL migrations from `prd.entities.md`). → `/ba-create-prd`.
- **PRD-061** `warn` — Each slice opens with a `# Phase: <name>` heading and lists
  its in-scope artefacts as `- [ ]` checkbox bullets. *(structural-file)* → `/ba-create-prd`.
- **PRD-094** `err` — **Self-containment test**: for each slice, every code it cites
  (entity, screen, permission, UC, BR, actor) is **defined inline** in that same
  slice (full body, not a bare ID reference). A sub-agent reading only one slice
  must be able to act. AC are intentionally NOT in this list — they live in
  `use-case.md` next to their UC and the test-scaffolder reads them directly. → `/ba-create-prd`.

### Per-page contract integrity (PRD-070..088)

Every `screen.md` screen produces exactly one pagespec (plus a synthesised
`detail` view per list+form pair). These catch the silent omissions that would
otherwise produce a non-functional PRD downstream.

- **PRD-070** `err` — Every screen in the module's `screen.md` files has a matching
  `pagespecs/*.md` whose `screenCode` equals the screen's `SCR-…` code (**coverage**).
  Synthesised detail entries are tolerated but should carry `needsRefinement: true`
  + a note. → `/ba-create-screen` if the screen is missing upstream, else `/ba-create-prd`.
- **PRD-071** `err` — Every pagespec `permission` matches
  `^[a-z][a-z0-9-]*\.[a-z][a-z0-9-]*\.[a-z][a-z0-9-]*$` (3 segments, lowercase, no
  appCode prefix) — the same shape `validate-page` enforces downstream. → `/ba-create-prd`.
- **PRD-072** `err` — Every pagespec `i18nKeys` carries **parallel key sets across
  the 4 locales `fr/en/it/de`** (the same key set in each). Missing keys per locale
  are the #1 cause of i18n-resolve failures downstream. *(structural-file: 4-locale parity)* → `/ba-create-prd`.
- **PRD-073** `warn` — Every computed column in a pagespec (`isComputed: true`, or a
  `columns[].formatHint`) carries a `formatHint` ∈ `{percent, currency, date,
  datetime, integer, decimal}`. Without it, numeric / date columns render raw. → `/ba-create-prd`.
- **PRD-074** `err` — Every pagespec `actions[].permission` is a valid
  `module.section[.resource].action` string (3 or 4 segments, same regex as PRD-071). Action permissions wrap mutating buttons in
  `<PermissionGuard>` — a wrong shape means an unguarded mutation. → `/ba-create-rbac` if no matching permission, else `/ba-create-prd`.
- **PRD-076** `err` — Where a pagespec declares form defaults, they reference only
  field names the pagespec also exposes as editable — no orphan keys (catches
  rename drift between the BA capture and the form spec). → `/ba-create-prd`.
- **PRD-077** `err` — Every pagespec `entity` appears in `prd.entities.md` (a
  pagespec on an undeclared entity cannot be scaffolded — no DTO to import). → `/ba-create-data-model`.
- **PRD-079** `info`→`warn` — Pagespecs flagged `needsRefinement: true` are surfaced
  with their `refinementNotes`. `info` when the refined ratio < 0.7 (transparency,
  not a block); escalates to `warn` when ≥ 0.7 of pagespecs are flagged (manual
  review recommended before dev). → `/ba-create-prd`.
- **PRD-080** `err` — Every `actions[].labelKey` and `columns[].labelKey` in a
  pagespec exists in that pagespec's `i18nKeys.fr` (and so, by PRD-072, in the 3
  other locales). Pre-resolves the i18n catalogue so downstream `t('key')` lands. → `/ba-create-prd`.
- **PRD-082** `err` — For each pagespec whose `view ∈ {list, kanban, card}`, the
  pagespec `filters[]` **count equals** the matching screen's filter count in
  `screen.md` (no silent drop of filters). *(structural-file: count preserved)* → `/ba-create-prd`.
- **PRD-083** `err` — Every screen in `screen.md` has at least one pagespec with the
  same `screenCode`, and its `view` follows the SmartXxx → view mapping
  (SmartListView → list, SmartForm → form, SmartDashboard → dashboard,
  SmartModuleHome → module-home, …). Synthesised `detail` views are tolerated. → `/ba-create-screen`.
- **PRD-084** `err` — Every entity in the module's `entité.md` is declared in
  `prd.entities.md` (by PascalCase name or BA code) — even entities not exposed by
  a pagespec, because the entities phase scaffolds the domain layer from this list.
  A missing entity amputates the backend. → `/ba-create-data-model`.
- **PRD-086** `err` — For each pagespec matched to a `screen.md` screen of type
  `SmartListView` / `SmartKanban` / `SmartCard`, the pagespec `actions[]` **count
  equals** the screen's action count (catches a silently dropped action).
  **Skip** when the screen type ∈ `{SmartForm, SmartDashboard, SmartModuleHome,
  SmartAppHome, SmartSectionHome}` (those capture actions implicitly). *(structural-file: count preserved)* → `/ba-create-prd`.
- **PRD-087** `err` — Every pagespec `appCode` equals the application code
  (lowercase, no `-web` / `-app` / `-api` suffix). Drift breaks the URL prefix in
  `scaffold-routes` (`componentKey = {appCode}.{module}.{section}`). → `/ba-create-prd`.
- **PRD-088** `err` — Every pagespec `screenCode` is **verbatim** a `SCR-…` code
  from `screen.md` — no abbreviated invented codes. **Tolerate** a synthesised
  `…-detail` code when it strips to a real upstream code by dropping `-detail`, that
  upstream section carries both a `SmartListView` and a `SmartForm`, and the pagespec
  carries `needsRefinement: true` with a note on the view. → `/ba-create-screen`.

### Custom-action contract (PRD-095..101)

Every entry under `pagespec.actions[]` is now subject to the full
`PageCustomActionSchema` declared in `templates/skills/lib/page-spec-actions.ts`.
These rules catch the silent drops that produce the class of bug (a UI button
that POSTs `/sync-from-pce` while the backend exposes `/sync-from-proconcept`).
Standard CRUD action codes (`create`, `read`, `edit`, `update`, `delete`,
`list`, `detail`) skip PRD-096 / PRD-097 / PRD-099 (they need only `code`,
`scope`, `permission`, `labelKey`, `variant`).

- **PRD-095** `err` — Every `pagespec.actions[]` entry parses against
  `PageCustomActionSchema`. Concretely: `code` matches `^[a-z][a-zA-Z0-9]*$`
  (camelCase); `kind ∈ {api, navigate}`; `scope ∈ {row, bulk, header}`;
  `permission` is the `module.section[.resource].action` kebab regex (3 or 4
  segments); `labelKey` is non-empty. Drops
  free-text custom actions that ba-create-prd silently ignored. → `/ba-create-screen` (fix `screen.md`) then `/ba-create-prd`.
- **PRD-096** `err` — For every custom action with `kind: "api"`, `endpoint` is
  either present and kebab-case (`^[a-z][a-z0-9-]*$`) OR absent (the default
  `kebab(code)` will be applied at scaffold time); `httpMethod` is one of
  `GET / POST / PUT / PATCH / DELETE`; `endpoint`, `httpMethod`, `payloadDto`
  are absent when `kind: "navigate"`. → `/ba-create-prd`.
- **PRD-097** `err` — Every `pagespec.actions[].ucReference: UC-…` resolves to
  a use case present in the section's `use-case.md`. The audit Greps the
  `UC-…` code across the section's docs. → `/ba-create-use-case`.
- **PRD-098** `err` — Every `pagespec.actions[].permission` resolves to a
  permission constant in the module's `rbac.md` (same dynamic-segment shape as
  PRD-071 / PRD-074, no app prefix). → `/ba-create-rbac`.
- **PRD-099** `err` — **Endpoint uniqueness per entity**: across the union of
  pagespecs sharing the same `(appCode, module, entity)` triplet, no two
  custom actions of `kind: "api"` share the `(httpMethod, scope, endpoint)`
  triplet. A duplicate would emit a colliding `[HttpVerb("<endpoint>")]` on
  the controller (compile error) or shadow a TypeScript service method.
  Caught here because PRD spans multiple screens of the same entity (list +
  form + detail). → `/ba-create-screen`.
- **PRD-100** `err` — For every custom action with `kind: "navigate"`,
  `targetScreen: SCR-…` resolves to a `SCR-…` code present in some `screen.md`
  of the module (or app, for cross-module navigation). When `targetRoute` is
  also provided, it MUST follow the `routes.<section>.<view>(<arg>?)` shape
  expected by the React Router registry — broken targets crash the page on
  click. → `/ba-create-screen` (fix the target) or `/ba-create-prd`
  (re-resolve the route).
- **PRD-101** `err` — Every `pagespec.actions[].labelKey` exists in that
  pagespec's `i18nKeys.fr` (and so, by PRD-072, in `en/it/de`). Mirrors
  PRD-080 for custom actions specifically — a missing labelKey produces an
  empty button. → `/ba-create-prd`.

### Vibecoding readiness (VIBE-001..009) — upstream coverage the dev sub-agent needs

These read the upstream BA docs (same content, file input). When the upstream doc
is absent, emit an `info` "upstream resolution unavailable" instead of failing.

- **VIBE-001** `err` — Every entity in `prd.entities.md` exists in `entité.md` with
  ≥ 1 attribute of an EF-mappable `dataType`. Otherwise the entities sub-agent must
  guess attributes. → `/ba-create-data-model`.
- **VIBE-002** `err` — Every entity in `entité.md` covered by the PRD has an
  unambiguous tenant mode (the module's multi-tenant convention is stated, not
  left implicit). → `/ba-create-data-model`.
- **VIBE-003** `err` — For every N:M relationship in `entité.md`, `prd.entities.md`
  names the junction table explicitly (else `scaffold-entity` emits only a simple
  FK and breaks). → `/ba-create-data-model`.
- **VIBE-004** `err` — For every permission ending in `.create|.update|.delete`,
  the `prd.api.md` slice references ≥ 1 validating business rule (`BR-…`) — OR the
  upstream `règles-métier.md` truly has none for that entity (acknowledged). Else
  `scaffold-business` generates an empty validator and integration tests pass
  silently. → `/ba-create-business-rules`.
- **VIBE-006** `err` — `## Technical constraints` names the target DB provider
  explicitly (`PostgreSQL`, `SQL Server`, or `Azure SQL` — never `SQLite`). Else
  `scaffold-migration` emits a neutral migration that can break on the real
  provider. → `/ba-create-prd`.
- **VIBE-007** `err` — For the application, `rbac.md` defines ≥ 1 native role and
  the permission floor (`access` + `read`). Without it `scaffold-core-seed` emits an
  amputated seed (a dev role with no base permission). → `/ba-create-rbac`.
- **VIBE-008** `err` — Every entity in `prd.entities.md` is the target of ≥ 1
  permission in `rbac.md` (via the section, 4-seg, or the resource segment, 5-seg).
  Else the API phase has no controller to scaffold for that entity. → `/ba-create-rbac`.
- **VIBE-009** `err` — For every `view: form` pagespec, the editable field list is
  non-empty and every field belongs to that entity's attributes in `entité.md` (no
  orphan). Else `scaffold-component` emits an `<input>` for a non-existent attribute
  and the runtime crashes. → `/ba-create-screen`.

> The richer Studio-only fields (specHash idempotency, breadcrumb chains,
> errorScenarios / testScenarios / referenceData / endpointSpecs / domainEvents
> sidecars) were checked by the legacy PRD-075/078/081/089..097/VIBE-005/011 against
> the injected JSON envelope. On disk those structures are folded into the slices
> and pagespec bodies, so their intent is carried by PRD-056/057/072/082/086/094 and
> VIBE-004 above. There is **no** separate sidecar to validate and **no** partial-PRD
> gate (PRD-089) — a `.md` PRD is either present and audited or absent (handled in
> Scope). There is no `[ACTION]` fix handler; every fail routes to a phase skill.

---

## Quality score & the dev-readiness gate

Count `err`, `warn`, `ok` across every check above (skipped checks don't count).
Keep the source's per-dimension saturating-monotonic formula:

```
score = round( 100 × 100 / (100 + 10·err + 3·warn) )
```

- `err` (×10) blocks the gate; `warn` (×3) is a quality hit; `info` (×0) is
  observation only. Examples: 0e/0w → 100, 0e/5w → 87, 1e/3w → 84, 3e/5w → 69.

**Dev-readiness gate** (what `/ba-develop` reads):

```
GO  ⟺  score ≥ 80  AND  err = 0
NO-GO otherwise
```

A GO is the gate for `/ba-develop`. Below GO, the PRD is not handed
to development — fix the findings (each routes to its owning phase skill) and re-run.

---

## Output — `.smartstack/ba/<APP>/<MODULE>/_audit/prd.md`

Write the verdict per the `_workflow/doc-templates.md` audit skeleton, but the
header MUST carry the dev-readiness gate so the orchestrator can read it:

```markdown
<!-- ba:audit dimension=prd scope=CRM/PIPELINE -->
# Audit PRD — CRM / PIPELINE
_2026-05-21 · Verdict : GO · score 92/100 · 0 err · 3 warn_

## ✅ Conforme
- **PRD-001′** — chaque spécification de page (`pagespecs/*.md`) est un bloc JSON
  valide et complet — contrat prêt pour la génération de composants.
- **PRD-005 / PRD-006** — le PRD et ses trois tranches de phase sont présents et complets.
- **PRD-070** — chaque écran défini a sa spécification de page (couverture complète).

## ⚠️ Avertissements
- **PRD-064** — l'exclusion « la facturation est gérée ailleurs » (hors-périmètre)
  n'est pas reprise dans les non-objectifs.
  - Pourquoi : risque que le développement réintroduise une fonction explicitement écartée.
  - → Recopier l'exclusion via `/ba-create-prd` (ou ajuster le périmètre via `/ba-create-menu`).

## ❌ Bloquants
- _(aucun)_
```

- The header line is `_<date> · Verdict : <GO|NO-GO> · score <N>/100 · <e> err · <w> warn_`.
  `GO` requires `score ≥ 80` AND `0 err`.
- Findings are grouped `✅ Conforme` / `⚠️ Avertissements` / `❌ Bloquants`. Rule
  codes stay **bold** (greppable) but are explained in business terms. Each non-ok
  finding gives **what's wrong** (offending codes/paths in bold), **why it matters**,
  and a `→` **fix** naming the owning phase skill (`/ba-create-prd`,
  `/ba-create-data-model`, `/ba-create-screen`, `/ba-create-rbac`,
  `/ba-create-business-rules`, `/ba-create-actors`, `/ba-create-use-case`,
  `/ba-create-menu`).
- Re-Write the whole file each run (overwrite — it is a fresh verdict).

## Chat summary

After writing the file, print a concise GO / NO-GO summary in the user's language,
in **business terms** (not rule codes): the verdict + score + counts, the top
blockers (max 5, one line each, naming the fix skill), and a plain statement that
**a GO is the gate for `/ba-develop`** — below GO, fix the blockers
and re-run before development.

## Used by the readiness orchestrator

`/ba-audit-pre-dev` aggregates the per-dimension verdicts. When invoked as part of
pre-dev readiness, still write `_audit/prd.md` as usual — the orchestrator reads
this file's `Verdict :` header.
