---
name: step-02-decomposition
description: Module decomposition - identify modules, dependency graph, topological sort, client checkpoint
model: sonnet
next_step: steps/step-03-specify.md
---

# Step 2: Decomposition

## MANDATORY EXECUTION RULES

- ALWAYS present the module structure to the client for validation (BLOCKING checkpoint)
- NEVER proceed to specification without client approval of module structure
- ALWAYS sort modules by dependency (foundations first)
- ALWAYS detect dependency cycles (ERROR if found)
- This step runs for BOTH application mode and single-module mode (trivial for single)

## YOUR TASK

Decompose the application scope into ordered modules. Identify dependencies between modules and determine the processing order for iterative specification.

---

## EXECUTION SEQUENCE

### 1. Read Cadrage Results

```
ba-reader.findFeature({feature_id})
→ Read cadrage.globalScope (mustHave, shouldHave, couldHave)
→ Read cadrage.stakeholders (roles, tasks, pain points)
→ Read cadrage.applicationRoles
→ Read cadrage.codebaseContext (existing modules found)
→ Read metadata.workflow.mode
```

IF status already "decomposed":
  Display: "Decomposition already completed. Loading next step."
  Load: steps/step-03-specify.md
  STOP

### 2. Module Identification

**From the scope items and stakeholder needs, identify distinct modules:**

For each mustHave/shouldHave scope item:
- Group related items into cohesive functional units
- Each module should be independently deployable
- Each module maps to a navigation entry at Level 3 (Module)

**ULTRATHINK Challenge:**
- "Is this one module or two? Could a user need only half of it?"
- "Are there hidden modules not mentioned in scope? (e.g., Notifications, Dashboard)"
- "Does the codebase already have modules that should be extended vs. created new?"

**For each module, determine:**

> **STRUCTURE CARD: modules[]** — Field names are EXACT. Include ALL fields below.
> ```json
> {
>   "code": "PascalCase",
>   "description": "1-2 sentence description",
>   "featureType": "data-centric|integration|ui-centric|workflow|reporting|full-module",
>   "dependencies": ["OtherModule"],
>   "dependents": ["DependentModule"],
>   "status": "pending",
>   "featureJsonPath": null,
>   "priority": "must|should|could",
>   "sortOrder": 0,
>   "entities": ["Anticipated entity names"],
>   "estimatedComplexity": "simple|medium|complex"
> }
> ```
> **MANDATORY fields:** `code`, `description`, `featureType`, `dependencies`, `dependents`, `status`, `priority`, `sortOrder`, `entities`, `estimatedComplexity`
> **status:** Always `"pending"` at creation (updated to `"in-progress"` → `"specified"` → `"validated"` by step-03/04)
> **sortOrder:** Integer from topological sort (0 = foundation layer)
> **featureJsonPath:** Set to null at creation; updated to actual path when module feature.json is created in step-03

**Complexity estimation rules:**
| Criteria | Simple | Medium | Complex |
|----------|--------|--------|---------|
| Entities | ≤2 | 3-5 | >5 |
| Expected UCs | ≤4 | 5-10 | >10 |
| Integrations | 0 | 1-2 | >2 |
| Workflows | None | Simple | Multi-step with approvals |

### 3. Present Module List to Client

Display the identified modules as markdown:

```
## Modules identifiés pour {application_name}

| # | Module | Type | Priorité | Complexité | Entités pressenties |
|---|--------|------|----------|------------|---------------------|
| 1 | Customers | data-centric | must | medium | Customer, Address, Contact |
| 2 | Products | data-centric | must | simple | Product, Category |
| 3 | Orders | workflow | must | complex | Order, OrderLine |
| 4 | Invoices | workflow | should | medium | Invoice, InvoiceLine, Payment |
```

Ask via AskUserQuestion:
```
question: "Ces modules correspondent-ils à votre vision de l'application ?"
header: "Modules"
options:
  - label: "Validé"
    description: "La liste des modules est correcte, on peut continuer"
  - label: "Ajouter un module"
    description: "Il manque un module dans la liste"
  - label: "Retirer un module"
    description: "Un module est en trop ou hors périmètre"
  - label: "Modifier un module"
    description: "Renommer, fusionner ou découper un module"
```

IF modifications requested:
  Apply changes and re-present the list
  Loop until "Validé"

### 4. Dependency Analysis

For each pair of modules, determine dependencies:

**Dependency types:**
| Type | Signal | Example |
|------|--------|---------|
| FK | Module A references entity from module B | Order.CustomerId → Customer |
| Event | Module A produces event consumed by module B | Order.Created → Invoice.AutoGenerate |
| Shared-entity | Both modules operate on same entity | Both Orders and Invoices reference Customer |
| Lookup | Module A uses reference data from module B | Products.CategoryId → Categories (if separate module) |

**For each dependency found:**
```json
{
  "from": "Orders",
  "to": "Customers",
  "type": "FK",
  "description": "Order references Customer via CustomerId"
}
```

### 5. Topological Sort

Sort modules so dependencies are processed first:

**Algorithm:**
1. Build adjacency list from dependency edges
2. Compute in-degree for each module (number of dependencies)
3. Start with modules having in-degree 0 (no dependencies)
4. Process in BFS order: remove processed modules, reduce in-degrees
5. Group into layers (modules with same depth can be processed in parallel)

**Cycle detection:**
IF a cycle is detected:
  Display ERROR:
  ```
  ⚠ Dépendance circulaire détectée : {Module A} → {Module B} → {Module A}
  Les modules ne peuvent pas dépendre mutuellement.
  ```
  Ask user to resolve: remove one direction of the dependency

**Result:**
```json
{
  "topologicalOrder": ["Customers", "Products", "Orders", "Invoices"],
  "layers": [
    { "layer": 0, "modules": ["Customers", "Products"] },
    { "layer": 1, "modules": ["Orders"] },
    { "layer": 2, "modules": ["Invoices"] }
  ]
}
```

### 6. Client Checkpoint (BLOCKING)

Display the complete decomposition as markdown:

```
## Structure de l'application {application_name}

### Graphe de dépendances

```
Customers ──┐
            ├──→ Orders ──→ Invoices
Products ───┘
```

### Ordre de traitement

| Ordre | Module | Dépend de | Complexité |
|-------|--------|-----------|------------|
| 1 | Customers | (aucune) | medium |
| 2 | Products | (aucune) | simple |
| 3 | Orders | Customers, Products | complex |
| 4 | Invoices | Orders, Customers | medium |

> Les modules seront spécifiés dans cet ordre. Chaque module sera
> détaillé avec ses sections, entités, permissions et maquettes,
> puis validé avant de passer au suivant.
```

Ask via AskUserQuestion:
```
question: "Validez-vous cette structure et cet ordre de traitement ?"
header: "Validation"
options:
  - label: "Validé, on commence"
    description: "Commencer la spécification par {first_module}"
  - label: "Modifier l'ordre"
    description: "Changer la priorité de traitement des modules"
  - label: "Revenir aux modules"
    description: "Modifier la liste des modules"
```

IF "Revenir aux modules": Go back to step 3
IF "Modifier l'ordre": Re-sort and re-present

### 7. Write Module Registry

Use ba-writer to update master feature.json:

```
ba-writer.enrichModuleRegistry({
  featureId: {feature_id},
  modules: [{module objects with all fields}],
  dependencyGraph: {
    edges: [{dependency edges}],
    topologicalOrder: [{sorted module codes}],
    layers: [{layer groups}]
  }
})

// Initialize workflow loop state
ba-writer.enrichSection({
  featureId: {feature_id},
  section: "metadata.workflow",
  data: {
    moduleOrder: [{topological order}],
    currentModuleIndex: 0,
    completedModules: [],
    currentModule: {first module code}
  }
})

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

### 8. Create Module Directories

For each module in moduleOrder:
```
Create: docs/business/{app}/{module_code}/business-analyse/v1.0/
```

> Module feature.json files will be created by step-03 when each module is processed.

### 9. Display Summary

```
## Decomposition Complete - {feature_id}

| Aspect | Value |
|--------|-------|
| Modules identified | {count} |
| Dependencies | {edge count} |
| Dependency layers | {layer count} |
| First module | {first module name} |

### Processing Order
{numbered list of modules}

→ Starting iterative specification with {first_module}...
```

---

## SINGLE-MODULE MODE

When `workflow.mode = "module"` or only 1 scope item identified:

1. Create a single module entry with code = `{module_name}` from init
2. No dependency analysis needed
3. **Simplified checkpoint:** Quick confirmation instead of full validation
4. Set moduleOrder = [{single module code}]
5. Proceed to step-03

---

## NEXT STEP

Load: `./step-03-specify.md`
