---
phase: rules
kind: level
level: identify
---

# Level 1 — IDENTIFY & CLASSIFY

> Discover and propose **5–10 candidate rules**, each already classified
> (`Type`, scope, severity). Conditions/expressions/examples are filled at
> Level 2. The file model (read tree → propose → AskUserQuestion → Write doc)
> and the `règles-métier.md` skeleton live in `SKILL.md` — this file is the
> proposal heuristic.

## Read FIRST (in parallel, from the tree)

| Source | Where | What to extract |
|--------|-------|-----------------|
| Use cases | the scope's `use-case.md` | preconditions, postconditions, exception flows → each non-trivial entry is a candidate rule |
| Entities | the module's `entité.md` (if present) | fields that suggest invariants (email, status, amount, stock, date, identifier) |
| Existing rules | the scope's `règles-métier.md` | avoid duplicates; work alongside, never over |
| Node context | the node's `index.md` (`## Contexte`, `## Hors-périmètre`) | domain framing + explicit exclusions |
| Level 0 context | conversation | jurisdiction/sector/size captured in the prelude |

## Discovery paths — use ALL that apply

### Path A — from use cases (when UCs exist)
For each UC in the scope's `use-case.md`:
- precondition expressing a constraint ("user must be authenticated") → `validation`
- precondition expressing a state ("document must be DRAFT") → `state-transition`
- postcondition invariant ("audit log updated") → `workflow`
- postcondition calculation ("total recomputed") → `calculation`
- exception-flow trigger → almost always a `constraint`/`validation` (its "what
  happens" becomes the rule's error message + code)

### Path B — from the data model / entities (when `entité.md` exists)
Scan attributes for invariants:

| Field hint | Likely candidate rules |
|------------|------------------------|
| `email` / `mail` | format validation, uniqueness |
| `password` / `secret` | strength, hashing required |
| `status` / `state` | enum constraint, state transition |
| `amount` / `price` / `total` | non-negative, max range, currency, calculation |
| `quantity` / `stock` | non-negative, integer, max |
| `date` / `start` / `end` | past/future bounds, ordering (start < end) |
| `iban` / `siret` / `vat` | format + checksum |
| `code` / `reference` | unique, immutable, format ; **`numbering`** when auto-generated/sequential (e.g. `AFF-{YY}-{NNNN}`) |
| `*Id` (FK) | referential integrity, soft-delete tombstone |

### Path C — from organizational policies & regulations
Scan the conversation for: GDPR/data protection (retention, erasure,
anonymization), audit/compliance (immutable trail), financial regulations (VAT,
invoice numbering, rounding), industry-specific (HIPAA, AML/KYC, labor law),
internal policies (approval thresholds, escalation, SLA). These exist
**independently of any UC** — propose them standalone, scoped to the relevant node.

### Path D — cross-cutting concerns
"All create operations set createdBy/createdAt", "all mutations are logged", "all
monetary amounts use 2-decimal precision" → `cross-cutting`.

### Path E — from the menu hierarchy (always available after the menu phase)
Systematic rules emerge from the structure itself; needs no UCs.

**Application level** (per app `index.md`):

| Pattern | Candidate rule | Type |
|---------|----------------|------|
| App exists | "All modules in {app} comply with {domain} regulations" | `compliance` |
| App exists | "All user actions in {app} produce an audit-trail entry" | `cross-cutting` |
| Multiple modules | "Data shared between modules keeps referential integrity" | `integrity` |
| Cross-module access | "Only roles with {app}-access may view any {app} module" | `access` |
| Session/auth | "All {app} pages require an authenticated session" | `access` |
| Data retention | "Inactive {app} records are anonymised after N months" | `compliance` |

→ Write at `<APP>/règles-métier.md`, `## Portée : {APP}`.

**Module level** (per module `index.md`):

| Pattern | Candidate rule | Type |
|---------|----------------|------|
| Module exists | "Access to {module} requires the module-level permission" | `access` |
| Sensitive data | "All {module} data must be auditable (who/what/when)" | `cross-cutting` |
| Financial data | "Monetary amounts in {module} use 2-decimal precision" | `constraint` |
| Status workflows | "Status transitions in {module} follow the state machine" | `state-transition` |
| Ownership scoping | "Only the {module} record owner can update it" | `access` (own) |
| Segregation of duties | "User who created a {module} record cannot approve it" | `workflow` |
| No orphan | "Every {module} record must have an active owner" | `integrity` |

→ Write at `<APP>/<MODULE>/règles-métier.md`, `## Portée : {APP} / {MODULE}`.

Access rules carry the permission spec — see `levels/access-rules.md`.

**Section level** — approval sections → threshold `workflow`; dashboards → data
aggregation `derivation`; import/export → format `validation`. Write at the
section's `règles-métier.md`.

## Domain knowledge — research weak spots before proposing
Domain rules vary wildly by industry. Before proposing in an unfamiliar domain,
ground yourself: read the node `## Contexte`, lean on the Level 0 context, and if
needed fetch current domain references via the `ctx7` CLI / a web search rather
than emitting generic rules. Cite the source in the rule's context line
("source : Code du travail FR, Art. L1243-13" / "OWASP auth best practices").
Discard any researched rule that does not map to a node in the tree.

## Classify each candidate inline

**Type** — match the phrasing: "must be valid/unique/formatted" → `validation`;
"is computed as" → `calculation`; "transitions A→B" → `state-transition`; "only
the owner/assignee can" → `ownership`; "X cannot exceed/be < N" → `constraint`;
"A derived from B+C" → `derivation`; "if X then approval/notification" →
`workflow`; "must reference an existing Y / no orphan" → `integrity`; "all
operations of type X do Y" → `cross-cutting`; "who can do X on which scope" →
`access`; "gets an auto-generated sequential code/number formatted as …" →
`numbering`. No fit → a domain-specific kind.

**Scope** — entity invariant or state machine → module doc; process inside a
section → section doc; strategic/compliance for the whole app → app doc.

**Sévérité** — `err` (action rejected — default), `warn` (proceeds + warning/
audit), `info` (logged only). Note business **priority** in the context line if
useful (critical/high/medium/low) — it is guidance, not a doc field.

## Ask the user (closed choices)
Present the 5–10 candidates grouped by type, then ask via **AskUserQuestion**
(multi-select) which to keep — pre-select the strong ones (typically 60–80 %).
Example proposal prose:

```
D'après vos cas d'usage, votre modèle de données et le domaine {domaine} :

Règles de validation
- BR-001 — Email unique (USER, validation, err)
- BR-002 — Téléphone au format E.164 (USER, validation, err)
Règles de calcul
- BR-003 — TVA = base × taux (INVOICE, calculation, err)
Règles d'intégrité (issues du modèle)
- BR-004 — Facture ne référence pas un client supprimé (integrity, err)
Règles de politique (sans UC)
- BR-005 — Données personnelles anonymisables sur demande (cross-cutting, err)
```

Then the AskUserQuestion multi-select with those candidates as options.

## After the user answers
Acknowledge briefly, then **Write the scope's `règles-métier.md`** with the
retained rules (classified). At Level 1 a rule may be a **draft** (no
condition/expression/examples yet) — that is fine to checkpoint progress, but
move straight to Level 2 to elaborate before any handoff: `/ba-audit-rules`
refuses a passing verdict until every rule has at least one valid + one invalid
example.

## Quality checks before proposing
For each candidate: is it about the **business** (not the UI)? Is it
**deterministic** (a programmer could implement it)? Does it map to a node in the
tree? Is it **not a duplicate**? Could a developer write a failing test for it? Is
the `Type` appropriate and the severity consistent?
