# Rapport de session · 2026-07-30 · session 21

## Tâche

**Sprint 7 · CRM + Faisabilité** — Générateur des **Scénarios démo (run-sheet de
pitch)** (roadmap `04_roadmap/ROADMAP_8_WEEKS_OR_LESS.md` **l.68** :
« CRM + Faisabilité : Scénarios démo (**P07 pitch banquier · P05 client ready**) »).

C'est le **dernier volet Sprint 7 réalisable en repo**. Les deux autres volets
(polish `otov7.com` côté Frontend, branchement au `data_room` réel des projets)
dépendent du site live / des archives serveur — hors périmètre worker (#8).

## Décision d'architecture

**Orchestrateur de méta-niveau**, pas un contenu marketing écrit à la main. Un
scénario démo est une suite de **beats** (scènes) ; chaque beat cite une **preuve**
= un **pointeur RFC 6901** vers un hand-off `out/` d'un module **déjà livré**. Le
générateur **résout** la valeur à la construction. Conséquences :

- **Zéro invention (#6)** : aucune valeur chiffrée n'est écrite dans le spec ; une
  valeur introuvable devient un placeholder `{{module:file#pointer}}` — jamais un
  `0` fabriqué, ni un `null` amont promu en chiffre de pitch.
- **Zéro duplication (#5)** : réutilise le validateur maison du Publiciste **et**
  la preuve de couverture CI de l'auditeur 4Big (`q4lib/registry.py`) pour
  garantir qu'une démo ne s'appuie QUE sur des modules **gated** par le CI.

## Fichiers créés — `05_deliverables_mvp/demo/scenarios/`

- `scenario_spec.json` — 2 scénarios · 12 beats · 23 pointeurs de preuve
  (**0 chiffre en dur** · libellés projets P05/P07 verbatim de CLAUDE.md §Projets)
- `scenlib/{__init__,deps,evidence,builder}.py`
  - `deps` réutilise `validator.validate` (Publiciste) + `registry.ci_module_paths`
    (audit 4Big) · `evidence` charge les `out/` amont + résout les pointeurs
    RFC 6901 · `builder` assemble run-sheet + manifeste de façon déterministe
- `demo_scenario_gen.py` — CLI `build`/`validate` + **7 familles d'invariants**
- `scenario.schema.json` — contrat de sortie draft-07
- `out/{run_sheet,MANIFEST}.json` — hand-off
- `tests/test_demo_scenario.py` — **32 tests** (dont 9 injections négatives)
- `README.md` · `.gitignore`

## Fichiers modifiés

- `.gitea/workflows/ci.yml` : job `demo-scenario-tests` + ajout au `gate`.
- `qa/audit_4big/quality_spec.json` : enregistrement du module `demo/scenarios`
  (archétype `generator`) + prose « 17 → 18 modules ».
- `qa/audit_4big/tests/test_audit_4big.py` : `totals.modules` **17 → 18**
  (2 assertions) — l'auditeur doit tracer chaque nouveau livrable, sinon sa
  **preuve de couverture bijective rougit** (garde-fou anti-omission).
- `qa/audit_4big/out/*` régénéré : **verdict PASS · 18/18 modules ≥ 95 (min 100)**.

## Anti-invention (cœur · #6)

Une valeur du run-sheet **ne peut pas être posée** : `_check_anti_invention`
**re-résout indépendamment** chaque pointeur depuis le disque et compare
(valeur + statut résolu) au run-sheet. Recoupe aussi spec ↔ run-sheet (mêmes
pointeurs, même ordre). Un `null` amont (`condition: null` d'une transition) est
traité comme **non résolu** → placeholder, jamais promu en chiffre.

## Résultat

Run-sheet `pret=true` : **2 scénarios · 12 beats · 23/23 citations résolues ·
10 modules cités tous gated**. Valeur = **contrat déterministe** qu'un rendu VPS
(deck / prompteur / page démo) consommera sans risque d'invention.

## Vérifications

- 32/32 tests du module ; 34/34 tests audit_4big (après passage à 18 modules).
- Régression complète : **474 tests verts** (442 → +32), **0 module en échec**.
- Guards CI locaux verts : `guard_constraints` · `validate_json` · `check_docs`.
- `ci.yml` : YAML valide · job + `needs` du gate présents.
- Builds déterministes (double build identique).

## Hors périmètre worker (VPS · #8)

Rendu final (deck / prompteur / page démo `otov7.com`) + branchement au
`data_room` réel → agent Frontend / DevOps. Le run-sheet est le **contrat**.

## Auto-score 4Big

**96/100** — orchestrateur cross-module, anti-invention prouvée par re-résolution,
couverture CI réutilisée, injections négatives. −4 : le rendu jouable (deck) reste
côté VPS, non démontrable en repo.
