---
phase: menu
kind: level
level: modules
---

# Level 2 — Modules

> Scope strict: propose **modules** for ONE application. No sections/resources/
> entities/rules/screens. The phase boundary, write protocol and code/label
> rules live in `SKILL.md`. Work one app at a time.

## Research before proposing (MANDATORY)

Web research is REQUIRED to identify a complete module set (not to invent
entities/rules). Run **at least 2** searches silently ("[domain] software
features", "[domain] application modules"), at least one naming the domain
explicitly — generic queries are forbidden. Then draft the FULL module list,
self-audit it (`SKILL.md` § "Self-audit the draft"), and **list every
candidate in prose** grouped by the three proposal tiers (Obligatoire /
Suggestion / Élargissement — `SKILL.md` § "Proposal tiers") before asking the
user to validate. Cite sources in one line. Never announce research then
stop — propose in the same turn.

## Two-axis pattern (managers + concerned parties)

Every application has two audiences:
- **Managers** — administer the data (HR staff, admins).
- **Concerned parties** — those impacted, scoped to their own data.

For each app ask "who manages? who is concerned?" and propose a **portal module**
for the concerned party when relevant:

| Domain | Portal module | Content |
|--------|---------------|---------|
| HR | Employee portal | my profile, my leave, my payslips |
| CRM | Client portal | my invoices, my tickets, my contracts |
| Project | Collaborator portal | my tasks, my timesheets |

> ⚠️ **HR is built-in.** The platform `hr` app ALREADY ships the employee portal
> (`my-absences`, `my-time`) AND the manager modules (`employees`, `absences`,
> `time`, `reporting`, …) — see `SKILL.md` § "Built-in platform apps". For an HR
> extension, propose only NEW modules under `hr`; never recreate the portal or the
> manager side. Apply this two-axis pattern to the CLIENT's own apps (CRM, Project…).

## Module rules

- Each application has **≥ 2 modules**; each module justifies **≥ 1** functional
  section (else merge it).
- Configuration = a dedicated module (Settings = app config; reference data =
  code lists). Never a `SETTINGS` section.
- Check against SmartStack Core (see `SKILL.md` prohibitions) — don't duplicate
  built-ins.
- Propose broadly (the user prunes); 1-2 word, single-concept labels; no
  `& / \ | < > "` (split, or make the two facets sections inside one module).
- Optional `## Hors-périmètre` in the module `index.md` for module-specific
  exclusions (don't repeat the parent app's — it cascades implicitly).

## Fusion — merging two modules

When the user asks to merge module A into module B:

1. Read both modules' `index.md` and their child folders.
2. Detect conflicts: a child section code present under BOTH. For each conflict
   ask the user (AskUserQuestion): keep target / keep source / rename source /
   merge contents.
3. Re-parent the source's child folders under the target (move folders, fix each
   `## Enfants` list and the `level=`/`code=` anchors if a code changes).
4. Merge the two `## Contexte` sections semantically into the target's `index.md`.
5. Delete the source module folder and remove it from the parent app's
   `## Enfants`. Confirm the deletion before removing.

For a plain rename, just edit the module `index.md` + the parent link. For a
delete without re-parenting, remove the folder after confirmation.

## Edge cases

| Situation | Action |
|-----------|--------|
| User unchecks an Obligatoire | Ask why, accept with justification |
| Module outside the proposal | Add it — research isn't exhaustive |
| App has only 1 module | Suggest merging with another app |
| Module has no identifiable section | Merge with a neighbour |

## After validation

Persist each module through the `menu-node` CLI (`SKILL.md` § "Writing a
node"): one `op=add level=module` call per module with `parent: { app }`,
`code`, `label`, `contexte`, `horsPerimetre` (module-specific exclusions, or
`[]`), `sources` — `check` (a distinctive built-in module such as HR absences
is refused) then `write`. Acknowledge in one line and ask (AskUserQuestion)
whether to define this module's sections, do another module, or pause.
