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

> **Context files:** `_shared.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 `_shared.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 index.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

## CONTEXT RECOVERY

Re-read session variables from `.business-analyse/config.json` (do NOT rely on LLM memory):
```javascript
const config = readJSON('.business-analyse/config.json').currentFeature;
const { id: feature_id, docsDir: docs_dir, application: application_name,
        applicationCode, workflowMode: workflow_mode, language, version } = config;
```

## 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: ÉCOUTE           → 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: PÉRIMÈTRE         → Bound scope with roles, coverage matrix (sections + resources)
```

---

## PHASE 1: ÉCOUTE (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-structure.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 + Docs Agents**
```
Launch 4 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/**/*.tsx)
  Agent 4: Scan existing BA documentation (Glob: docs/**/business-analyse/**/index.json)
           → For each found file: read metadata.application, metadata.module, status, modules[].code
           → Also scan: docs/**/*.md (ERD, guides, specs)

Merge findings into {codebase_context}
```

**Phase 2c: Existing Documentation Context**

> **Load existing BAs and documentation BEFORE engaging the client.**
> This prevents re-specifying what already exists and surfaces integration constraints early.

```
IF Agent 4 found existing index.json files:
  For each file found:
    → Extract: application, modules[], entities[], status, version
    → Store as {existing_ba_context}: list of existing applications with their modules and key entities
  Display (silent — internal context only, not shown to client):
    "Found {count} existing BA(s): {app names} — {total modules} modules already specified"

IF docs/**/*.md files found:
  → Scan for ERD diagrams, API specs, architecture decisions
  → Store relevant findings in {codebase_context}
```

**Use in pre-analysis:**
- Cross-reference detected modules against `{existing_ba_context}` — flag modules that already exist
- Pre-identify integration points: new feature may depend on or extend existing modules
- NEVER re-specify what's already handed-off (status = "handed-off") — reference it instead

### 2d. Domain Research (WebSearch — BEFORE engaging the client)

> **Ground the analysis in real-world patterns. This prevents greenfield mistakes
> (e.g., putting firstName on Employee instead of linking to User).**
> This step takes 30-60 seconds and dramatically improves entity design quality.

**WHEN to search:** ALWAYS for the main business domain. Skip only if the domain is purely SmartStack-internal (e.g., config, admin tools).

**HOW to search:** Use WebSearch tool with targeted queries based on the detected domain.

```
1. DOMAIN MODEL SEARCH
   Query: "{detected_domain} data model best practices" (e.g., "HR management data model best practices")
   → Extract: standard entities, common relationships, industry patterns
   → Store key findings in {domain_research}.dataModel

2. ENTITY PATTERN SEARCH (for the 2-3 most complex detected entities)
   Query: "{entity_name} entity design pattern ERP" (e.g., "employee entity design pattern ERP")
   → Extract: standard attributes, versioning patterns, common pitfalls
   → Store in {domain_research}.entityPatterns[entity_name]

3. WORKFLOW SEARCH (if the domain involves approval/validation flows)
   Query: "{domain} approval workflow pattern" (e.g., "timesheet approval workflow pattern")
   → Extract: standard states, transition rules, multi-level approval
   → Store in {domain_research}.workflows
```

**WHAT to extract (ULTRATHINK — internal only):**
```yaml
domain_research:
  domain: "{detected domain — e.g., HR, CRM, Billing}"
  dataModel:
    standardEntities: ["Entity1", "Entity2"]     # what the industry considers standard
    commonRelationships: ["Entity1 → Entity2"]   # typical FK patterns
    antiPatterns: ["storing salary directly on employee"]  # mistakes to avoid
  entityPatterns:
    Employee:
      standardAttributes: ["code", "userId", "departmentId", "hireDate", "status"]
      versionedData: ["salary → separate table with effectiveDate"]
      personPattern: "link to User via FK, never duplicate personal info"
    Invoice:
      standardAttributes: ["number", "clientId", "issueDate", "dueDate", "status"]
      calculatedFields: ["subtotal", "taxAmount", "total"]
      workflowStates: ["Draft", "Sent", "Paid", "Overdue", "Cancelled"]
  workflows:
    timesheetApproval: "Draft → Submitted → ManagerApproved → ClientApproved"
    invoiceLifecycle: "Draft → Validated → Sent → Paid"
```

> **CRITICAL:** This research is INTERNAL context. Do NOT show raw search results to the client.
> Use the findings to:
> - Improve pre-analysis quality (detect shadow zones the client won't mention)
> - Ground entity architecture decisions in Phase 4d-bis
> - Inform proactive suggestions in Phase 4 (ANTICIPATION)
> - Prevent common anti-patterns during step-03 entity specification

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

> **The AI prepares the conversation before speaking. This is NOT output — it's internal reasoning.**
> **INCLUDES domain research findings from 2d above.**

Analyze `{feature_description}` AND `{domain_research}` 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}` — Write pre_analysis to cadrage.json as a `_preAnalysis` field (transient — removed on cadrage completion). This ensures the data survives context compaction:
```yaml
_preAnalysis:
  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}]
  domain_research:                          # from Phase 2d web search
    domain: "{detected domain}"
    standardEntities: [...]
    antiPatterns: [...]
    entityPatterns: {entity: {standardAttributes, versionedData, personPattern}}
    workflows: {name: "state1 → state2 → state3"}
```

---

## 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 `_shared.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.
> The questionnaire contains 3 targeted questions: Q1.1 (business process), Q1.4 (friction points), Q1.8 (vision).

Ask all 3 questions in 1 batch via AskUserQuestion.

Apply ULTRATHINK after the 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-scope.md`)

> The questionnaire contains 10 targeted questions covering profiles, tasks, access levels, scope, and user journey.

**Mandatory minimum:** Q2.1 (users), Q2.5 (tasks per profile), Q2.9-Q2.11 (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 "no restrictions" → probe: "Are there sensitive data (salary, contracts, personal info) that should be restricted to specific roles?"
- If tasks are generic → ask for a concrete scenario: "Walk me through a typical day"

#### 4b-bis. Détection Portail Client (ULTRATHINK — après batch stakeholders)

Analyser les réponses stakeholders pour signaux d'utilisateurs externes :

```
EXTERNAL_SIGNALS = ["client", "customer", "fournisseur", "supplier", "partenaire",
  "partner", "portail", "portal", "externe", "external", "tiers", "third-party",
  "organisation cliente"]
```

SI un profil stakeholder match EXTERNAL_SIGNALS :
  → Stocker dans `{pre_analysis}`: `_portalDetected: true`
  → Poser la question via AskUserQuestion :

```
question: "{language == 'fr'
  ? 'J\'ai détecté des utilisateurs externes ({profiles}). Votre application comportera-t-elle un portail client en plus de la partie interne ?'
  : 'I detected external users ({profiles}). Will your application include a client portal in addition to the internal part?'}"
header: "Portail client"
options:
  - label: "{language == 'fr' ? 'Oui, portail + interne' : 'Yes, portal + internal'}"
    description: "{language == 'fr' ? 'L\'application servira des utilisateurs internes ET externes via un portail dédié' : 'The app will serve internal AND external users via a dedicated portal'}"
  - label: "{language == 'fr' ? 'Non, interne uniquement' : 'No, internal only'}"
    description: "{language == 'fr' ? 'Seuls les employés internes utiliseront l\'application' : 'Only internal employees will use the application'}"
  - label: "{language == 'fr' ? 'Non, portail uniquement' : 'No, portal only'}"
    description: "{language == 'fr' ? 'L\'application est exclusivement destinée aux utilisateurs externes' : 'The application is exclusively for external users'}"
```

| Réponse | Action |
|---------|--------|
| **Oui, portail + interne** | `_portalMode = "dual"` → Follow-up : classifier chaque stakeholder comme `audience: "internal" \| "external" \| "shared"` |
| **Portail uniquement** | `_portalMode = "portal-only"` |
| **Interne uniquement** | `_portalMode = "internal-only"` (défaut, pas d'action supplémentaire) |

> **Note SmartStack :** Le déploiement multi-tenant est géré automatiquement par SmartStack. La partie interne et la partie portail seront déployées sur des tenants séparés.

SI aucun profil ne match EXTERNAL_SIGNALS → `_portalMode = "internal-only"` (défaut silencieux, rien à demander).

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

**Mandatory minimum:** Q2.13 (in-scope), Q2.15 (exclusions), Q2.16 (main journey).

Ask in 1-2 batches. After each batch:
- 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?"

> **MANDATORY Error Path Challenge (run for EVERY project after the main journey is described):**
>
> Ask via AskUserQuestion (1 batch, 2-3 questions):
> - "Si l'action principale échoue (erreur serveur, données invalides, timeout), que doit-il se passer ?"
> - "Qui est notifié en cas d'erreur ? L'utilisateur ? Un administrateur ? Via quel canal ?"
> - "L'état doit-il être annulé (rollback) ou conservé partiellement ?"
>
> Record answers in `cadrage.errorFlows[]`:
> ```json
> { "scenario": "...", "trigger": "...", "notification": "...", "recovery": "rollback|partial|manual" }
> ```
>
> These error flows become **Business Rules** in step-03 (BR-WF category: workflow/guard conditions).

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

> **Load reference material from `_shared.md` for domain-specific patterns and elicitation techniques.**

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:
1. Identify the assumption (what the client stated as fact)
2. Formulate a "what if the opposite?" question
3. Use techniques from the reference (Scenario, Absence Test, Impact Escalation)

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 sections: 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"} |
|--------|--------|---------------|
| 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 inScope. The `list` section is ALWAYS the main section. Additional sections ONLY for distinct functional sections (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 materials on integrations if not already covered. |
| **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. Conditional Deep-Dives

Based on brief analysis, load additional materials if relevant:

| Condition | Questionnaire |
|-----------|---------------|
| Security or compliance mentioned | `questionnaire/03-data-ui.md` (security section) |
| External system integration | `questionnaire/05-cross-module.md` (integration section) |
| Performance requirements | Additional probing on non-functional needs |
| Technical constraints | Additional probing on platform constraints |

---

## 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 pattern guidance from `_shared.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 | {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'}"
```

### 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:
   - Create an entry in `cadrage.coverageMatrix[]`
   - Assign it to inScope or outOfScope
   - Assign the module that will cover it (or null if cross-cutting)
   - List anticipated sections (Level 4) — ONLY functional sections
   - List anticipated resources (Level 5) for each section
   - List detail page tabs — for entities accessible via click from `list`

   **SI `_portalMode === "dual"` :**
   - Chaque entrée `coverageMatrix` reçoit `audience: "internal" | "external" | "shared"`
   - Règles de dérivation :
     - Items mentionnés uniquement par stakeholders internes → `"internal"`
     - Items mentionnés uniquement par stakeholders externes → `"external"`
     - Items mentionnés par les deux ou cross-cutting → `"shared"`
   - Afficher colonne "Audience" dans le tableau de la matrice

4. **RECONCILIATION CHECK (MANDATORY — BLOCKING):**

   > **Every explicitly requested item MUST appear in the coverage matrix.**
   > This check prevents silent omissions — if the user asked for 5 modules, all 5 must be tracked.

   ```
   // Extract all explicit requests from the original prompt
   requestedItems = extract_explicit_items({feature_description})
   // Include: modules mentioned by name, features listed, applications named

   // Verify each requested item has a coverage matrix entry
   uncoveredItems = requestedItems.filter(item =>
     !coverageMatrix.some(entry => fuzzyMatch(entry.feature, item))
   )

   IF uncoveredItems.length > 0:
     BLOCKING: "The following requested items have no coverage matrix entry:
       {uncoveredItems.map(i => '- ' + i).join('\n')}
     Add them to the coverage matrix before proceeding."

   ELSE:
     Display: "✓ Coverage reconciliation: all {requestedItems.length} requested items mapped"
   ```

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

6. **THEN** (after the table is displayed) ask via AskUserQuestion for confirmation

7. Iterate until the client confirms

---

## WRITE & SUMMARY

### 8. Write Cadrage to Feature.json

Use ba-writer with granular JSON approach. Write to `cadrage.json` section:

```
ba-writer.enrichSection({
  featureId: {feature_id},
  section: "cadrage",
  subsection: "cadrage.json",
  data: {
    metadata: {
      tablePrefix: "{from Phase 5, section 6b — validated prefix, e.g., rh_}",
      portalMode: "{_portalMode || 'internal-only'}"
    },
    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},
    stakeholders: [{from Phase 3, section 4b — each with audience: "internal"|"external"|"shared" if portalMode is "dual"}],
    globalScope: {
      inScope: [{from Phase 3, section 4c + Phase 4 accepted suggestions + coverage matrix}],
      outOfScope: [{from Phase 3, section 4c — Q2.15 exclusions}]
    },
    applicationRoles: [{from Phase 5, section 6}],
    errorFlows: [{from Phase 3, section 4c}],
    coverageMatrix: [{from Phase 5, section 7 — with anticipatedSections and anticipatedResources}],
    codebaseContext: "{string summary of codebase findings}"
  }
})

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

### 9. Display Summary

```
## Cadrage Complete - {feature_id}

| Aspect | Count |
|--------|-------|
| Stakeholders | {count} |
| In-scope items | {count} |
| Application roles | {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 structure analysis (step-02-structure.md)
```

---

## NEXT STEP

Load: `./step-02-structure.md`

> step-02 handles module structure analysis and entity/section definition.
