---
name: step-01-cadrage
description: Application/module framing - listen, reformulate, challenge, anticipate, bound scope
model: opus
next_step: steps/step-02-decomposition.md
---

> **Context files:** `_shared.md` | `_elicitation.md` | `_architecture.md` | `_suggestions.md`
> **Reference (4d-bis):** `references/entity-architecture-decision.md` — Entity scoring, domain coherence, section patterns

# Step 1: Cadrage (Framing)

## MANDATORY EXECUTION RULES

- ALWAYS use ULTRATHINK mode for this step
- ALWAYS apply the Elicitation Techniques from `_elicitation.md`
- NEVER accept vague answers — probe deeper
- NEVER define entities or business rules here — that's per-module in step-03
- ALL questions via AskUserQuestion tool (NEVER as text dumps)
- ALL communication in `{language}` (from feature.json.metadata.language)
- **NEVER skip the reformulation phase** — it is the foundation of good analysis
- **NEVER auto-infer cadrage data without client validation** — every key decision is confirmed

## YOUR TASK

Frame the analysis scope at the **application level** through an interactive conversation with the client: understand the problem, stakeholders, scope, and define application-level roles. The analysis phase is ALWAYS interactive — the AI listens, reformulates, challenges, and validates with the user.

**Key difference from step-03:** This step does NOT define entities, business rules, or process flows. Those are per-module and handled in step-03.

---

## EXECUTION FLOW — 5 PHASES

```
Phase 1: ECOUTE           → Read brief + codebase pre-research + silent pre-analysis
Phase 2: REFORMULATION     → Rephrase the need back to the client for validation
Phase 3: APPROFONDISSEMENT → Challenge assumptions with targeted questionnaires
Phase 4: ANTICIPATION      → Suggest unexpressed needs from domain expertise
Phase 5: PERIMETRE         → Bound scope with roles, coverage matrix (sections + resources)
```

---

## PHASE 1: ECOUTE (Listen)

### 1. Read Current State

```
ba-reader.findFeature({feature_id})
→ Read metadata: application, language, workflow.mode, useCase
→ Read cadrage section (if resuming)
```

IF cadrage already completed (status = "framed"):
  Display: "Cadrage already completed. Loading next step."
  Load: steps/step-02-decomposition.md
  STOP

### 2. Codebase Pre-Research

> **Understand what already exists before engaging the client.**

**Phase 2a: MCP Tools (if available)**
```
IF mcp_available:
  Call: mcp__smartstack__analyze_extension_points
  → Discover existing modules, entities, services

  Call: mcp__smartstack__api_docs
  → Existing API documentation

  Call: mcp__smartstack__validate_conventions
  → Validate application/module naming

  Store findings in {codebase_context}
```

**Phase 2b: Parallel Codebase Agents**
```
Launch 3 agents in parallel:
  Agent 1: Search for existing domain entities (Glob: **/Domain/**/*.cs)
  Agent 2: Search for existing services/integrations (Grep: IService, IRepository)
  Agent 3: Search for existing page patterns (Glob: **/pages/business/**/*.tsx)

Merge findings into {codebase_context}
```

### 2b. Silent Pre-Analysis (ULTRATHINK — no output to client)

> **The AI prepares the conversation before speaking.** This is NOT output — it's internal reasoning.

Load: [references/cadrage-pre-analysis.md](../references/cadrage-pre-analysis.md)

Analyze `{feature_description}` silently:

1. **Identify problem type** from keywords (replace, automate, centralize, new tool)
2. **Extract explicit modules/features** mentioned in the description
3. **Detect shadow zones** — what is NOT said but should be:
   - Missing stakeholders (who else would use this?)
   - Missing sections (reports mentioned but no details?)
   - Implicit relationships (1:1, 1:N — why this cardinality?)
   - Missing non-functional needs (security, performance, compliance)
4. **Prepare challenge questions** — specific to this brief, not generic
5. **Pre-identify anticipated sections and resources** per detected module

Store in `{pre_analysis}` (internal use only, NOT written to feature.json):
```yaml
pre_analysis:
  problem_type: "new_tool|replace|automate|centralize"
  detected_modules: [{name, description, detected_sections}]
  shadow_zones: [{topic, why_it_matters, challenge_question}]
  anticipated_suggestions: [{suggestion, justification, module}]
```

---

## PHASE 2: REFORMULATION (Rephrase & Validate)

### 3. Reformulation du besoin (MANDATORY — NEVER SKIP)

> **Golden rule of requirements analysis: NEVER proceed without reformulating.**
> The analyst must prove they understood before digging deeper.
> This is what distinguishes a professional analysis from a superficial one.

**Process:**

1. From `{feature_description}` and `{pre_analysis}`, build a structured reformulation.

2. **Display as markdown** (direct text output, NOT inside AskUserQuestion):

```
## {language == "fr" ? "Voici ce que j'ai compris de votre besoin" : "Here is my understanding of your need"}

**Application :** {detected application name}
**Objectif :** {reformulation in 2-3 sentences of the global need — in the client's own words, not technical jargon}

**Modules identifiés :**
- **{Module 1}** : {functional description}
  - Section **list** : {entity}-grid, {entity}-filters + pages `/create` et `/:id/edit`
  - Page détail (onglets) : {Infos, {relation_tabs}...}
  - {IF dashboard needed:} Section **dashboard** : {kpi-cards, charts...}
- **{Module 2}** : {functional description}
  - Section **list** : {entity}-grid, {entity}-filters, {entity}-form
  - Page détail (onglets) : {Infos, ...}

**Points que j'ai notés :**
- {specific point 1 from the brief, quoted verbatim when possible}
- {specific point 2}

**Points qui me semblent ambigus ou non précisés :**
- {shadow zone 1 — what I don't know yet}
- {shadow zone 2}
```

3. Then ask via AskUserQuestion:
```
question: "{language == 'fr' ? 'Cette reformulation correspond-elle à votre besoin ?' : 'Does this reformulation match your need?'}"
header: "Validation"
options:
  - label: "{language == 'fr' ? 'Oui, c\'est correct' : 'Yes, correct'}"
    description: "{language == 'fr' ? 'La reformulation reflète bien mon besoin' : 'The reformulation accurately reflects my need'}"
  - label: "{language == 'fr' ? 'Partiellement' : 'Partially'}"
    description: "{language == 'fr' ? 'Certains points sont corrects mais d\'autres à ajuster' : 'Some points are correct but others need adjustment'}"
  - label: "{language == 'fr' ? 'Non, à revoir' : 'No, needs revision'}"
    description: "{language == 'fr' ? 'La reformulation ne correspond pas à mon besoin' : 'The reformulation does not match my need'}"
```

4. IF "Partially" or "No":
   - Ask for corrections via AskUserQuestion (open-ended "Other" option)
   - Re-reformulate and re-validate (loop until confirmed)

5. Once confirmed, update `{pre_analysis}` with any corrections.

---

## PHASE 3: APPROFONDISSEMENT (Challenge & Deepen)

### 4. Targeted Questionnaires

> **Principle: Do NOT ask ALL questions from ALL questionnaires.**
> Select the RELEVANT questions based on the pre-analysis and detected shadow zones.
> Apply elicitation techniques from `_elicitation.md` after each batch.
> The goal is a CONVERSATION, not an interrogation.

#### 4a. Business Context (ALWAYS — from `questionnaire/01-context.md`)

> Load the full questionnaire reference for elicitation guides and alert signals.

Select the most relevant questions from Q1.1-Q1.12.
**Mandatory minimum:** Q1.1 (problem), Q1.4 (current tools), Q1.8 (vision), Q1.11 (trigger).

Ask in 1-2 batches via AskUserQuestion (max 4 questions per batch).

Apply ULTRATHINK after each batch:
- If answer is vague → probe deeper using the elicitation guide from 01-context.md
- If answer is solution-oriented → apply Technique 1 (reformulate as need)
- If answer is superficial → apply Technique 2 (chain of whys)
- If answer is excellent → record and move on

#### 4b. Stakeholders (ALWAYS — from `questionnaire/02-stakeholders.md`)

**Mandatory minimum:** Q2.1 (users), Q2.5 (tasks per profile), Q2.9 (access levels).

Ask in 1-2 batches. After each batch:
- If only 1 user type mentioned → probe: "Who else interacts? Managers? Admins? External users?"
- If "everyone sees everything" → challenge: "Even interns? Contractors? Salary data?"
- If tasks are generic → ask for a concrete scenario: "Walk me through a typical day"

#### 4c. Functional Scope (ALWAYS — from `questionnaire/03-scope.md`)

**Mandatory minimum:** Q3.2 (must-have), Q3.4 (exclusions), Q3.5 (main journey).

Ask in 1-2 batches. After each batch:
- If everything is "must-have" → **BLOCKING**: apply MoSCoW prioritization question (see POST-CHECK below)
- If no exclusions → probe: "What should this system explicitly NOT do?"
- If journey is too simple → detail: "What happens when something goes wrong? When someone cancels?"

> **BLOCKING RULE — MoSCoW DISTRIBUTION:**
> If the client classifies ALL features as "must-have", you MUST challenge this BEFORE proceeding.
> Ask via AskUserQuestion:
> ```
> question: "{language == 'fr'
>   ? 'Toutes les fonctionnalités sont marquées indispensables. Si vous ne pouviez livrer que 60% du périmètre en v1, lesquelles pourraient attendre la v2 ?'
>   : 'All features are marked must-have. If you could only deliver 60% of scope in v1, which ones could wait for v2?'}"
> header: "Priorisation"
> multiSelect: true
> options:
>   - label: "{feature_1}"
>     description: "{language == 'fr' ? 'Pourrait passer en Important (v1.x)' : 'Could move to Important (v1.x)'}"
>   - label: "{feature_2}"
>     description: "{language == 'fr' ? 'Pourrait passer en Optionnel (v2)' : 'Could move to Optional (v2)'}"
>   - label: "{feature_3}"
>     description: "{language == 'fr' ? 'Pourrait passer en Important (v1.x)' : 'Could move to Important (v1.x)'}"
>   - label: "{language == 'fr' ? 'Tout est vraiment indispensable' : 'Everything is truly must-have'}"
>     description: "{language == 'fr' ? 'Je confirme que toutes les fonctionnalités sont critiques pour la v1' : 'I confirm all features are critical for v1'}"
> ```
> If client moves items → update categories. If client confirms ALL mustHave → accept but log in changelog.

#### 4d. Challenge Implicit Assumptions (CRITICAL)

> **Apply elicitation techniques to challenge what the client considers "obvious".**
> This is what separates a deep analysis from a shallow one.

For EACH specific point from the brief, prepare a targeted challenge question.

**Rules for challenge questions:**
1. Identify the assumption (what the client stated as fact)
2. Formulate a "what if the opposite?" question
3. Use Technique 4 (absence test) or Technique 7 (contradiction test)

**Examples by domain pattern:**

| Brief statement | Implicit assumption | Challenge question |
|----------------|--------------------|--------------------|
| "Entities are 1:1 extensions of X" | Cardinality is always 1:1 | "Can a user be linked to multiple employee records (temp contracts, part-time multi-position)? Can an employee NOT have a user account?" |
| "Entry split into activity and absence" | Binary decomposition is sufficient | "What granularity? Day, half-day, hour? Are activities linked to projects or clients? Are there other entry types (training, travel, on-call)?" |
| "A reports section" | Reports are a simple addition | "Which reports exactly? For whom? How often? PDF/Excel export? Real-time dashboards? Aggregated or detailed?" |
| "Module X manages Y" | The scope of "manages" is clear | "What does 'manage' mean concretely? Create, read, update, delete? Approve? Archive? Import/export?" |

Use these techniques:
- **Technique 3** (concrete scenario): "Walk me through a typical day of [role] using this module"
- **Technique 4** (absence test): "If [feature] didn't exist, how would you handle it?"
- **Technique 8** (impact escalation): "With 50 records this works, but with 500? 5000? Does the process stay the same?"

Ask challenge questions via AskUserQuestion (1-2 batches of max 4).

#### 4d-bis. Entity Sourcing Pattern (MANDATORY for detected dependencies)

> **When the analysis detects a referenced entity/concept (e.g., "Projets" referenced by activities, "Clients" referenced by orders), ALWAYS analyze and recommend BEFORE asking the client.**
> This pattern detects potential new modules not mentioned in the original brief.
> **Reference:** Load [references/entity-architecture-decision.md](../references/entity-architecture-decision.md) for scoring grid, decision tree, and section patterns.

For EACH referenced entity/concept detected during phases 2-4 that is NOT already covered by an identified module:

##### PHASE 1 — ULTRATHINK: Silent Architecture Analysis (NO output to client)

> **The AI reasons about the entity BEFORE presenting options. This is internal thinking only.**

```
ULTRATHINK — Entity Architecture Analysis for {entity_name}:

1. DOMAIN COHERENCE (from decision tree in reference)
   - Application domain: {app_description}
   - Entity fit: CORE | SUPPORT | PERIPHERAL
   - Justification: {1 sentence — why this entity is/isn't core to the app}
   - Example: "Projets" in a time management app = CORE (without projects, time entries have no target)
   - Example: "Codes d'imputation" in a time management app = SUPPORT (useful for accounting, but not central)

2. ENTITY SCORING (5 criteria, 0-3 each — from scoring grid in reference)
   - Lifecycle:  {score}/3 — {brief justification}
   - Actors:     {score}/3 — {brief justification}
   - Relations:  {score}/3 — {brief justification}
   - Volume:     {score}/3 — {brief justification}
   - Autonomy:   {score}/3 — {brief justification}
   - TOTAL:      {total}/15 → {classification: config_list | in_app | light_module | full_module}

3. PRE-CLASSIFICATION CHECK (from entity patterns in reference)
   - Does {entity_name} match a known pattern? → {yes: which one | no: use scoring}
   - Override needed? → {yes: why | no}

4. RECOMMENDATION
   - Option: {config_list | in_app_section | new_module | external_system}
   - Confidence: HIGH | MEDIUM | LOW
   - Reasoning: {1-2 sentences}
   - Risk if wrong choice: {what goes wrong if user picks a different option}

5. IF recommendation = new_module → PRE-BUILD ARCHITECTURE
   - Module code: {PascalCase}
   - Section `list`: {main entity grid + create action + navigation to detail}
   - Detail page tabs: [{tab_name: content}] (accessible by clicking a row in list)
   - Additional sections: [{code: justification}] (ONLY functional zones: dashboard, approve, import, rapport...)
   - Dependencies: [{which modules reference/are referenced by this entity}]
   - Topological position: layer {N} (foundation if no dependencies)
```

##### PHASE 2 — Present Analysis & Recommendation to Client

**BEFORE the AskUserQuestion, display the analysis as markdown:**

```
### {language == "fr" ? "Analyse" : "Analysis"} : {entity_plural}

{language == "fr"
  ? "Les **{entity_plural}** sont référencés par {parent_module} ({relationship_description})."
  : "**{entity_plural}** are referenced by {parent_module} ({relationship_description})."}

{language == "fr" ? "**Mon analyse :**" : "**My analysis:**"}
- {language == "fr" ? "Cohérence domaine" : "Domain coherence"} : **{CORE|SUPPORT|PERIPHERAL}** — {justification}
- {language == "fr" ? "Score de complexité" : "Complexity score"} : **{score}/15** ({classification})
- {language == "fr" ? "Recommandation" : "Recommendation"} : **{recommended_option}** — {reasoning}
```

**IF recommendation = new_module AND confidence >= MEDIUM, ALSO display:**

```
{language == "fr" ? "**Architecture proposée :**" : "**Proposed architecture:**"}

| {language == "fr" ? "Niveau" : "Level"} | {language == "fr" ? "Valeur" : "Value"} | {language == "fr" ? "Justification" : "Rationale"} |
|--------|--------|---------------|
| Context | `business` | {language == "fr" ? "Contexte métier standard" : "Standard business context"} |
| Application | `{app_code}` | {app_name} |
| Module | `{ModuleCode}` | {language == "fr" ? "{pourquoi ce découpage}" : "{why this decomposition}"} |

| Section | {language == "fr" ? "Justification" : "Rationale"} | Resources |
|---------|---------------|-----------|
| `list` | {language == "fr" ? "Page principale : grille, création, navigation vers détail" : "Main page: grid, create action, navigate to detail"} | {entity}-grid, {entity}-filters, {entity}-form |
| {additional_section} | {justification} | {resources} |

{language == "fr"
  ? "**Page détail** (onglets accessibles depuis la liste) :"
  : "**Detail page** (tabs accessible from list):"}

| {language == "fr" ? "Onglet" : "Tab"} | {language == "fr" ? "Contenu" : "Content"} |
|--------|---------|
| {language == "fr" ? "Informations" : "Information"} | {language == "fr" ? "Fiche principale" : "Main record"} |
| {tab_name} | {tab_content} |

{language == "fr"
  ? "**Impact :** {ModuleName} deviendra une dépendance de {parent_module} (couche {N} du graphe)."
  : "**Impact:** {ModuleName} will become a dependency of {parent_module} (layer {N} in the graph)."}
```

##### PHASE 3 — Ask with Recommended Option First

**Order the options with the recommendation FIRST, marked "(Recommandé)" / "(Recommended)":**

```
question: "{language == 'fr'
  ? 'Comment souhaitez-vous gérer les {entity_plural} ?'
  : 'How do you want to manage {entity_plural}?'}"
header: "{entity_name}"
options:
  (ORDER: recommended option FIRST, then the 3 remaining options in logical order)

  IF recommendation = new_module:
  - label: "{language == 'fr' ? 'Nouveau module dédié (Recommandé)' : 'New dedicated module (Recommended)'}"
    description: "{language == 'fr'
      ? 'Module {ModuleCode} avec page liste, détail par onglets, permissions dédiées'
      : '{ModuleCode} module with list page, tabbed detail, dedicated permissions'}"
  - label: "{language == 'fr' ? 'Géré dans l\'app' : 'Managed in app'}"
    description: "..."
  - label: "{language == 'fr' ? 'Système externe' : 'External system'}"
    description: "..."
  - label: "{language == 'fr' ? 'Liste simple en config' : 'Simple config list'}"
    description: "..."

  IF recommendation = config_list:
  - label: "{language == 'fr' ? 'Liste simple en config (Recommandé)' : 'Simple config list (Recommended)'}"
    description: "{language == 'fr'
      ? 'Table de référence administrable, pas de module dédié'
      : 'Admin-managed reference table, no dedicated module'}"
  - label: "{language == 'fr' ? 'Géré dans l\'app' : 'Managed in app'}"
    description: "..."
  - label: "{language == 'fr' ? 'Nouveau module dédié' : 'New dedicated module'}"
    description: "..."
  - label: "{language == 'fr' ? 'Système externe' : 'External system'}"
    description: "..."

  IF recommendation = in_app_section:
  - label: "{language == 'fr' ? 'Géré dans l\'app (Recommandé)' : 'Managed in app (Recommended)'}"
    description: "{language == 'fr'
      ? 'Accessible via un onglet dans la page détail de {parent_module}'
      : 'Accessible via a tab in {parent_module} detail page'}"
  - label: "{language == 'fr' ? 'Nouveau module dédié' : 'New dedicated module'}"
    description: "..."
  - label: "{language == 'fr' ? 'Liste simple en config' : 'Simple config list'}"
    description: "..."
  - label: "{language == 'fr' ? 'Système externe' : 'External system'}"
    description: "..."

  IF recommendation = external_system:
  - label: "{language == 'fr' ? 'Système externe (Recommandé)' : 'External system (Recommended)'}"
    description: "{language == 'fr'
      ? 'Les {entity_plural} viennent d\'un autre système (import ou API)'
      : '{entity_plural} come from another system (import or API)'}"
  - label: "{language == 'fr' ? 'Nouveau module dédié' : 'New dedicated module'}"
    description: "..."
  - label: "{language == 'fr' ? 'Géré dans l\'app' : 'Managed in app'}"
    description: "..."
  - label: "{language == 'fr' ? 'Liste simple en config' : 'Simple config list'}"
    description: "..."

  IF confidence = LOW (no clear recommendation):
  (all 4 options in neutral order, NO "(Recommandé)" tag)
```

##### PHASE 4 — Process Answer

| Choice | Action |
|--------|--------|
| **Géré dans l'app** | Entity becomes a sub-entity of the parent module. Add as a **tab in the detail page** of the referencing module. Note in coverageMatrix with `parentModule` field. |
| **Nouveau module dédié** | **Add new module to `{pre_analysis}.detected_modules[]`** with the proposed architecture (sections, detail tabs, dependencies). Add to `coverageMatrix` as mustHave. The `list` section is ALWAYS the main section. Additional sections ONLY for distinct functional zones (dashboard, approve, import...). `create` and `edit` are ACTIONS within `list` and detail pages, NEVER standalone sections. |
| **Système externe** | Flag for integration specification. Add to `coverageMatrix` as integration. Load `questionnaire/05-integrations.md` if not already loaded. |
| **Liste simple en config** | Entity becomes a lookup/reference table (no dedicated module, no section). Note in coverageMatrix as config data. |

> **CRITICAL:** The intelligence of this step is in the ULTRATHINK analysis. The AI must REASON about domain coherence, score the entity, and recommend — not just present 4 neutral options. The client can always override the recommendation, but they should benefit from expert architectural guidance.

#### 4e. Risks & Success Criteria (ALWAYS — from `questionnaire/14-risk-assumptions.md` and `questionnaire/15-success-metrics.md`)

Select the most pertinent questions:
- **14-risk-assumptions.md:** Q14.1 (identified risks), Q14.4 (unvalidated assumptions)
- **15-success-metrics.md:** Q15.1 (success definition), Q15.4 (measurable objectives)

Ask in 1 batch via AskUserQuestion.

#### 4f. Conditional Deep-Dives

Based on brief analysis, load additional categories if relevant:

| Condition | Category | Questionnaire |
|-----------|----------|---------------|
| Security or compliance mentioned | 06 | `questionnaire/06-security.md` |
| External system integration | 05 | `questionnaire/05-integrations.md` |
| Performance requirements | 08 | `questionnaire/08-performance.md` |
| Technical constraints | 09 | `questionnaire/09-constraints.md` |
| Documentation needs | 10 | `questionnaire/10-documentation.md` |

> **Categories 04 (data), 07 (UI), 11 (lifecycle), 12 (migration), 13 (cross-module) are per-module and loaded in step-03.**

---

## PHASE 4: ANTICIPATION (Suggest Unexpressed Needs)

### 5. Proactive Suggestions

> **An expert analyst doesn't just capture what is said.**
> They anticipate what the client hasn't thought to ask for.

**Process:**

1. Load: `patterns/suggestion-catalog.md`
2. Match suggestion patterns against the project context (domain, modules, features)
3. Add implicit needs for this type of system that weren't mentioned

4. **Display as markdown** (direct text, NOT inside AskUserQuestion):

```
## {language == "fr" ? "Besoins complémentaires que je vous suggère" : "Complementary needs I suggest"}

{language == "fr"
  ? "D'après mon analyse de votre besoin, voici des aspects que vous n'avez peut-être pas mentionnés mais qui sont souvent nécessaires pour ce type d'application :"
  : "Based on my analysis of your need, here are aspects you may not have mentioned but that are often necessary for this type of application:"}

| # | Suggestion | Justification | Module concerné |
|---|-----------|---------------|-----------------|
| 1 | {suggestion} | {why it's relevant for THIS project} | {module} |
| 2 | {suggestion} | {why} | {module} |
| 3 | {suggestion} | {why} | {module} |
| ... | ... | ... | ... |
```

5. Then ask via AskUserQuestion (multiSelect: true):
```
question: "{language == 'fr' ? 'Quelles suggestions souhaitez-vous inclure dans le périmètre ?' : 'Which suggestions would you like to include in scope?'}"
header: "Suggestions"
multiSelect: true
options:
  - label: "{suggestion 1 short name}"
    description: "{justification in 1 sentence}"
  - label: "{suggestion 2 short name}"
    description: "{justification in 1 sentence}"
  - label: "{suggestion 3 short name}"
    description: "{justification in 1 sentence}"
  - label: "{language == 'fr' ? 'Aucune' : 'None'}"
    description: "{language == 'fr' ? 'Je n\'ai pas besoin de ces suggestions' : 'I don\'t need any of these suggestions'}"
```

6. Accepted suggestions enrich `coverageMatrix` and `globalScope`.

---

## PHASE 5: PERIMETRE (Bound Scope)

### 6. Application Roles Definition

> **Define roles at the APPLICATION level, not per-module.**

Propose the standard 4-tier roles:

```
Application Roles for {application_name}:

| Role | Level | Default Permissions |
|------|-------|-------------------|
| {App} Admin | admin | business.{app}.* (wildcard) |
| {App} Manager | manager | read, create, update, assign |
| {App} Contributor | contributor | read, create, update |
| {App} Viewer | viewer | read only |
```

Ask via AskUserQuestion:
```
question: "{language == 'fr' ? 'Ces 4 rôles conviennent-ils pour votre application ?' : 'Do these 4 roles suit your application?'}"
header: "Rôles"
options:
  - label: "{language == 'fr' ? 'Oui, parfait' : 'Yes, perfect'}"
    description: "{language == 'fr' ? 'Utiliser les 4 rôles standards tels quels' : 'Use the 4 standard roles as-is'}"
  - label: "{language == 'fr' ? 'Renommer' : 'Rename'}"
    description: "{language == 'fr' ? 'Garder 4 niveaux mais personnaliser les noms' : 'Keep 4 levels but customize names'}"
  - label: "{language == 'fr' ? 'Personnaliser' : 'Customize'}"
    description: "{language == 'fr' ? 'Modifier le nombre ou les permissions des rôles' : 'Modify number or permissions of roles'}"
```

IF single-module mode:
  Same role definition but inferred from stakeholders

### 6b. Table Prefix Definition (MANDATORY)

> **Every business application MUST define a table prefix.**
> This prefix identifies which application a database table belongs to (e.g., `rh_Employees`, `fi_Invoices`).

**Process:**

1. Derive a suggested prefix from the application name:
   - Use the most recognizable abbreviation (2-5 lowercase letters + `_`)
   - Examples: HumanResources → `rh_`, SalesManagement → `sales_`, Finance → `fi_`, CRM → `crm_`

2. **Display as markdown** (direct text output):

```
{language == "fr"
  ? "### Préfixe de table\n\nToutes les tables de cette application en base de données porteront un préfixe pour identifier leur appartenance.\n\nPréfixe suggéré : **`{suggested_prefix}`**\n\nExemple : `{suggested_prefix}Employees`, `{suggested_prefix}Contracts`"
  : "### Table Prefix\n\nAll database tables for this application will carry a prefix to identify their ownership.\n\nSuggested prefix: **`{suggested_prefix}`**\n\nExample: `{suggested_prefix}Employees`, `{suggested_prefix}Contracts`"}
```

3. Ask via AskUserQuestion:
```
question: "{language == 'fr' ? 'Ce préfixe de table vous convient-il ?' : 'Does this table prefix work for you?'}"
header: "Préfixe"
options:
  - label: "{language == 'fr' ? 'Oui, parfait' : 'Yes, perfect'}"
    description: "{language == 'fr' ? 'Utiliser le préfixe suggéré' : 'Use the suggested prefix'}"
  - label: "{language == 'fr' ? 'Personnaliser' : 'Customize'}"
    description: "{language == 'fr' ? 'Choisir un autre préfixe (2-5 lettres minuscules + _)' : 'Choose a different prefix (2-5 lowercase letters + _)'}"
```

4. IF "Customize" → ask for custom prefix via AskUserQuestion (open-ended "Other" option)

5. **Validate the prefix:**
   - Format: `^[a-z]{2,5}_$` (2-5 lowercase letters followed by underscore)
   - Must NOT collide with platform prefixes: `auth_`, `nav_`, `usr_`, `ai_`, `cfg_`, `wkf_`, `support_`, `entra_`, `ref_`, `loc_`, `lic_`, `tenant_`
   - If collision detected → ask the user to choose another prefix

6. Store in `metadata.tablePrefix`

### 7. Coverage Matrix with Sections & Resources (MANDATORY)

> **ENRICHMENT: The coverage matrix now includes anticipated sections (Level 4) and resources (Level 5).**
> This gives downstream steps (step-02, step-03) a concrete starting point.

BEFORE transitioning to step-02:

1. Re-read the original prompt/brief in its entirety
2. Re-read ALL answers collected during phases 2-4
3. For EACH distinct feature/requirement identified:
   a. Create an entry in `cadrage.coverageMatrix[]`
   b. Assign it to mustHave, shouldHave, couldHave, or outOfScope
   c. Assign the module that will cover it (or null if cross-cutting)
   d. **List anticipated sections** (Level 4) — ONLY functional zones (see `references/entity-architecture-decision.md` section 4)
   e. **List anticipated resources** (Level 5) for each section
   f. **List detail page tabs** — for entities accessible via click from `list`

> **SECTION RULE:** Sections are functional zones (list, dashboard, approve, import, rapport...).
> `create` and `edit` are SEPARATE PAGES with their own URL routes (`/create` and `/:id/edit`).
> `detail` is a page with tabs accessible by clicking a row in `list`, NOT a standalone section.

4. **OUTPUT the matrix as text** (do NOT put it inside AskUserQuestion — it won't render):

Print a markdown table with columns: **Fonctionnalité | Priorité | Module | Section | Resources clés | Onglets détail**

Example:
```
{language == "fr"
  ? "Voici la matrice de couverture enrichie. J'ai identifié {N} fonctionnalités :"
  : "Here is the enriched coverage matrix. I identified {N} features:"}

| Fonctionnalité | Priorité | Module | Section | Resources clés | Onglets détail |
|---|---|---|---|---|---|
| Gestion des employés | mustHave | Employees | list | employee-grid, employee-filters, employee-form | Infos, Contrats, Documents |
| Suivi des activités | mustHave | TimeTracking | list | activity-grid, activity-filters, activity-form | Infos, Imputations |
| Saisie d'absences | mustHave | TimeTracking | list | absence-grid, absence-form, absence-calendar | Infos, Justificatifs |
| Rapports temps | shouldHave | TimeTracking | dashboard | time-kpi-cards, time-summary-chart | — |
| Validation absences | shouldHave | TimeTracking | approve | approval-queue, status-timeline | — |
| Export PDF/Excel | couldHave | TimeTracking | rapport | export-panel | — |
| Intégration paie | outOfScope | — | — | — | — |
```

5. **THEN** (after the table is displayed) ask via AskUserQuestion:
```
question: "{language == 'fr' ? 'Cette matrice de couverture vous convient-elle ?' : 'Does this coverage matrix suit you?'}"
header: "Couverture"
options:
  - label: "{language == 'fr' ? 'Oui, parfait' : 'Yes, perfect'}"
    description: "{language == 'fr' ? 'La classification et les sections sont correctes' : 'Classification and sections are correct'}"
  - label: "{language == 'fr' ? 'Ajouter des éléments' : 'Add items'}"
    description: "{language == 'fr' ? 'Il manque des fonctionnalités ou des sections' : 'Missing features or sections'}"
  - label: "{language == 'fr' ? 'Réajuster' : 'Readjust'}"
    description: "{language == 'fr' ? 'Modifier les priorités, modules ou sections' : 'Change priorities, modules, or sections'}"
```

6. Iterate until the client confirms.

**VALIDATION:**
- Every line of the original prompt must map to at least one coverageMatrix entry.
- If a feature is in mustHave → it MUST have at least one anticipated section.
- Accepted suggestions from Phase 4 must appear in the matrix.

**POST-CHECK — PRIORITY DISTRIBUTION (BLOCKING):**

```
coverageItems = cadrage.coverageMatrix[]
mustHaveCount = coverageItems.filter(i => i.category === "mustHave").length
shouldHaveCount = coverageItems.filter(i => i.category === "shouldHave").length
couldHaveCount = coverageItems.filter(i => i.category === "couldHave").length
outOfScopeCount = coverageItems.filter(i => i.category === "outOfScope").length

IF shouldHaveCount === 0 AND couldHaveCount === 0 AND outOfScopeCount === 0:
  → FAIL: ALL {mustHaveCount} items are mustHave — no distribution.
  → ACTION: Return to Phase 3 section 4c and apply MoSCoW question.
  → DO NOT write cadrage until at least shouldHave OR outOfScope has ≥ 1 item.
  → EXCEPTION: If client explicitly confirmed "tout est indispensable" during
    Phase 3 section 4c, accept but ADD a changelog entry:
    "Client confirmed all {N} features as mustHave after MoSCoW challenge"
```

**POST-CHECK — CROSS-CUTTING COVERAGE (WARNING):**

```
FOR each item in coverageMatrix WHERE item.module === null:
  IF item.category === "mustHave":
    → WARNING: "{item.item}" is mustHave but has no assigned module.
    → Ensure it is covered by infrastructure or a cross-cutting concern.
    → Add a note explaining HOW it will be implemented (e.g., "handled by platform notification service").
  IF item.anticipatedSections.length === 0 AND item.category !== "outOfScope":
    → WARNING: "{item.item}" has no anticipated sections — will it be implemented?
```

---

## WRITE & SUMMARY

### 8. Write Cadrage to Feature.json

Use ba-writer to enrich master feature.json. **Follow the STRUCTURE CARDS exactly.**

See [references/cadrage-structure-cards.md](../references/cadrage-structure-cards.md) for exact JSON formats of: `stakeholders[]`, `applicationRoles[]`, `risks[]`, `acceptanceCriteria[]`, `coverageMatrix[]`, `codebaseContext`.

```
ba-writer.enrichSection({
  featureId: {feature_id},
  section: "metadata",
  data: {
    tablePrefix: "{from Phase 5, section 6b — validated prefix, e.g., rh_}"
  }
})

ba-writer.enrichSection({
  featureId: {feature_id},
  section: "cadrage",
  data: {
    problem: {from Phase 3, section 4a — Q1.1 answer or refined problem},
    asIs: {from Phase 3, section 4a — Q1.4 answer},
    toBe: {from Phase 3, section 4a — Q1.8 answer},
    trigger: {from Phase 3, section 4a — Q1.11 answer},
    stakeholders: [{from Phase 3, section 4b — use STRUCTURE CARD format}],
    globalScope: {
      mustHave: [{from Phase 3, section 4c + Phase 4 accepted suggestions}],
      shouldHave: [{from coverage matrix}],
      couldHave: [{from coverage matrix}],
      outOfScope: [{from Phase 3, section 4c — Q3.4 exclusions}]
    },
    applicationRoles: [{from Phase 5, section 6 — use STRUCTURE CARD format}],
    risks: [{from Phase 3, section 4e — use STRUCTURE CARD format}],
    acceptanceCriteria: [{from Phase 3, section 4e — use STRUCTURE CARD format}],
    coverageMatrix: [{from Phase 5, section 7 — use STRUCTURE CARD format with anticipatedSections and anticipatedResources}],
    codebaseContext: "{string summary of codebase findings}"
  }
})

ba-writer.updateStatus({feature_id}, "framed")
```

### 9. Multi-Application Detection (NEW)

> **Analyze whether the project spans multiple independent applications.**

After coverage matrix is validated, check if the identified functional domains suggest multiple applications:

**Detection triggers (ANY of these = suggest multi-app):**
- Coverage matrix entries reference different navigation contexts (business + personal + platform)
- User mentioned "multiple applications", "several apps", "cross-platform"
- Functional domains form clearly independent applications with separate user bases
- Stakeholders only interact with specific domains (not shared across all)

**IF detection triggers matched:**

Display analysis as markdown:
```
{language == "fr"
  ? "### Analyse multi-application\n\nD'après mon analyse, ce projet couvre plusieurs domaines fonctionnels qui pourraient former des applications indépendantes :\n\n"
  : "### Multi-Application Analysis\n\nBased on my analysis, this project spans multiple functional domains that could form independent applications:\n\n"}

| Domain | Suggested Context | Suggested Application | Key Modules |
|--------|-------------------|----------------------|-------------|
{for each identified domain: domain name | business/platform/personal | PascalCase name | top modules}
```

Ask via AskUserQuestion:
```
question: "{language == 'fr' ? 'Ce projet constitue-t-il une seule application ou plusieurs applications distinctes ?' : 'Is this a single application or multiple independent applications?'}"
header: "Architecture"
options:
  - label: "{language == 'fr' ? 'Application unique' : 'Single application'}"
    description: "{language == 'fr' ? 'Tous les domaines forment une seule application avec plusieurs modules' : 'All domains form one application with multiple modules'}"
  - label: "{language == 'fr' ? 'Applications multiples' : 'Multiple applications'}"
    description: "{language == 'fr' ? 'Chaque domaine est une application indépendante (navigation, rôles et préfixe de table séparés)' : 'Each domain is an independent application (separate navigation, roles, and table prefix)'}"
```

**IF "Multiple applications":**
1. Create project-level feature.json:
```
ba-writer.createProjectFeature({
  metadata: {
    projectName: {project_name derived from feature_description},
    language: {language},
    featureDescription: {feature_description}
  },
  cadrage: {cadrage data already collected in this step}
})
```
2. Set `workflow.mode = "project"` in project feature.json
3. Load `questionnaire/00b-project.md` for additional project-level questions
4. Load `steps/step-01b-applications.md` for application decomposition
5. **STOP — DO NOT load step-02**

**IF "Single application":**
→ Continue to step 10 (display summary) and step-02 as usual.

**IF no detection triggers matched:**
→ Skip this section entirely — continue to step 10 (display summary).

### 10. Display Summary

```
## Cadrage Complete - {feature_id}

| Aspect | Count |
|--------|-------|
| Stakeholders | {count} |
| Must-have scope items | {count} |
| Application roles | {count} |
| Risks identified | {count} |
| Suggestions accepted | {count} |
| Anticipated sections | {total across all modules} |

### Application Roles
{table of roles with permission levels}

### Coverage Highlights
{top 3-5 must-have items with their anticipated sections}

### Next Step
→ Module decomposition (step-02-decomposition.md)
```

---

## NEXT STEP

**IF workflow.mode === "project":** Load: `./step-01b-applications.md`
**ELSE:** Load: `./step-02-decomposition.md`
