---
name: step-00-init
description: Initialize Business Analysis - Auto-detect new/update, create index.json structure
next_step: steps/step-01-cadrage.md
---

> **Context files:** `_shared.md`

# Step 00: Initialize Business Analysis

**Before anything else**, display the version banner:

```
═══════════════════════════════════════════════════════════════
  SmartStack Business Analyse — v{{SMARTSTACK_VERSION}}
═══════════════════════════════════════════════════════════════
```

Initialize the business analysis workflow by auto-detecting whether this is a new application or an update to an existing one, then creating the initial index.json structure with thematic JSON files.

## Flow

1. MCP health check (blocking)
2. Scan existing applications in `docs/`
3. Auto-detect: new application or update
4. Determine application name
5. Select language
6. Generate feature ID
7. Create output directory structure
8. Deploy JSON schemas
9. Create master index.json
10. Update config
11. Display summary
12. Load next step

## Step 1: MCP Prerequisite Check (BLOCKING)

Verify MCP availability. **This check is BLOCKING** - the skill cannot proceed without MCP.

> See `_shared.md` → "MCP Prerequisite Guard (BLOCKING)" for the full pattern.

**Detection:** Call MCP with minimal parameters:

```
mcp__smartstack__validate_conventions({ checks: ["tables"] })
```

**Decision matrix:**

| Result | Action |
|--------|--------|
| Success response | Set `mcp_available = true`, continue to Step 2 |
| Connection error / tool not found | **STOP EXECUTION** - display error below |

**On failure (STOP):**

```
═══════════════════════════════════════════════════════════════
  MCP SMARTSTACK NOT AVAILABLE - SKILL BLOCKED
═══════════════════════════════════════════════════════════════

  The SmartStack MCP server is required for business-analyse
  but could not be reached.

  To install:
    claude mcp add smartstack -- npx --package @atlashub/smartstack-cli smartstack-mcp

  To verify:
    /mcp healthcheck

  After installation, restart Claude Code and retry.

═══════════════════════════════════════════════════════════════
```

**DO NOT** continue to any subsequent step.
**STOP the skill immediately.**

## Step 2-3: Workflow Detection (Review / New / Update)

**Objective:** Detect workflow type and match against existing applications.

**Process:**

Execute workflow detection algorithm:
1. **Review Mode Detection:** Check if `{feature_description}` starts with `-review`
2. **Existing Projects Scanner:** Glob `docs/*/v*/index.json` (new ba-006 format)
3. **Legacy Scanner (backward compat):** Glob `docs/business-analyse/*/index.json` AND `docs/*/business-analyse/*/index.json` (pre-ba-006 format)
4. **Similarity Analysis:** Score user intent against existing apps (>= 80 = strong match)
5. **Decision Tree:** Prompt user with relevant options

**Decision logic:**

1. Run workflow detection: compare `{feature_description}` against `existingApps` using similarity scoring.
2. **IF detection fails or is ambiguous:**
   - **CONDITIONAL LOAD:** Read `references/detection-strategies.md` for detailed scoring algorithm, decision tree, and error handling.
   - Resolve ambiguity with user clarification.
3. **IF detection succeeds:**
   - `Workflow detected: {workflow_type} ✓`
   - Continue to application name determination.

**Key decision points:**
1. IF review mode → inform user to use `/business-analyse-review` skill instead
2. IF no existing apps → workflow_type = "new"
3. IF existing apps → analyze similarity → prompt user

**Optimization:** The detailed 400-line detection-strategies.md is loaded **only when detection fails or is ambiguous** (saves ~15,000 tokens on clear detection path).

**Store:**
```yaml
workflow_type: "new" | "update" | "review"
existing_feature_id: string | null
existing_project_id: string | null  # PROJ-NNN if resuming a project
version: "1.0" (new) | "1.1"+ (update)
review_json_path: string | null (review only)
existing_apps: array of { app, featureId, description, version }
existing_projects: array of { projectName, projectId, applications[], version }
```

> **Project Resume Detection:** If a project-level index.json is found at `docs/*/v*/index.json`, check its `metadata.workflow` to determine resume point. The project may have partially completed applications. Also check legacy path `docs/business-analyse/*/index.json` for backward compat.

## Step 3b: Early Multi-Application Detection from Prompt (NEW)

> **Detect multi-app structure BEFORE asking for a single application name.**
> When the user's prompt describes multiple applications or spans multiple business domains,
> we must recognize this immediately and set `workflow.mode = "project"` to avoid doing cadrage for a single app.

### Tier 1 — Explicit patterns (ANY match = multi-app detected)

French patterns:
- "une application X ... une application Y" (two occurrences of "une application")
- "application 1: X ... application 2: Y" (numbered applications)
- "première application ... deuxième application"
- "app 1: ... app 2: ..."

English patterns:
- "an application (for) X ... an application (for) Y" (two occurrences)
- "application #1: ... application #2: ..." (numbered)
- "first app ... second app"

If ANY of these patterns is found in `{feature_description}`:
→ `isMultiApp = true`, `detectionTier = "explicit"`

### Tier 2 — Domain diversity analysis (when Tier 1 does not match)

ULTRATHINK: Analyze `{feature_description}` to extract distinct business domains.

**Definition:** A "domain" is an autonomous business perimeter with its own entities and processes (e.g., HR, CRM, Finance, Projects, Sales, Inventory).

**Algorithm:**
1. List all business domains mentioned or implied in the description
2. Classify each domain:
   - **DISTINCT** — has its own entities, processes, and lifecycle (e.g., HR vs CRM)
   - **RELATED** — is a sub-domain of another (e.g., Payroll is a sub-domain of HR)
3. Count DISTINCT domains only

**Threshold:** 2+ DISTINCT domains → `isMultiApp = true`, `detectionTier = "domain-diversity"`

**False positive protection:**
- "RH complet avec employés, congés, paie, pointage" = 1 domain (HR) with 4 modules, NOT 4 domains
- "HR and Payroll management" = 1 domain (HR) with 2 modules — Payroll is RELATED to HR
- "gestion commerciale avec devis, commandes et facturation" = 1 domain (Sales) with 3 modules
- Only count as DISTINCT when domains have genuinely independent entity models and processes

### Extraction algorithm (depends on detection tier)

**IF Tier 1 (explicit):**

1. **Identify boundaries:** Split the prompt at each "une application" / "an application" occurrence. Each block = one candidate.
2. **Extract per candidate:** For each block, derive `name` (application name), `description` (summary of purpose), and `modules[]` (listed modules/features).
   - Example: `[{ name: "RH", description: "gestion des employés, congés, temps", modules: ["Employés", "Congés", "Temps"] }, ...]`
3. **Detect shared modules:** Collect all module names across all candidates. Any module appearing in more than one candidate is a shared module.
   - Example: `sharedModules = ["Temps"]` (appears in both RH and Projet)

**IF Tier 2 (domain-diversity):**

1. Each DISTINCT domain = 1 candidate application:
   - `name` = short domain label (e.g., "RH", "CRM", "Finance")
   - `description` = user's expressed need for that domain
   - `modules[]` = sub-functionalities mentioned (can be empty → "(à définir au cadrage)")
2. Group RELATED sub-domains under their parent DISTINCT domain as modules
3. **Detect shared modules:** Same logic as Tier 1 — modules appearing in multiple candidates

### Confirmation dialogue

Display detection result:

```
{detectionTier == "explicit"
  ? (language == "fr"
    ? "### Détection multi-application\n\nJ'ai détecté **{candidates.length} applications** dans votre description :"
    : "### Multi-application detection\n\nI detected **{candidates.length} applications** in your description:")
  : (language == "fr"
    ? "### Détection multi-application\n\nVotre description couvre **{candidates.length} domaines métier distincts**. Chaque domaine pourrait constituer une application séparée :"
    : "### Multi-application detection\n\nYour description covers **{candidates.length} distinct business domains**. Each domain could be a separate application:")}

| # | Application | Modules identifiés |
|---|-------------|-------------------|
{for each candidate: index | name | modules.join(", ") || "(à définir au cadrage)"}

{sharedModules.length > 0
  ? "⚠️ **Modules partagés détectés :** {sharedModules.join(', ')} — ces modules apparaissent dans plusieurs applications. Ils pourraient constituer une application transversale dédiée."
  : ""}
```

Ask via AskUserQuestion:
```
question: "{language == 'fr' ? 'Confirmez-vous cette structure multi-application ?' : 'Do you confirm this multi-application structure?'}"
header: "Architecture"
options:
  - label: "{language == 'fr' ? 'Oui, {candidates.length} applications' : 'Yes, {candidates.length} applications'}"
    description: "{language == 'fr' ? 'Créer un projet avec les applications identifiées' : 'Create a project with the identified applications'}"
  - label: "{language == 'fr' ? 'Extraire les modules partagés' : 'Extract shared modules'}" (only if sharedModules.length > 0)
    description: "{language == 'fr' ? 'Créer une application dédiée pour {sharedModules.join(', ')} ({candidates.length + 1} applications au total)' : 'Create a dedicated app for {sharedModules.join(', ')} ({candidates.length + 1} total)'}"
  - label: "{language == 'fr' ? 'Regrouper certains domaines' : 'Regroup some domains'}" (only if detectionTier == "domain-diversity")
    description: "{language == 'fr' ? 'Fusionner des domaines en moins d\\'applications' : 'Merge domains into fewer applications'}"
  - label: "{language == 'fr' ? 'Application unique' : 'Single application'}"
    description: "{language == 'fr' ? 'Tout regrouper en une seule application avec plusieurs modules' : 'Group everything into one application with multiple modules'}"
```

**IF "Oui, N applications" or "Extraire les modules partagés":**

```yaml
workflow_mode: "project"
project_name: derived from feature_description
candidate_applications: [{ name, description, modules, context }]
shared_modules_extracted: boolean  # true if user chose extraction
```

→ Skip step 4 (application name) — applications will be confirmed in step-01-cadrage
→ Continue to step 5 (language selection)

**IF "Regrouper certains domaines" (Tier 2 only):**

Ask via AskUserQuestion:
```
question: "{language == 'fr' ? 'Comment souhaitez-vous regrouper ces domaines ? (ex: \"RH + Paie ensemble, CRM seul\")' : 'How would you like to regroup these domains? (e.g., \"HR + Payroll together, CRM alone\")'}"
header: "Regroupement"
```

Process user response:
1. Parse the grouping instructions (natural language)
2. Rebuild `candidate_applications` based on the specified groups
3. Re-display the confirmation dialogue with the updated candidates

**IF "Application unique":**

```yaml
workflow_mode: "application"
```

→ Continue to step 4 normally

**IF no multi-app detected (neither Tier 1 nor Tier 2):**
→ Continue to step 4 normally

## Step 4: Determine Project Name & Application Name

### 4a. Project Name (ALWAYS — creates the top-level directory)

```
IF workflow_type = "update":
  projectSlug = existing project slug (from step 3 detection)
  → Skip to 4b

ELSE:
  Analyze {feature_description} to derive a project slug
  Ask via AskUserQuestion:
    question: "{language == 'fr' ? 'Quel nom pour ce projet ?' : 'What name for this project?'}"
    header: "Project"
    options:
      - label: "{detected_slug}"
        description: "{language == 'fr' ? 'Nom détecté depuis votre description (sera le dossier docs/)' : 'Name detected from description (will be the docs/ folder)'}"
      - label: "{language == 'fr' ? 'Autre' : 'Other'}"
        description: "{language == 'fr' ? 'Saisir un nom personnalisé' : 'Enter a custom name'}"

  Ensure projectSlug is kebab-case:
    projectSlug = userAnswer
      .toLowerCase()
      .replace(/[^a-z0-9\s-]/g, '')
      .replace(/\s+/g, '-')
      .replace(/-+/g, '-')
      .trim()
```

### 4b. Application Name

```
IF workflow_mode = "project":
  application_name = project_name  // Project-level name, not a single app name
  → Skip to step 5

ELSE IF workflow_type = "update":
  application_name = existing app name (from step 3)
ELSE:
  Analyze {feature_description} to extract application name
  Ask via AskUserQuestion:
    question: "{language == 'fr' ? 'Quel nom pour cette application ?' : 'What name for this application?'}"
    header: "Application"
    options:
      - label: "{detected_name}"
        description: "{language == 'fr' ? 'Nom détecté depuis votre description' : 'Name detected from description'}"
      - label: "{language == 'fr' ? 'Autre' : 'Other'}"
        description: "{language == 'fr' ? 'Saisir un nom personnalisé' : 'Enter a custom name'}"
```

**Store:**
```yaml
projectSlug: string       # kebab-case directory name (e.g., "projet-rh")
application_name: string  # or project_name if project mode
```

## Step 5: Select Language

Determine the language for analysis and code generation.

**Check config:**
- Retrieve `language` from `.business-analyse/config.json`
- Default: "fr" (Français)

**If not in config:**
```
Ask via AskUserQuestion:
  question: "Quelle langue pour l'analyse ?"
  header: "Langue"
  options:
    - label: "Français (fr)"
    - label: "English (en)"
    - label: "Italiano (it)"
    - label: "Deutsch (de)"
```

**Store:**
```yaml
language: string (code, e.g., "en", "fr")
```

## Step 5b: Analysis Mode

> The analysis phase is ALWAYS interactive — the AI listens, reformulates,
> challenges, and validates with the user. This is non-negotiable regardless
> of development mode.

**Set directly (no question):**

```yaml
analysisMode: "interactive"  # Always interactive for cadrage
```

## Step 6: Generate Feature ID

Create a unique feature identifier.

```
IF workflow_type = "update":
  feature_id = existing_feature_id (from step 3)
ELSE:
  feature_id = generate_feature_id()
  → Read .business-analyse/config.json → lastFeatureId
  → Increment and format as FEAT-NNN
```

**Store:**
```yaml
feature_id: string
```

## Step 7: Create Output Directory Structure

```
projectDir = "docs/" + projectSlug + "/v" + version

IF workflow_type = "new":
  mkdir -p {projectDir}
  docs_dir = projectDir

ELSE:
  // Directory already exists from previous session
  docs_dir = projectDir
```

> **Key change (ba-006):** All project data lives under `docs/{projectSlug}/v{X.Y}/`.
> No more `business-analyse/` intermediate directory. Applications and modules are
> direct subdirectories: `docs/{projectSlug}/v{X.Y}/{appKebab}/{moduleKebab}/`.

**Store:**
```yaml
docs_dir: string      # e.g., "docs/projet-rh/v1.0"
projectSlug: string   # e.g., "projet-rh"
```

## Step 8: Deploy JSON Schemas to Project (MANDATORY)

> **The JSON Schemas MUST be present in the project alongside the generated index.json files.**
> Without schemas, JSON files cannot be validated and have no structural reference.

See [references/init-schema-deployment.md](../references/init-schema-deployment.md) for cache-based deployment logic:
- 7 thematic schemas: entities.json, rules.json, usecases.json, permissions.json, screens.json, validation.json, handoff.json
- Version-checked via `.schema-cache.json`

**Deployment logic:**
1. Read `.schema-cache.json` if present
2. Compare current smartstack version with cached version
3. If versions match, skip deployment (already done)
4. If versions differ or cache missing:
   - Deploy all 7 schema files from `@smartstack/cli/schemas/` to `{docs_dir}/schemas/`
   - Update `.schema-cache.json` with new version

## Step 9: Create Master index.json and Thematic Files

Create the master index document and initialize thematic JSON files using ba-writer agent.

```
IF workflow_mode = "project":
  // PROJECT MODE: Create project-level index.json
  ba-writer.createProjectIndex({
    id: generate_project_id(),  // PROJ-NNN
    version: {version},
    scope: "project",
    status: "draft",
    metadata: {
      projectName: {project_name},
      language: {language},
      featureDescription: {feature_description},
      workflowType: {workflow_type},
      analysisMode: "interactive",
      mcpAvailable: true,
      candidateApplications: {candidate_applications},  // From step 3b detection
      sharedModulesExtracted: {shared_modules_extracted},
      workflow: {
        mode: "project",
        applicationOrder: [],
        currentApplicationIndex: 0,
        completedApplications: []
      }
    }
  })

  Output path: docs/{projectSlug}/v{version}/index.json
  Thematic files — EXACTLY these 3, NO OTHERS:
    - cadrage.json
    - validation.json
    - consolidation.json
  FORBIDDEN: entities.json, rules.json, usecases.json, permissions.json, screens.json, handoff.json
  Creating any FORBIDDEN file at project level is a BLOCKING ERROR.

  Store:
    project_id: string  // PROJ-NNN
    feature_id: project_id  // In project mode, feature_id = project_id for step-01

ELSE:
  // SINGLE-APP MODE: Create application-level index.json + thematic files
  ba-writer.createApplicationIndex({
    id: {feature_id},
    version: {version},
    scope: "application",
    status: "draft",
    metadata: {
      application: {application_name},
      language: {language},
      featureDescription: {feature_description},
      workflowType: {workflow_type},
      analysisMode: "interactive",
      mcpAvailable: true,
      workflow: {
        mode: "application",
        moduleOrder: [],
        currentModuleIndex: 0,
        completedModules: [],
        currentModule: null
      }
    }
  })

  Output path: docs/{projectSlug}/v{version}/index.json
  Thematic files — EXACTLY these 3, NO OTHERS:
    - cadrage.json
    - validation.json
    - consolidation.json
  FORBIDDEN: entities.json, rules.json, usecases.json, permissions.json, screens.json, handoff.json
  Creating any FORBIDDEN file at application level is a BLOCKING ERROR.
```

> **Note:** In project mode, per-application index.json files are created later in step-01-cadrage.
> In single-app mode, step-02 (structure) determines if it's single or multi-module.

### POST-CREATE VERIFICATION (MANDATORY)

After creating thematic files, verify no forbidden files were created:

```
List all *.json files in {docs_dir}/
Expected (project/application): [index.json, cadrage.json, validation.json, consolidation.json]
If any file NOT in expected list is found → DELETE it immediately + log WARNING
```

This guard catches any accidental creation of module-only files at the wrong scope.

## Step 10: Update Config

Write ALL context variables to `.business-analyse/config.json`. This file is the **single source of truth** for session state — downstream steps MUST re-read it instead of assuming LLM memory.

```json
{
  "currentFeature": {
    "id": "{feature_id}",
    "version": "{version}",
    "projectSlug": "{projectSlug}",
    "docsDir": "{docs_dir}",
    "workflowType": "{workflow_type}",
    "workflowMode": "{workflow_mode}",
    "application": "{application_name}",
    "applicationCode": "{applicationCode}",
    "projectId": "{project_id}",
    "language": "{language}",
    "analysisMode": "interactive",
    "mcpAvailable": true,
    "candidateApplications": "{candidate_applications}",
    "sharedModulesExtracted": "{shared_modules_extracted}"
  },
  "lastInitialized": "{ISO timestamp}"
}
```

> **CRITICAL:** Every downstream step (01-04) MUST start by reading this file to recover variables. Do NOT rely on LLM memory for `docs_dir`, `feature_id`, `applicationCode`, or `workflow_mode`.

## Step 11: Display Summary

```
═══════════════════════════════════════════════════════════════
  BUSINESS ANALYSIS INITIALIZATION COMPLETE
  SmartStack CLI v{{SMARTSTACK_VERSION}}
═══════════════════════════════════════════════════════════════

| Field              | Value                                        |
|--------------------|----------------------------------------------|
| Feature ID         | {feature_id}                                 |
| Workflow           | {workflow_type}                               |
| Mode               | {workflow_mode === "project" ? "Multi-application project" : "Single application"} |
| Application/Project| {workflow_mode === "project" ? project_name + " (" + candidate_applications.length + " apps)" : application_name} |
| Output Path        | {docs_dir}/index.json                        |
| Language           | {language}                                   |
| Version            | {version}                                    |
| MCP Available      | true                                         |
| Analysis Mode      | Interactive (always)                         |

{workflow_mode === "project"
  ? "Candidate applications: " + candidate_applications.map(a => a.name).join(", ")
  : ""}

NEXT STEP: step-01-cadrage
═══════════════════════════════════════════════════════════════
```

## Step 12: Load Next Step

After showing initialization summary, proceed to `./step-01-cadrage.md`

**Pass context variables:**
```yaml
feature_id: string               # FEAT-NNN (single-app) or PROJ-NNN (project)
feature_description: string
workflow_type: "new" | "update"
workflow_mode: "application" | "project"
projectSlug: string              # kebab-case directory name (e.g., "projet-rh")
application_name: string         # Single-app: app name. Project: project name.
applicationCode: string          # PascalCase derived from application_name (preliminary, confirmed in step-01)
project_id: string | null        # PROJ-NNN if project mode, null if single-app
candidate_applications: array | null  # Pre-identified apps from prompt (project mode only)
shared_modules_extracted: boolean     # True if user chose to extract shared modules as new app
language: string
docs_dir: string
mcp_available: boolean
analysisMode: "interactive"
version: string
```

## Error Handling

| Error | Action |
|-------|--------|
| Config missing | Create fresh with defaults, continue |
| Directory creation fails | Check permissions, display error, EXIT |
| index.json creation fails | Validate ba-writer, retry or fallback |
| Feature ID not unique | Generate new ID, retry |

### Resume After Interruption

If initialization was interrupted:

1. Check `.business-analyse/config.json` for currentFeature or currentProject
2. If project ID exists, search for project index.json in `docs/*/v*/` (or legacy `docs/business-analyse/`)
   - If found with scope = "project": resume project mode (see Project Resume below)
3. If feature ID exists, search for index.json in `docs/`
4. If found, check status and `metadata.workflow.lastCompletedStep`:

   **Status-based resume routing (check in this order):**

   - If status = `"handed-off"` or `"consolidated"`:
     → Display: "BA workflow complete. Use /business-analyse-html to generate HTML, /business-analyse-review for corrections."
     → STOP

   - If status = `"specified"` AND `metadata.workflow.allModulesSpecified === true`:
     → Resume at `step-04-consolidate.md`
     → Display: "All modules specified — resuming at consolidation..."

   - If status = `"specified"` AND `metadata.workflow.completedModules.length > 0` AND `metadata.workflow.completedModules.length < metadata.workflow.moduleOrder.length`:
     → Resume at `step-03-specify.md` (continue specifying remaining modules)
     → Display: "Resuming module specification ({completedCount}/{totalCount})..."

   - Otherwise: offer to resume from last completed step

5. If not found, create fresh index.json

**Project Resume (project mode):**

If a project-level index.json is found (scope = "project"):

   - If status = `"draft"` or `"framed"`:
     → Resume at `step-01-cadrage.md`

   - If status = `"decomposed"`:
     → Check `metadata.workflow.currentApplicationIndex` and `completedApplications[]`
     → Resume module specification for current application (step-02 or step-03)

   - If status = `"specified"`:
     → All applications specified → Resume at `step-04-consolidate.md`

   - If status = `"consolidated"`:
     → Display: "BA workflow complete. Use /business-analyse-html to generate HTML."
     → STOP
