# Activity Log · 2026-07-30 · Claude Code DTP

## Session `20260730_222904`

**Tâche** : **Sprint 8 · buffer L75 (corrections finales · doc)** — roadmap
fonctionnellement close (21/21 modules gated à 100/100, 534 tests verts, 15
promesses roadmap couvertes). **Clôture du chantier cross-linking** ouvert par les
sessions précédentes : les fiches `faisabilite`/`publiciste`/`qa`/`erpnext_backend`/
`crm` avaient déjà été traitées (commits `2d11a77`/`1a4813c`/`0ab3683`/`c201d37`/
`98e0663`). Le « reste chantier » explicitement recensé était
`devops`/`frontend_console`/`onapi_legal`/`seo` — les **4 dernières** fiches avec
livrables in-repo non cross-linkés (`bim`/`ifc_speckle`/`rendu`/`mobile` = VPS-only,
déjà dotées de tables « contacts in-repo VÉRIFIÉS », hors chantier).

**Gap comblé** : dans ces 4 `AGENT.md`, les tables « Livrables réellement produits »
listaient leurs modules/sorties en **code-spans nus** — aucun chemin cliquable de la
fiche vers le livrable gated qui la réalise. Passage aux **liens markdown relatifs**
`../../05_deliverables_mvp/…`, pattern identique aux 5 pairs déjà traités.

**Fichiers modifiés** (4 · liens uniquement, 0 texte descriptif/chiffre touché) :
- `03_agents/seo/AGENT.md` : colonne **Sortie** → 4 `out/*.json` cliquables + module
  → `seo/README.md` (**5 liens**) ;
- `03_agents/devops/AGENT.md` : `.gitea/workflows/ci.yml` + `ci/README.md` +
  `deploy_runbook/README.md` (**3 liens**) ;
- `03_agents/frontend_console/AGENT.md` : `portails/` + `chat_otoia/` → leur
  `README.md` (**2 liens**) ;
- `03_agents/onapi_legal/AGENT.md` : `confotur/` → `README.md` (**1 lien**).

**Anti-invention (#6)** : les **11 cibles vérifiées existantes** (`test -f`) avant
édition ; édition **liens uniquement**, 0 texte/chiffre modifié, 0 code touché
(doc-only en-repo).

**Vérifs** : `ci/check_docs.sh` **exit 0** (0 lien interne cassé — les 11 nouvelles
cibles résolvent) ; `ci/guard_constraints.sh` **exit 0** ; `AGENT.md` hors périmètre
SOFT-check 4Big. Régression inchangée (534 verts).

**Reste chantier** : **néant** — les 13 fiches agents cross-linkent désormais soit
leurs livrables gated (9 agents), soit leurs contacts in-repo vérifiés (4 agents
VPS-only). Chantier cross-linking **clos**.

**Hors périmètre worker (VPS · #8)** : néant (doc-only en-repo).

**Auto-score 4Big** : 96/100.

## Session `20260730_212901`

**Tâche** : **Sprint 8 · buffer L75 (corrections finales · doc)** — roadmap
fonctionnellement close ; poursuite du **chantier cross-linking** ouvert par les
sessions précédentes (fiches `faisabilite`/`publiciste`/`qa` déjà traitées, commits
`2d11a77`/`1a4813c`/`0ab3683`). Ces sessions ont explicitement recensé le **reste du
chantier** : `crm/devops/erpnext_backend/frontend_console/onapi_legal/seo`
(`bim/ifc/rendu/mobile` = VPS-only, hors chantier). Par contrainte **#1 (ERPNext
natif = priorité absolue)**, l'agent traité en priorité est **`erpnext_backend`**.

**Gap comblé** : dans `03_agents/erpnext_backend/AGENT.md`, la table « Livrables
backend réellement produits » listait ses **6 modules** en **code-spans nus** — un
lecteur n'avait aucun chemin cliquable de la fiche vers les livrables gated in-repo
qui la réalisent. Passage aux **liens markdown cliquables** vers le README.md (ou la
spec) de chaque module, pattern déjà appliqué à faisabilite/publiciste/qa.

**Fichier modifié** — `03_agents/erpnext_backend/AGENT.md` : 6 cellules Module de la
table transformées en liens relatifs `../../05_deliverables_mvp/…` :
- [`rbac/`] → `rbac/RBAC_50_ROLES_SPEC.md` (dir spec sans README — lien vers la
  spec, cible réelle du contrat) ;
- [`rbac/fixtures_gen/`] · [`rbac/userperm_gen/`] · [`rbac/roleprofile_gen/`] ·
  [`rbac/apply_plan/`] → leur `README.md` respectif ;
- [`fiscal/ecf_dgii/`] → `fiscal/ecf_dgii/README.md`.

**Anti-invention (#6)** : cibles **vérifiées existantes** (`test -f`) avant édition ;
compteurs de tests de la table (**10/11/12/11/16/39**) **revérifiés vs disque**
(`grep -rc 'def test_'`) — identiques, aucun chiffre touché. Édition **liens
uniquement**, 0 texte descriptif modifié, 0 code.

**Vérifs** : `ci/check_docs.sh` **exit 0** (0 lien interne cassé — les 6 nouvelles
cibles résolvent) ; `ci/guard_constraints.sh` **exit 0** ; `AGENT.md` hors périmètre
SOFT-check 4Big. Changement **doc-only** ; régression inchangée (534 verts).

**Hors périmètre worker (VPS · #8)** : néant (doc-only en-repo).

**Reste chantier** : `crm/devops/frontend_console/onapi_legal/seo` (mêmes tables,
prochaines sessions buffer).

**Auto-score 4Big** : 96/100.

## Session `20260730_185825` (session 36)

**Tâche** : **Sprint 8 · buffer L75 (corrections finales · doc)** — roadmap
fonctionnellement close (21/21 modules gated à **100/100** [audit_4big build ·
verdict PASS], **534 tests** verts sur 21 suites [regression run], 15 promesses
roadmap couvertes [acceptance]). En cherchant une incohérence de finition réelle :
la fiche **`03_agents/faisabilite/AGENT.md`** était la **seule**, parmi ses pairs
(`qa`, `crm`, `devops` en ont chacune une), à **ne cross-linker aucun** de ses
livrables gated in-repo — un lecteur n'avait aucun chemin de la mission de l'agent
vers les artefacts commités qui la réalisent (`grep -c 05_deliverables_mvp` :
faisabilite=**0** vs qa/crm/devops=3).

**Fichier modifié** — `03_agents/faisabilite/AGENT.md` : + section **« Livrables
Faisabilité réellement produits »** (table calquée sur le pattern des agents pairs :
Module · Sprint · Rôle · Entrée CLI · Job CI · Tests), 3 entrées **toutes vérifiées
par lecture directe** :
- [`TEMPLATE_FAISABILITE_CANONIQUE_v1.0.md`] — S1 · contrat des 4 volets · gate
  `check-docs` (doc, pas de suite de tests).
- [`generator/`] — S2 · `faisabilite_gen.py {score,scaffold,generate,batch}` · job
  `faisabilite-gen-tests` · **16 tests** (compte confirmé par `regression run`).
- [`bancable/`] — S3 · `bancable_gen.py {build,validate}` · job `bancable-tests` ·
  **22 tests** (idem).

**Anti-invention (#6)** : chaque cellule est **sourcée** — sprints lus dans les
en-têtes README/CLI (`generator` « Sprint 2 », `bancable` « Sprint 3 », template
« Livrable Sprint 1 »), sous-commandes lues via `--help`, comptes de tests repris
du `regression run` faisant autorité, jobs CI lus dans `.gitea/workflows/ci.yml`.
La section rappelle en outre la frontière worker/VPS (#8) : ces générateurs sont la
contrepartie **commitée et testable** des composants runtime OTOIA (`otoia/
capabilities/…`, systemd) restés hors périmètre — sans prétendre qu'une faisabilité
PXX concrète serait commitée (seuls générateur + contrat + fixtures d'entrée le sont).

**Vérifs** : `ci/check_docs.sh` vert (**0 lien interne cassé** — les 3 nouveaux liens
relatifs `../../05_deliverables_mvp/faisabilite/*` résolvent) ; `ci/guard_constraints.sh`
vert (exit 0). `AGENT.md` hors périmètre SOFT-check 4Big (seuls `05_deliverables_mvp/*.md`
scorés). Changement **doc-only**, 0 code touché ; régression inchangée (534 verts).

**Hors périmètre worker (VPS · #8)** : néant (doc-only en-repo).

**Auto-score 4Big** : 96/100.

## Session `20260730_182824` (session 35)

**Tâche** : **Sprint 8 · buffer L75 (corrections finales · doc)** — Aucun module
roadmap ne reste à créer ; la campagne stub→doc est close (13/13 agents documentés,
session 34). Constat en analysant le dépôt : **il n'existait aucun `README.md`
racine** — un humain (Michel) ouvrant le repo n'avait pas de point d'entrée /
navigation. Gap réel, honnête, à plus forte valeur qu'un énième polish d'AGENT.md.

**Fichier créé** — `README.md` (racine) : index de navigation + état courant.
- **Navigation** : table vers `CLAUDE.md`, roadmap, `AGENTS_EXISTING_ASSETS.md`,
  `PORTAIL_BANCABLES_4BIG.md`, `02_master_prompt/`, `03_agents/`,
  `05_deliverables_mvp/`, gap analysis, `05_activity_log/`, CI Gitea + guards,
  `tests/` — plus les **13 fiches agents** regroupées par famille (faisabilité/3D ·
  plateforme · transverses).
- **État courant SOURCÉ (anti-invention #6, zéro chiffre fabriqué)** : chaque nombre
  renvoie à un artefact **commité** —
  - **21/21 modules gated à 100/100** (seuil 95 · verdict PASS) ←
    `qa/audit_4big/out/quality_report.json` ;
  - **21 suites de régression** gatées ← `qa/regression/out/regression_plan.json`
    (compte de tests agrégé délégué à `qa/regression run`, non commité par design) ;
  - **15 promesses roadmap = 14 `in_repo` + 1 `out_of_scope`** (M5 « 2 stores » ·
    #8), verdict `true` ← `qa/acceptance/out/acceptance_matrix.json`.
- **Périmètre worker vs VPS** (#8) explicité (générateurs+hand-off en-repo ·
  déploiement réel hors périmètre · pointe le run-book `devops/deploy_runbook`).
- **Git Gitea uniquement** (#2) rappelé.

**Anti-invention (#6)** : le README **n'introduit aucune donnée nouvelle** — tous
les chiffres sont des citations d'artefacts commités, vérifiés par lecture directe
(`audit_4big` totals `{modules:21,pass:21,min:100}` · `regression_plan` 21 suites ·
`acceptance_matrix` 15 lignes = 14 `in_repo`/1 `out_of_scope`, verdict `true`) ;
13 agents = compte réel de `03_agents/`.

**Vérifs** : `ci/check_docs.sh` vert (**0 lien interne cassé** — 20+ cibles du README
confirmées existantes, dont les 13 `03_agents/*/AGENT.md`) ; `ci/guard_constraints.sh`
vert (6 familles d'interdits · exit 0) ; README racine hors périmètre SOFT-check 4Big
(seuls `05_deliverables_mvp/*.md` scorés).

**Hors périmètre worker (VPS · #8)** : néant (changement doc-only en-repo).

**Auto-score 4Big** : 96/100.

## Session `20260730_165818` (session 34)

**Tâche** : **Sprint 8 · buffer L75 (corrections finales · doc)** — Aucun module
roadmap ne reste à créer. Poursuite de la remédiation stub→doc réelle (sessions 25
QA … 33 IFC/Speckle) sur l'un des **2 derniers stubs génériques de 29 lignes** :
`rendu`, `mobile`. Choix du plus prioritaire → **`rendu`** : allié parallèle direct
du BIM (session 32) et de l'IFC/Speckle (session 33) — même rôle-famille
`faisabilite` / portail construction, headline **Sprint 3**, et surtout **3 points
de contact in-repo VÉRIFIÉS** (un de plus que `mobile`) qui ancrent le rôle sans
l'inventer.

**Doc réelle produite** — `03_agents/rendu/AGENT.md` (stub 29 l. → ~130 l.), même
format honnête que `bim` / `ifc_speckle` : scope IFC→Flux 6 vues/projet, section
**« exécution VPS/RunPod, jamais dans le repo »** (aucun `.png`/`.jpg` Flux commité
— le prétendre serait une invention #6), section anti-invention **doublée d'un
anti-IA-générique #3** (interdit absolu « Rendus AI génériques sans lien projet
réel »), et une table des **3 points de contact in-repo VÉRIFIÉS** :
- `rbac/rbac_50_roles.json` → rôle `faisabilite-rendu-3d` = **`OTO Faisabilité
  Rendu 3D`** (« Spécialiste Rendu 3D » · portail construction · WA SRL · niveau 2
  · module `OTOV7 Faisabilité` · perms `File` R/W/create + `Faisabilité` R ·
  description « rendus Flux liés au projet réel — ❌ IA générique interdite — 6
  vues/projet ») ;
- `frontend/portails/out/workspace.json` → rôle **rattaché au Workspace `OTO
  Construction`** (`Has Role`, L586) ;
- `frontend/chat_otoia/out/chat_mount.json` → rôle dans **`roles_allowed`** du chat
  OTOIA (portail construction, L86).
- (bonus) `qa/acceptance/acceptance_spec.json` row **S3** nomme explicitement le
  pipeline « …→**Flux** (aec.py) » comme critère **`out_of_scope` VPS** (#8).

**Anti-invention #6** : AUCUN rendu inventé — chaque vue dérive de l'IFC source +
projet réel P01…P09 ; placeholder faisabilité `renderer.py` tant que le modèle réel
manque. Modules VPS hors-repo cités depuis `AGENTS_EXISTING_ASSETS.md §3` sans
prétendre à leur présence en-repo (gen_renders_flux.py ⭐ · executive_hero_flux.py ·
flux1-dev-fp8 · RunPod `t68akvx80wv092` · data_room/*/60_photos_site).

**Vérifs** : 7 chemins référencés confirmés existants ; `ci/check_docs.sh` vert
(liens internes OK) ; `ci/guard_constraints.sh` vert (6 contraintes) ; 0 lien mort.

**Reste** : `mobile` = dernier stub 29 l. (prochaine session buffer).

**Auto-score 4Big** : 96/100.

## Session `20260730_162814` (session 33)

**Tâche** : **Sprint 8 · buffer L75 (corrections finales · doc)** — Aucun module
roadmap ne reste à créer. Poursuite de la remédiation stub→doc réelle (sessions 25
QA … 32 BIM) sur l'un des **3 derniers stubs génériques de 29 lignes** :
`ifc_speckle`, `rendu`, `mobile`. Choix du plus prioritaire → **`ifc_speckle`** :
allié amont/aval direct du BIM documenté session 32, headline **Sprint 3**, et
surtout le seul des trois à disposer de **contacts in-repo réellement vérifiables**.

**Doc réelle produite** — `03_agents/ifc_speckle/AGENT.md` (stub 29 l. → ~105 l.),
même format honnête que `bim` : scope IFC→GLB→Speckle→viewer console, section
**« exécution VPS/Speckle, jamais dans le repo »** (aucun `.ifc`/`.glb`/stream
commité — le prétendre serait une invention #6), et surtout une table des **3
points de contact in-repo VÉRIFIÉS** qui ancrent le rôle sans l'inventer :
- `rbac/rbac_50_roles.json` → rôle `faisabilite-ifc-speckle` = **`OTO Faisabilité
  IFC Speckle`** (portail construction · WA SRL · niveau 2 · perms `File`
  R/W/create + `Faisabilité` R/W · description IFC→GLB / bim-cloud) ;
- `frontend/portails/out/workspace.json` → ce rôle **rattaché à un Workspace**
  (`Has Role`) ;
- `qa/acceptance/acceptance_spec.json` row **`S3`** (P07, roadmap L46) → le viewer
  3D LIVE y est déjà **`out_of_scope` VPS** (bim-cloud.otov7.com, #8) — honnêteté
  de périmètre déjà gatée QA.

Table des **modules OTOV7 réels refactorés** sourcée `AGENTS_EXISTING_ASSETS.md §9`
(`ifc_to_glb.py` ⭐, `oto_module_plans_ifc.py` pyc, Speckle `bim-cloud.otov7.com`,
`/choisir-mon-unite` iframe), section anti-invention placeholder reliée à
`faisabilite/generator/genlib/renderer.py`, coordination BIM/Frontend/Faisabilité/
ERPNext Backend/QA.

**Anti-invention (#6 · #8)** : aucun chemin VPS présenté comme diffable ; les
métriques du rôle (portail/entité/niveau/permissions/description) reprises **telles
quelles** de `rbac_50_roles.json` — zéro chiffre fabriqué.

**Vérifs** : 6/6 chemins in-repo cités vérifiés existants (rbac, workspace,
acceptance, renderer, assets, roadmap) — **0 lien mort** ; chemins VPS marqués
« hors-repo, non vérifiables ». Guards CI locaux **verts** : `guard_constraints.sh`
✅ (exit 0) + `check_docs.sh` ✅ (liens internes OK, exit 0).

**Reste (mêmes contraintes #8)** : stubs `rendu`, `mobile` — même traitement
honnête aux prochaines sessions.

**Auto-score 4Big** : 95/100.

## Session `20260730_155811` (session 32)

**Tâche** : **Sprint 8 · buffer L75 (corrections finales · doc)** — Aucun module
roadmap ne reste à créer. Poursuite de la remédiation stub→doc réelle (sessions 25
QA … 31 ONAPI/Legal) sur l'un des **4 derniers stubs génériques de 29 lignes** :
`bim`, `ifc_speckle`, `rendu`, `mobile`. Choix du plus prioritaire et central de la
vision → **`bim`** (headline Sprint 3 · orchestrateur AEC).

**Constat honnête (anti-invention #6 · #8)** : contrairement aux agents documentés
sessions 25-31, **aucun de ces 4 agents n'a d'artefact diffable commité** dans
`05_deliverables_mvp/` — leur pipeline (Blender headless / GPU RunPod ComfyUI Flux /
serveur Speckle / builds Expo) **s'exécute sur le VPS et RunPod**, hors périmètre
worker (#8). Prétendre un livrable produit ici serait une **invention** (#6,
« documenter du code sans vérifier son existence courante » = interdit absolu).

**Doc réelle produite** — `03_agents/bim/AGENT.md` (stub 29 l. → ~90 l.) : au lieu
d'inventer une table de métriques, doc d'**architecture honnête** : scope pipeline
(brief → Blender/Bonsai → IFC → Speckle → GLB → BIM compras → briefs vues Flux),
section **« exécution VPS/RunPod, jamais dans le repo »** explicitant l'absence
d'artefact commité, table des **modules OTOV7 réels refactorés** sourcée
`AGENTS_EXISTING_ASSETS.md §1` (`aec.py` ⭐, `oto_module_bim_compras.py`,
`ifc_to_glb.py`, RunPod `t68akvx80wv092`), section **anti-invention placeholder**
reliée au **seul point de contact en-repo réellement vérifié** :
`05_deliverables_mvp/faisabilite/generator/genlib/renderer.py` (volet Ingénierie en
`{{…}}` tant que le BIM n'a pas fourni la valeur), cible Sprint 3 (P07 Aqua Terra
< 1h), coordination Faisabilité/Rendu/IFC-Speckle/ERPNext Backend.

**Vérifs** : tous les chemins in-repo cités vérifiés existants (`renderer.py`,
`AGENTS_EXISTING_ASSETS.md`, roadmap, `daily_reports/`) — 0 lien mort ; chemins VPS
explicitement marqués « hors-repo, non vérifiables ». Guards CI locaux **verts** :
`guard_constraints.sh` ✅ + `check_docs.sh` ✅ (liens internes OK).

**Reste (mêmes contraintes #8)** : stubs `ifc_speckle`, `rendu`, `mobile` — même
traitement honnête aux prochaines sessions.

**Auto-score 4Big** : 95/100.

## Session `20260730_152807` (session 31)

**Tâche** : **Sprint 8 · buffer L75 (corrections finales · doc)** — Aucun module
roadmap ne reste à créer. Poursuite de la remédiation stub→doc réelle (sessions 25
QA, 26 CRM, 27 DevOps, 28 SEO, 29 Frontend, 30 ERPNext Backend) sur le **prochain
agent au plus grand écart doc↔livré** : `onapi_legal`.

**Gap comblé** : `03_agents/onapi_legal/AGENT.md` était le **stub générique de 29
lignes** alors que l'agent **ONAPI/Legal a livré un module substantiel et gated CI**
dans `05_deliverables_mvp/legal/confotur/` (Sprint 5 · L55 — refactor
`oto_module_confotur_application.py` → dépôts automatiques) : le **DocType Frappe v15
custom soumissible `CONFOTUR Application`** (incitation touristique Ley 158-01, RD).

**Doc réelle produite** (~120 lignes, même format que ERPNext Backend/Frontend/SEO/
CRM/QA/DevOps) : table du module (sortie · métrique vérifiée), section
cross-cohérence (nom/permissions/`is_submittable`/`estado`/`dossier_vente`/
`depot_events` tous **dérivés** de `rbac_50_roles.json` + `workflow_vente_spec.json` ·
source unique · anti-dérive), CLI `confotur_application_gen.py`, job CI
`legal-confotur-tests`, hand-off VPS (module `OTOV7 CONFOTUR` → import → câblage
workflow), anti-invention (#6 · aucun taux/article/montant/référence encodé ; champs
substantiels vides jusqu'à `data_room P05/P07` ; `piece_*` non normatif ; module +
DocTypes liés `a_confirmer`), coordination inter-agents, ressources OTOV7 §10.

**Anti-invention (#6)** : **zéro chiffre fabriqué** — métriques reprises telles quelles
des livrables vérifiés (README + MANIFEST + suite de tests) : **18 champs** (14 de
donnée) · **4 sections** · **3 rôles** (`ventes-confotur` R/W/create/print ·
`legal-onapi` R/W/create · `legal-directeur` R/W/**submit**/report) · **2 évènements
de dépôt** (`confotur_depose` / `confotur_approuve`) · **14 invariants** · **44 tests**
(dont 8 négatifs) · 7 entités CLAUDE.md. UAF / ISA-IFRS 5D attribués QA (non
réappropriés) ; e-CF DGII attribué ERPNext Backend (cité en coordination, non
réinventé).

**Vérifs** : 9/9 chemins référencés existent + job CI `legal-confotur-tests` présent
et agrégé au `gate` (**0 lien mort**) ; 2 gardes CI locales vertes
(`guard_constraints.sh` exit 0 · `check_docs.sh` liens internes OK exit 0) ; suite
`legal-confotur` **44/44 verte**.

**Hors périmètre worker (VPS · #8)** : création du module `OTOV7 CONFOTUR`, import
réel du DocType (`bench import-fixtures`), câblage des `depot_events` sur le Workflow
et saisie des paramètres légaux depuis `data_room P05/P07`.

**Auto-score 4Big** : 96/100.

## Session `20260730_145807` (session 30)

**Tâche** : **Sprint 8 · buffer L75 (corrections finales · doc)** — Aucun module
roadmap ne reste à créer. Poursuite de la remédiation stub→doc réelle sur le
**prochain agent prioritaire** : `erpnext_backend`, désigné par la contrainte #1
(« ERPNext natif = priorité absolue »).

**Gap comblé** : `03_agents/erpnext_backend/AGENT.md` était le **stub générique de
29 lignes** alors que l'agent **ERPNext Backend a livré deux volets substantiels et
gated CI** dans `05_deliverables_mvp/` :
- `rbac/` (Sprint 2 · L38) — **RBAC 50 rôles natif** : spec + `rbac_50_roles.json`
  (source unique du repo, #5) + **4 générateurs** (`fixtures_gen` Role/Custom
  DocPerm · `userperm_gen` row-level · `roleprofile_gen` bundles portail ·
  `apply_plan` run-book unifié) = **60 tests** (10+11+12+11+16) ;
- `fiscal/ecf_dgii/` (Sprint 4 · L51) — **e-CF DGII (Compupar)** : plan de
  facturation électronique + composeur d'e-NCF traçable = **39 tests**.

**Doc réelle produite** : tableau des 6 modules (module/sprint/rôle/CLI/job CI/
tests), section hand-off reçus (ordre d'import CRM DocType→Workflow→commissions +
chat OTOIA / Workspaces Frontend), section anti-invention (#6 · RNC/ITBIS/
TipoCambio/taux commission `null`, USD+DOP/Letter US/Cardnet cités non réinventés),
coordination inter-agents, non-négociables.

**Vérifs** : 11/11 chemins référencés existent + 6/6 jobs CI existent (**0 lien
mort**) ; 3 gardes CI locales vertes (guard contraintes · check_docs liens internes
OK · validate_json). Repo : **560 tests** au total gated.

**Hors périmètre worker (VPS · #8)** : application réelle des fixtures RBAC/e-CF
(`bench migrate`, import, connexion proveedor Compupar) reste l'acte serveur.

**Auto-score 4Big** : 96/100.

## Session `20260730_142804` (session 29)

**Tâche** : **Sprint 8 · buffer L75 (corrections finales · doc)** — Aucun module
roadmap ne reste à créer. Poursuite de la remédiation stub→doc réelle (sessions 25
QA, 26 CRM, 27 DevOps, 28 SEO) sur le **prochain agent le plus sous-documenté vs ce
qu'il a livré**.

**Gap comblé** : `03_agents/frontend_console/AGENT.md` était le **stub générique de
32 lignes** alors que l'agent **Frontend Console a livré deux générateurs
substantiels** dans `05_deliverables_mvp/frontend/` :
- `portails/` (Sprint 4 · L49) — **5 `Workspace` ERPNext natifs v15**, un par
  portail rôle métier (Ventes/Construction/Achat/Compta/Direction) ;
- `chat_otoia/` (Sprint 6 · L63) — **5 `Custom Block` natifs** montant l'assistant
  OTOIA (persona Amélie QC) dans chaque portail.
La doc ne reflétait rien de la réalité livrée.

**Fichier modifié** :
- `03_agents/frontend_console/AGENT.md` : réécrit (stub → doc réelle, ~120 lignes,
  même format que SEO/CRM/QA/DevOps). Table des **2 modules** (sortie · métrique
  vérifiée), CLI `workspaces_gen.py` / `chat_otoia_gen.py`, jobs CI
  `frontend-portails-tests` + `chat-otoia-tests`, principe **ERPNext natif d'abord**
  (Workspace/Custom Block, pas de dashboard externe · #1), hand-off VPS / pas
  d'écriture serveur (#8), **source de vérité unique** (`rbac_50_roles.json`),
  anti-invention détaillée (`endpoint`/`module` = `null a_confirmer`, couverture
  bijective des DocTypes), réutilisation validateur/branding Publiciste + builder
  `wslib` (#5), coordination inter-agents, spec attribuée `/choisir-mon-unite`.

**Anti-invention (#6)** : **zéro chiffre fabriqué** — toutes les métriques reprises
telles quelles des livrables vérifiés (READMEs + CI + suites de tests) :
Workspaces **4/11/12 · 4/9/10 · 3/8/5 · 4/11/8 · 4/14/9** (cartes/liens/rôles par
portail), **12 invariants / 19 tests** (portails), **14 invariants / 31 tests**
(chat), `plateforme` exclu (5 portails métier exacts), `endpoint`/`module` laissés
`null · a_confirmer`.

**Vérifs** : suites frontend **50/50 vertes** (19 portails + 31 chat) ; gate CI
local vert (`check_docs.sh` liens internes OK · `guard_constraints.sh` contraintes
NON-NÉGOCIABLES OK, exit 0).

**Hors périmètre worker (VPS · #8)** : import des fixtures (`bench migrate`),
insertion des `Custom Block` dans le `content` des Workspaces, câblage de l'endpoint
OTOIA + application du thème desk dark+doré → agent ERPNext Backend / Frontend.

**Auto-score 4Big** : 96/100.

## Session `20260730_135801` (session 28)

**Tâche** : **Sprint 8 · buffer L75 (corrections finales · doc)** — Aucun module
roadmap ne reste à créer. Poursuite de la remédiation stub→doc réelle (sessions 25
QA, 26 CRM, 27 DevOps) sur le **prochain agent le plus sous-documenté vs ce qu'il a
livré**.

**Gap comblé** : `03_agents/seo/AGENT.md` était le **stub générique de 29 lignes**
alors que l'agent **SEO a livré un bundle trilingue substantiel** :
`05_deliverables_mvp/seo/` (Sprint 6 · roadmap L60 — mots-clés FR/EN/ES,
`schema.org` JSON-LD, `hreflang`). La doc ne reflétait rien de la réalité livrée.

**Fichier modifié** :
- `03_agents/seo/AGENT.md` : réécrit (stub → doc réelle, ~95 lignes, même format que
  CRM/QA/DevOps). Table des **3 volets** (sortie · métrique vérifiée), CLI
  `seo_gen.py build|validate`, job CI `seo-tests`, principe hand-off VPS / pas
  d'écriture serveur (#8), **source de vérité unique** (`projets_master.json` du
  Publiciste), anti-invention détaillée, réutilisation du validateur/lexique
  Publiciste (#5), coordination inter-agents.

**Anti-invention (#6)** : **zéro chiffre fabriqué** — métriques reprises telles
quelles du livrable vérifié : **258 mots-clés** (fr=87 · en=87 · es=84), **10 nœuds**
schema.org (Organization + 9 Residence), **10 pages** hreflang, **offers=0**
(aucun projet `disponible` avec prix sourcé), **36 tests**. Rappel de la règle :
un mot-clé ne porte que les chiffres présents dans son champ projet source ;
`schema.org` n'émet un prix que pour un statut `disponible` avec `prix_depuis_usd`
numérique sourcé (USD · #10).

**Vérifs** : `python3 seo_gen.py validate` vert (258 mots-clés · 9 listings · 10
pages hreflang · schéma + 15 invariants) ; `python3 -m unittest discover -s tests`
= **36/36 verts** ; `ci/guard_constraints.sh` vert (6 familles d'interdits) ;
`ci/check_docs.sh` vert (liens internes OK · aucun lien mort).

**Hors périmètre worker (VPS · #8)** : injection des balises `<link hreflang>` /
`<script JSON-LD>` dans les pages `www/`, génération + soumission `sitemap.xml` et
Google Search Console → agent Frontend/SEO.

**Auto-score 4Big** : 96/100.

## Session `20260730_132801` (session 27)

**Tâche** : **Sprint 8 · buffer L75 (corrections finales · doc)** — Aucun module
roadmap ne reste à créer. Poursuite de la remédiation stub→doc réelle (sessions 25
QA, 26 CRM) sur le **prochain agent le plus sous-documenté vs ce qu'il a livré**.

**Gap comblé** : `03_agents/devops/AGENT.md` était le **stub générique de 29 lignes**
alors que l'agent **DevOps a livré 2 volets substantiels** : le **gate CI Gitea
Actions** (`.gitea/workflows/ci.yml` + `ci/` guards · Sprint 1 · roadmap L29) et le
**run-book VPS unifié** (`devops/deploy_runbook/` · Sprint 8 · roadmap L73). La doc
ne reflétait rien de la réalité livrée.

**Fichier modifié** :
- `03_agents/devops/AGENT.md` : réécrit (stub → doc réelle, ~90 lignes). Table des
  **2 livrables DevOps** (sprint · rôle · entrée · nb suites/tests — tous **sourcés**
  depuis le CI réel et le README run-book), détail des **3 guards blocants**
  (`guard_constraints`/`validate_json`/`check_docs`), principe gate-en-repo /
  application-côté-serveur (#8), périmètre **bijectif prouvé vs CI** (anti-omission),
  anti-invention (**confirmations sourcées, zéro chiffre**), coordination inter-agents.

**Anti-invention (#6)** : **zéro chiffre fabriqué** — **22 suites gated** comptées
depuis `grep` des jobs de `ci.yml` (jobs `*-tests`) ; **29 tests** repris du README
`deploy_runbook` ; le **compte total de tests délégué à `qa/regression`** (source
unique · jamais recopié) ; confirmations VPS (`taux_commission`, `rnc_emisor`,
`itbis_tipocambio`, `seuil_uaf`, `endpoint_otoia`…) citées avec owner + source.

**Vérifs** : `ci/guard_constraints.sh` vert (6 familles d'interdits) ;
`ci/check_docs.sh` vert (liens internes OK · aucun lien mort · AGENT.md hors
périmètre du SOFT-check 4Big) ; aucun `[..](..)` ajouté → zéro risque de lien mort.

**Hors périmètre worker (VPS · #8)** : exécution réelle du run-book sur le VPS
(bench migrate, imports, câblage nginx/systemd, vérifs HTTP) → agent DevOps/ERPNext.

**Auto-score 4Big** : 96/100.

## Session `20260730_125754` (session 26)

**Tâche** : **Sprint 8 · buffer L75 (corrections finales · doc)** — Aucun module
roadmap ne reste à créer (recette `qa/acceptance` : 15/15 promesses `in_repo`,
seule M5 « 2 stores » hors périmètre worker · #8). Tâche buffer conforme au mandat
(« améliore la doc d'un AGENT.md existant ») : poursuite de la remédiation entamée
session 25 (QA) sur le **prochain agent le plus sous-documenté vs ce qu'il a livré**.

**Gap comblé** : `03_agents/crm/AGENT.md` était le **stub générique de 29 lignes**
alors que l'agent **CRM a livré 3 modules substantiels** au Sprint 4
(`workflow_vente`, `dossier_vente`, `commissions`). La doc ne reflétait rien de la
réalité livrée (même écart que QA en session 25).

**Fichier modifié** :
- `03_agents/crm/AGENT.md` : réécrit (stub → doc réelle, ~90 lignes). Table des
  **3 livrables CRM** (sprint · rôle · **entrée CLI** · **job CI** · **nb tests** —
  tous **sourcés** depuis les modules réels + le CI), principe hand-off VPS (jamais
  d'écriture serveur · #8), cross-cohérence source-unique (`workflow_vente_spec.json`
  + `rbac_50_roles.json`), anti-invention (**taux commission `null`**), mise en avant
  #3 (CRM = ERPNext natif · JAMAIS EspoCRM/HubSpot), coordination inter-agents.

**Anti-invention (#6)** : **zéro chiffre fabriqué** — 25/31/25 = **81 tests**
comptés par `grep -c 'def test_'` ; jobs CI et sous-commandes `build`/`validate`
vérifiés par `grep` ; deliverables Sprint 4 cités depuis roadmap L51 ; USD+DOP /
Letter US cités depuis CLAUDE.md #10.

**Vérifs** : `ci/guard_constraints.sh` vert ; `ci/check_docs.sh` vert (liens
internes OK · aucun lien mort) ; 0 référence `ROADMAP_8_WEEKS.md` (non régressé).

**Hors périmètre worker (VPS · #8)** : néant (changement doc-only en-repo).

**Détail complet** : voir
[`05_deliverables_mvp/daily_reports/2026-07-30-session26.md`](../05_deliverables_mvp/daily_reports/2026-07-30-session26.md).

**Auto-score 4Big** : 95/100.

## Session `20260730_122751` (session 25)

**Tâche** : **Sprint 8 · buffer L75 (corrections finales · doc)** — Toutes les
promesses roadmap sont désormais prouvées en-repo (recette `qa/acceptance` :
15/15 `in_repo`, seule M5 « app publiée 2 stores » reste hors périmètre worker).
Aucun module roadmap restant à créer. La tâche buffer à plus forte valeur, conforme
au mandat (« améliore la doc d'un AGENT.md existant ») : **corriger + étoffer la
documentation agent**.

**Gap comblé (2 défauts réels)** :
1. **Référence roadmap cassée** dans **11 fichiers** `03_agents/*/AGENT.md` : ils
   pointaient vers `04_roadmap/ROADMAP_8_WEEKS.md` (**inexistant**) au lieu de
   `04_roadmap/ROADMAP_8_WEEKS_OR_LESS.md` (le vrai fichier, référencé partout
   ailleurs). Lien mort → corrigé sur les 11.
2. **`03_agents/qa/AGENT.md` était un stub de 29 lignes** alors que l'agent QA a
   livré **4 modules de méta-niveau** substantiels (`audit_5d`, `audit_4big`,
   `regression`, `acceptance`) ; la doc ne reflétait pas la réalité livrée.

**Fichiers modifiés** :
- `03_agents/qa/AGENT.md` : réécrit (stub → doc réelle). Table des 4 livrables QA
  (sprint · rôle · **entrée CLI** · **job CI** · **nb tests** — tous **sourcés**
  depuis les modules réels), principe méta-niveau (ISA 315 · SoD), verdict agrégé
  courant (**21 suites · 534 tests · PASS**, cité depuis
  `qa/regression/out/regression_run.json`), invariants anti-invention, coordination.
- `03_agents/{bim,crm,devops,erpnext_backend,frontend_console,ifc_speckle,mobile,onapi_legal,rendu,seo}/AGENT.md`
  + `qa` : correction du lien roadmap cassé (11 fichiers).

**Anti-invention (#6)** : **zéro chiffre fabriqué** — chaque nombre de la doc QA
est soit un compte réel (`grep def test_`, `regression_run.json`), soit une citation
de la roadmap ; aucune donnée métier inventée.

**Vérifs** : `ci/guard_constraints.sh` vert (contraintes non-négociables OK) ;
`ci/check_docs.sh` vert (**liens internes OK** — plus aucun lien mort) ;
0 référence `ROADMAP_8_WEEKS.md` restante ; 11 fichiers pointent bien vers le fichier
existant.

**Hors périmètre worker (VPS · #8)** : néant (changement doc-only en-repo).

**Détail complet** : voir
[`05_deliverables_mvp/daily_reports/2026-07-30-session25.md`](../05_deliverables_mvp/daily_reports/2026-07-30-session25.md).

**Auto-score 4Big** : 95/100.

## Session `20260730_115744` (session 24)

**Tâche** : **Sprint 8 · QA (buffer L75 · recette)** — Générateur de la **Matrice
d'acceptation / traçabilité MVP**. Sprint 8 étant le dernier (déploiement VPS réel
hors périmètre worker · #8), le volet réalisable en-repo restant est la
**recette** : mapper chaque **promesse** roadmap (8 livrables de sprint L33..L76 +
7 métriques succès MVP L81..L87) vers sa **preuve** livrée OU un hors-périmètre
worker sourcé. Consolidation naturelle du « DELIVERABLE MVP » (L76) + métriques
succès (L80-87).

**Gap comblé** : aucun artefact ne traçait les promesses roadmap → livrables ; les
preuves étaient éparpillées (gap analysis + 23 rapports) sans vue bijective ni
recensement des parties hors périmètre worker.

**Décision d'architecture** : harnais de **MÉTA-NIVEAU** orienté RECETTE, **axe
distinct** des 4 autres méta (non redondant · #5) — `audit_4big` note la qualité
statique · `regression` prouve l'exécution · `deploy_runbook` ordonne le
déploiement · **`acceptance`** prouve la **couverture des promesses** roadmap.

**Anti-invention (cœur · #6)** : périmètre **PROUVÉ** — modules-preuve **dérivés
du CI** (`q4lib.registry.parse_ci`, réutilisé · zéro duplication) et confrontés de
façon **BIJECTIVE** (module gated non tracé OU preuve non gated → refus ; la
validation **recalcule** depuis le CI) ; **cross-cohérence** : fenêtre de sprint
**lue** dans le registre 4Big (anti-dérive), l'auditeur (SoD) via
`extra_module_sprint` sourcé ; **partition exacte** par sprint ; **zéro chiffre
fabriqué** (les nombres des énoncés `<1h`/`95/100`/`7 dashboards`/`2 stores` sont
des **citations verbatim** de la roadmap) ; tout hors-périmètre **sourcé** ;
**SoD** : la matrice ne se cite jamais elle-même.

**Fichiers créés** — `05_deliverables_mvp/qa/acceptance/` :
- `acceptance_spec.json` (8 livrables + 7 métriques · `roadmap_line` · hors-
  périmètre sourcé · **0 chiffre fabriqué**)
- `acclib/{__init__,deps,builder}.py` (`deps` réutilise `parse_ci` + validateur
  Publiciste + registre 4Big ; `builder` pur/déterministe)
- `acceptance_gen.py` (CLI `build`/`validate` · **10 familles d'invariants**)
- `acceptance.schema.json` (contrat draft-07)
- `out/{acceptance_matrix,MANIFEST}.json` (hand-off · verdict) ·
  `tests/test_acceptance.py` (**31 tests** dont 14 injections négatives) ·
  `README.md` · `.gitignore`

**Fichiers modifiés** :
- `.gitea/workflows/ci.yml` : job `qa-acceptance-tests` + ajout au `gate`.
- `qa/audit_4big/` : enregistrement du module (couverture bijective **20 → 21** ·
  PASS 21/21 à min 100) ; `out/` régénéré.
- `devops/deploy_runbook/` : `module_phase` +`qa/acceptance` (`verification-qa`) ;
  bijectif **20 → 21** ; `out/` régénéré.
- `qa/regression/out/` : plan régénéré (**20 → 21 suites** · découverte auto CI).

**Résultat** : matrice `verdict=true` — **15 promesses** (8 sprint + 7 métriques) ·
**21 modules gated tracés sans doublon** (bijectif) · **partition par sprint
exacte** · **12 hors-périmètre sourcés**.

**Vérifs** : 31/31 tests module ; validations méta vertes ; régression `run`
exhaustive **21/21 suites vertes · 534 tests passés · 0 échec · 0 erreur**
(503 → +31) ; gate CI local vert (guard + JSON + docs + YAML) ; build déterministe.

**Hors périmètre worker (VPS · #8)** : le module ne déploie rien — exécution réelle
(démo publique, run-book VPS, builds stores, indexation, voix Amélie) → agent
DevOps / direction.

**Détail complet** : voir
[`05_deliverables_mvp/daily_reports/2026-07-30-session24.md`](../05_deliverables_mvp/daily_reports/2026-07-30-session24.md).

**Auto-score 4Big** : 96/100.

## Session `20260730_112734` (session 23)

**Tâche** : **Sprint 8 · DevOps** — Générateur du **Run-book de déploiement VPS
unifié** (roadmap Sprint 8 · DevOps « **Deployment production complet +
monitoring** », L73). Dernier volet Sprint 8 réalisable en-repo ; le déploiement
réel reste hors périmètre worker (#8), mais le **PLAN** ordonné se produit en-repo.

**Gap comblé** : les étapes d'activation VPS de chaque générateur (« Hors
périmètre worker ») étaient **éparpillées dans 12 rapports**, sans ordre
inter-modules ni graphe de dépendances. Aucun artefact ne consolidait l'ordre de
déploiement des 20 livrables gated.

**Décision d'architecture** : agrégateur de **MÉTA-NIVEAU** au-dessus du run-book
RBAC (`rbac/apply_plan`). Il ordonne le déploiement de **TOUS** les livrables
gated en **7 phases** (Prérequis → DocTypes → RBAC → Workflow/métier → Frontend →
Contenu → Vérification QA), chacune avec responsable, rationale, modules assignés,
dépendances inter-phases (graphe acyclique) et confirmations préalables sourcées.

**Anti-invention (cœur · #6)** : périmètre **PROUVÉ** — l'ensemble des modules est
**dérivé du CI** via `q4lib.registry.parse_ci` (réutilisé · zéro duplication · #5)
et mis en correspondance **BIJECTIVE** avec le spec (un module gated non planifié
OU un module planifié non gated → génération refusée) ; la validation **recalcule**
la couverture depuis le CI. **SoD** (ISA 315) : le run-book s'exclut lui-même.
**Zéro chiffre métier** : les paramètres non confirmés restent des **confirmations
sourcées** (owner + source ; reprises des contrôles `audit_5d` D1.1/D1.2/D1.3/D2.3
+ endpoint OTOIA), jamais fabriquées ; un invariant refuse tout champ chiffré.

**Fichiers créés** — `05_deliverables_mvp/devops/deploy_runbook/` :
- `deploy_spec.json` (7 phases · `module_phase` des 20 modules · 7 confirmations
  sourcées · **0 chiffre**)
- `deploylib/{__init__,deps,builder}.py` (`deps` réutilise validateur Publiciste +
  `parse_ci` ; `builder` pur/déterministe)
- `deploy_runbook_gen.py` (CLI `build`/`validate` · **11 familles d'invariants**)
- `deploy.schema.json` (contrat draft-07)
- `out/{deploy_runbook,MANIFEST}.json` (hand-off) · `tests/test_deploy_runbook.py`
  (**29 tests** dont 14 injections négatives) · `README.md` · `.gitignore`

**Fichiers modifiés** :
- `.gitea/workflows/ci.yml` : job `devops-deploy-runbook-tests` + ajout au `gate`.
- `qa/audit_4big/` : enregistrement du module (couverture bijective **19 → 20** ·
  PASS 20/20 à 100) ; note count-agnostique ; `out/` régénéré.
- `qa/regression/out/` : plan régénéré (**19 → 20 suites**, découverte auto via CI).

**Résultat** : run-book `bijective=true` — **7 phases · 20 modules couverts sans
doublon · 7 confirmations sourcées** · graphe acyclique.

**Vérifs** : 29/29 tests module ; 34/34 audit_4big (PASS 20/20 à 100) ; régression
`run` exhaustive **20/20 suites vertes · 503 tests passés · 0 échec · 0 erreur**
(474 → +29) ; gate CI local vert (guard + JSON + docs + YAML) ; build déterministe.

**Hors périmètre worker (VPS · #8)** : exécuter le plan sur le VPS (modules/DocTypes
custom, imports, Workflows, 7 confirmations, vérifs HTTP + audits desk réel) →
agent DevOps / ERPNext Backend.

**Détail complet** : voir
[`05_deliverables_mvp/daily_reports/2026-07-30-session23.md`](../05_deliverables_mvp/daily_reports/2026-07-30-session23.md).

**Auto-score 4Big** : 96/100.

## Session `20260730_105732` (session 22)

**Tâche** : **Sprint 8 · QA** — Générateur de la **Matrice de régression
exhaustive** (roadmap Sprint 8 · QA « **Regression tests exhaustifs** »). Sprint 7
réalisable en repo étant clos (L68/L69 livrés · L67 polish `otov7.com` dépend du
site live · #8), on enchaîne sur le premier volet Sprint 8 réalisable en repo.

**Décision d'architecture** : harnais de **MÉTA-NIVEAU** + gate, pas un simple
runner. Il agrège l'exécution de **toutes** les suites gated en **une matrice +
verdict PASS/FAIL** et fournit le **compte agrégé faisant autorité** (« N tests
verts »). **Distinct de l'audit 4Big** (non redondant · #5) : l'audit note la
qualité **statique** par module ; ce harnais prouve que chaque suite **s'exécute
au vert**. Deux artefacts : `build` → plan déterministe commité (**aucun compteur
de résultat**) ; `run` → matrice live non déterministe (non commitée).

**Zéro invention (#6)** : périmètre **dérivé du CI** via `q4lib/registry.parse_ci`
(réutilisé · zéro duplication) ; les comptes de disque sont **recomputés** à la
validation (INV5) → un compte figé/fabriqué est détecté ; le nombre de tests verts
n'existe **qu'à l'exécution**. **Séparation des pouvoirs (ISA 315)** : le harnais
s'exclut lui-même (pas de récursion, pas d'auto-comptage).

**Fichiers créés** — `05_deliverables_mvp/qa/regression/` :
- `regression_spec.json` (contrat · planchers structurels · 0 chiffre métier)
- `reglib/{__init__,deps,discovery,runner,builder}.py` (réutilise `parse_ci` +
  validateur Publiciste ; parseur PUR de sortie unittest ; plan + matrice)
- `regression_gen.py` (CLI `build`/`validate`/`run` · **8 invariants**)
- `regression.schema.json` (contrat de sortie draft-07)
- `out/{regression_plan,MANIFEST}.json` (hand-off) · `tests/test_regression.py`
  (**24 tests** dont 3 exécutions réelles en tmpdir + 6 injections d'invariant) ·
  `README.md` · `.gitignore` (exclut la sortie non déterministe de `run`)

**Fichiers modifiés** :
- `.gitea/workflows/ci.yml` : job `qa-regression-tests` + ajout au `gate`.
- `qa/audit_4big/` : enregistrement du module `qa/regression` (couverture
  bijective **18 → 19 modules** · PASS 19/19 à 100) ; `out/` régénéré ; test
  rendu robuste (`len(spec['modules'])` au lieu du littéral `18`).

**Résultat `run` exhaustif** : **19/19 suites vertes · 474 tests passés · 0 échec ·
0 erreur** — compte agrégé reproductible en une commande.

**Vérifs** : 24/24 tests module ; 34/34 audit_4big ; gate CI local vert (guard +
JSON + docs + YAML) ; builds déterministes.

**Hors périmètre worker (VPS · #8)** : planifier `run` sur le runner CI/VPS +
publier le compte agrégé dans le desk ERPNext → agent QA / DevOps.

**Détail complet** : voir
[`05_deliverables_mvp/daily_reports/2026-07-30-session22.md`](../05_deliverables_mvp/daily_reports/2026-07-30-session22.md).

**Auto-score 4Big** : 96/100.

## Session `20260730_102730` (session 21)

**Tâche** : **Sprint 7 · CRM + Faisabilité** — Générateur des **Scénarios démo
(run-sheet de pitch)** (roadmap **l.68** « CRM + Faisabilité : Scénarios démo
(**P07 pitch banquier · P05 client ready**) »). Dernier volet Sprint 7 réalisable
en repo — le polish `otov7.com` (Frontend) et le branchement au `data_room` réel
dépendent du site live / archives serveur (hors périmètre worker · #8).

**Décision d'architecture** : **orchestrateur de méta-niveau**, pas du contenu
marketing écrit à la main. Un scénario = suite de **beats** ; chaque beat cite une
**preuve** = un **pointeur RFC 6901** vers un hand-off `out/` d'un module déjà
livré, **résolu à la construction**. Zéro chiffre dans le spec ; une valeur
introuvable devient un placeholder `{{module:file#pointer}}`, jamais un `0`
fabriqué (#6). Zéro duplication (#5) : réutilise le validateur Publiciste **et** la
preuve de couverture CI de l'auditeur 4Big (`q4lib/registry.py`) — une démo ne
s'appuie QUE sur des modules **gated**.

**Fichiers créés** — `05_deliverables_mvp/demo/scenarios/` :
- `scenario_spec.json` (2 scénarios · 12 beats · 23 pointeurs · 0 chiffre en dur)
- `scenlib/{__init__,deps,evidence,builder}.py` (résolveur RFC 6901 + assemblage
  déterministe · anti-invention)
- `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` + `tests/` + `out/` : enregistrement du module
  `demo/scenarios` (couverture bijective **17 → 18 modules** · verdict **PASS
  18/18 à 100**). L'auditeur DOIT tracer chaque nouveau livrable, sinon sa preuve
  de couverture rougit.

**Anti-invention (cœur · #6)** : `_check_anti_invention` **re-résout
indépendamment** chaque pointeur depuis le disque et compare au run-sheet ; un
`null` amont est traité comme non résolu (jamais promu en chiffre de pitch).

**Résultat** : run-sheet `pret=true` — **2 scénarios · 12 beats · 23/23 citations
résolues · 10 modules cités tous gated**.

**Vérifs** : 32/32 tests module ; 34/34 audit_4big ; régression **474 tests verts**
(442 → +32) · 0 module en échec ; guards CI locaux verts ; `ci.yml` YAML valide ;
builds déterministes.

**Hors périmètre worker (VPS · #8)** : rendu jouable (deck / prompteur / page démo
`otov7.com`) + branchement `data_room` réel → agent Frontend / DevOps.

**Détail complet** : voir
[`05_deliverables_mvp/daily_reports/2026-07-30-session21.md`](../05_deliverables_mvp/daily_reports/2026-07-30-session21.md).

**Auto-score 4Big** : 96/100.

## Session `20260730_095728` (session 20)

**Tâche** : **Sprint 7 · QA** — Générateur de l'**Audit 4Big qualité** (roadmap
**L69** « QA : **Audit 4Big niveau 95+/100 sur 100% deliverables** »). Premier
volet Sprint 7 réalisable en repo — les volets polish `otov7.com` (Frontend) et
scénarios démo P07/P05 (CRM+Faisabilité) dépendent du site live / `data_room`
réelle (hors périmètre worker · #8).

**Décision d'architecture** : audit de **MÉTA-NIVEAU** et **gate** (pas rapport
indicatif). Il note la qualité 4Big de **100 % des livrables** et **bloque**
(verdict `FAIL`) si un module tombe sous **95/100** (CLAUDE.md #5) ou si la
couverture est incomplète. La couverture est **prouvée, pas déclarée** : le
registre est recoupé **bijectivement** avec les `working-directory` du CI Gitea,
moins l'auditeur lui-même (**séparation des pouvoirs** · ISA 315). 5 critères
déterministes : `DOC` · `CONTRAT` (schema) · `TESTS` (≥8 méthodes) · `CLI`
(argparse+`__main__`) · `HANDOFF` (`out/` intègre), renormalisés par archétype.

**Fichiers créés** — `05_deliverables_mvp/qa/audit_4big/` :
- `quality_spec.json` (rubrique 5 critères + poids · seuil 95 verbatim · 4
  archétypes · registre 17 modules sourcés)
- `q4lib/{__init__,deps,registry,criteria,scoring,builder}.py` (`deps`
  **réutilise** le validateur maison Publiciste · `registry` parse `ci.yml` et
  prouve la couverture · `criteria` purs lus depuis le dépôt · `scoring`
  renormalise par archétype · `builder` déterministe)
- `audit_4big_gen.py` (CLI `build`/`validate` · **9 familles d'invariants**)
- `quality.schema.json` (contrat de sortie draft-07)
- `out/{quality_report,MANIFEST}.json` (hand-off) · `tests/test_audit_4big.py`
  (**34 tests** dont 15 injections négatives sur arbre synthétique) · `README.md`
  · `.gitignore`

**Fichiers modifiés** :
- `.gitea/workflows/ci.yml` : job `qa-audit-4big-tests` + ajout au `gate`.

**Anti-invention (cœur · #6)** : une note **ne peut pas être fabriquée « pour
faire 95 »** — elle est **recalculée** depuis des faits (fichiers, taille,
comptage `test_*`, validité JSON du hand-off) ; un invariant re-somme les poids et
recompute chaque note (`INV6`) ; l'auditeur est **hors de son propre périmètre**
(SoD · `INV4`) ; seuil 95 repris verbatim de CLAUDE.md #5.

**Résultat** : verdict `PASS` — **17/17 modules à 100/100** · pass-rate 100 % ·
couverture 100 % des livrables gated. Valeur = **gate anti-régression** (15 tests
négatifs prouvent la chute sous 95 en cas de dégradation).

**Vérifs** : 34/34 tests ; gate CI local vert (guard + JSON + docs + YAML) ;
régression **442 tests verts** au total (408 → +34) ; build déterministe.

**Hors périmètre worker (VPS · #8)** : publication du rapport dans le desk ERPNext
+ branchement du gate 4Big sur le pipeline de release VPS → agent QA / DevOps.

**Détail complet** : voir
[`05_deliverables_mvp/daily_reports/2026-07-30-session20.md`](../05_deliverables_mvp/daily_reports/2026-07-30-session20.md).

**Auto-score 4Big** : 96/100.

## Session `20260730_092724` (session 19)

**Tâche** : **Sprint 6 · ERPNext Backend** — Générateur du **Chat OTOIA embarqué
par portail** (roadmap **L63** « ERPNext Backend : **Chat OTOIA embedded dans chaque
portail** »). Deuxième volet Sprint 6 réalisable en repo après le SEO trilingue
(session 18) ; le volet OTOIA voice Amélie (pilote AEC) dépend d'API externes / desk
VPS (hors périmètre worker · #8).

**Décision d'architecture (#1 ERPNext natif)** : dans ERPNext v15, un bloc de contenu
réutilisable inséré dans un `Workspace` **EST** le DocType `Custom Block` → on livre
**un `Custom Block` par portail** (un `<div>` de montage) + la **config runtime**
(`chat_mount.json`), pas de framework de chat externe. Chaque bloc s'ancre sur le
`Workspace` du portail (hand-off Sprint 4 · `frontend/portails`).

**Fichiers créés** — `05_deliverables_mvp/frontend/chat_otoia/` :
- `chat_spec.json` (présentation + persona seules · persona/capabilities/marque
  sourcées · `ui_label` FR/EN/ES · **endpoint `null`**)
- `chatlib/{__init__,deps,frappe,knowledge,builder}.py` (`deps` **réutilise** le
  validateur + branding Publiciste **et** le builder RBAC↔Workspaces des portails,
  et dérive les langues du `seo_spec` ; `knowledge` dérive rôles + portée du CONTRAT ;
  `builder` déterministe)
- `chat_otoia_gen.py` (CLI `build`/`validate` · **14 invariants**)
- `chat.schema.json` (contrat de sortie draft-07)
- `out/{custom_block,chat_mount,MANIFEST}.json` (hand-off) · `tests/test_chat_otoia.py`
  (**31 tests** dont 11 injections négatives) · `README.md` · `.gitignore`

**Fichiers modifiés** :
- `.gitea/workflows/ci.yml` : job `chat-otoia-tests` + ajout au `gate`.

**Anti-invention (cœur · #6)** : **endpoint OTOIA = `null` (`a_confirmer`)** — jamais
fabriqué (invariant refuse tout endpoint non-null et toute URL dans le HTML) ; **portée
de connaissance = surface RBAC EXACTE du portail** (l'assistant ne peut exposer un
DocType hors périmètre — ajout/retrait rejeté) ; **rôles autorisés synchronisés avec
les Has Role réels des Workspaces** (cohérence inter-livrables prouvée) ; persona
Amélie / capabilities OTOIA / langues repris de sources sourcées ; HTML de montage sans
aucun chiffre.

**Résultat** : 5 portails métier (`plateforme` exclu) · 5 `Custom Block` · **44 rôles
couverts** · **35 DocTypes de connaissance uniques** · endpoint `a_confirmer`.

**Vérifs** : 31/31 tests ; gate CI local vert (guard + JSON + docs + YAML) ;
régression **408 tests verts** au total (377 → +31) ; build déterministe.

**Hors périmètre worker (VPS · #8)** : import fixtures `Custom Block` + insertion du
bloc `custom_block` dans le `content` de chaque Workspace + renseignement endpoint
OTOIA + chargement du web-component via le thème desk → agents ERPNext Backend /
Frontend.

**Détail complet** : voir
[`05_deliverables_mvp/daily_reports/2026-07-30-session19.md`](../05_deliverables_mvp/daily_reports/2026-07-30-session19.md).

**Auto-score 4Big** : 96/100.

## Session `20260730_085719` (session 18)

**Tâche** : **Sprint 6 · SEO** — Générateur **SEO trilingue** (roadmap L60 :
« Refactor mission `seo_autonome/` → **200+ mots-clés FR/EN/ES · schema.org ·
hreflang** »). Premier volet Sprint 6 réalisable en repo — les volets OTOIA voice
Amélie (pilote AEC) et chat OTOIA embarqué dépendent d'API externes / desk VPS
(hors périmètre worker · #8).

**Décision d'architecture** : livrable de **second niveau** — la matière première
est **`projets_master.json`**, la sortie canonique du **Publiciste** (dérivée de
`data_room/PXX/`). Le générateur ne fabrique aucun fait de projet ; il **réutilise**
(zéro duplication · #5) le validateur maison + les tokens de marque du Publiciste
(`lib/validator.py`, `lib/branding.py`).

**Fichiers créés** — `05_deliverables_mvp/seo/` :
- `seo_spec.json` (config site + **lexique éditorial générique** FR/EN/ES + org
  schema.org + cibles · zéro donnée projet, zéro chiffre)
- `seolib/{__init__,deps,keywords,schemaorg,hreflang,builder}.py` (`deps` réutilise
  validateur + branding Publiciste ; `keywords`/`schemaorg`/`hreflang` purs et
  déterministes ; `builder` assemble bundle + manifeste)
- `seo_gen.py` (CLI `build`/`validate` · **15 invariants**)
- `seo.schema.json` (contrat de sortie draft-07)
- `fixtures/projets_master.json` (test only · 9 projets P01..P09, noms sourcés
  `CLAUDE.md §Projets`, tous `en_developpement`, **zéro chiffre**)
- `out/{seo_keywords,seo_schema_org,seo_hreflang,MANIFEST}.json` (hand-off) ·
  `tests/test_seo.py` (**36 tests** dont 8 injections négatives) · `README.md` ·
  `.gitignore`

**Fichiers modifiés** :
- `.gitea/workflows/ci.yml` : job `seo-tests` + ajout au `gate`.

**Anti-invention (cœur · #6)** : un mot-clé = composition de tokens factuels
(`projet:<code>.nom`/`.localisation`, sourçables) + lexique éditorial générique
non chiffré (`lexicon:*`) ; un invariant vérifie que chaque mot-clé est sourcé et
résoluble ; un mot-clé ne peut porter que les chiffres de son champ source
(« 1069 Crisfer » passe ; un prix injecté est refusé). schema.org n'émet un prix
que pour un projet `disponible` à typologie **sourcée** (USD · #10) — la fixture
`en_developpement` produit donc **0 offre**, aucun chiffre inventé dans le hand-off.

**Résultat** : **258 mots-clés** (fr=87 · en=87 · es=84 · cible 200 dépassée) ·
schema.org 10 nœuds (1 Organization + 9 Residence) · hreflang 10 pages (accueil +
9 projets) × 4 alternates (FR/EN/ES + x-default).

**Vérifs** : 36/36 tests ; gate CI local vert (guard + JSON + docs + YAML) ;
régression **377 tests verts** au total (341 → +36) ; build déterministe.

**Hors périmètre worker (VPS · #8)** : injection balises hreflang/JSON-LD dans
`www/` + sitemap + Google Search Console + branchement sur la vraie sortie
Publiciste (9 projets réels) → agent SEO / Frontend.

**Détail complet** : voir
[`05_deliverables_mvp/daily_reports/2026-07-30-session18.md`](../05_deliverables_mvp/daily_reports/2026-07-30-session18.md).

**Auto-score 4Big** : 96/100.

## Session `20260730_082714` (session 17)

**Tâche** : **Sprint 5 · QA** — Générateur de l'**Audit 5D de conformité**
(roadmap Sprint 5 · QA « **Audit UAF + normes ISA/IFRS 5D** »). Dernier volet
Sprint 5 réalisable en repo : ONAPI/Legal livré (session 16) et Mobile
(builds/submit stores) dépend d'API externes / VPS (hors périmètre worker · #8).

**Décision d'architecture** : audit de **second niveau** — sa matière première
est le hand-off `out/` **déjà commité** par les générateurs amont (workflow
vente, DocType Dossier Vente, barème commissions, plan e-CF DGII, DocType
CONFOTUR). Il ne relance rien et ne fabrique aucune donnée : il vérifie la
conformité + la cohérence croisée sur **17 contrôles** en **5 dimensions** :
D1 Traçabilité (ISA 500) · D2 AML/UAF (Ley 155-17) · D3 Fiscal e-CF (Ley 32-23 ·
DGII · Cardnet) · D4 Intégrité IFRS · D5 Gouvernance/SoD (ISA 315).

**Fichiers créés** — `05_deliverables_mvp/qa/audit_5d/` :
- `audit_spec.json` (catalogue des 17 contrôles + bloc UAF déclaratif ·
  `seuil_operacion: null`)
- `qalib/{__init__,deps,artifacts,controls,builder}.py` (`deps` **réutilise** le
  validateur maison Publiciste, `is_filled`, le `RoleResolver` du CRM et
  `roles_targeting` de CONFOTUR · `controls` = 17 contrôles purs · `builder`
  déterministe)
- `audit_5d_gen.py` (CLI `build`/`validate` · **15 invariants**)
- `audit.schema.json` (contrat de sortie draft-07)
- `out/{audit_report,MANIFEST}.json` (hand-off) · `tests/test_audit_5d.py`
  (**37 tests** · une injection négative par contrôle) · `README.md` · `.gitignore`

**Fichiers modifiés** :
- `.gitea/workflows/ci.yml` : job `qa-audit-5d-tests` + ajout au `gate`.

**Anti-invention (cœur · #6)** : l'audit **remonte, ne fabrique pas**. Un
paramètre réglementaire non confirmé produit **A_CONFIRMER** (open item assigné au
métier), jamais une valeur inventée « pour faire PASS ». **FAIL** = incohérence
inter-livrables OU valeur chiffrée **sans `source`**. Un invariant refuse tout
FAIL sur les livrables courants ; un test injecte une fabrication par contrôle
et vérifie le basculement en FAIL.

**Résultat** : verdict `PASS_WITH_OPEN_ITEMS` — **13 PASS · 0 FAIL · 4 à
confirmer** (D1.1 taux → Direction ; D1.2 RNC émetteur → Compta ; D1.3
ITBIS/TipoCambio → Fiscaliste eCF ; D2.3 seuil UAF → Oficial de Cumplimiento).
Ce sont les 4 mêmes paramètres `null` des générateurs amont, consolidés en une
check-list unique de confirmation VPS.

**Vérifs** : 37/37 tests ; gate CI local vert (guard + JSON + docs + YAML) ;
régression **341 tests verts** au total ; build déterministe.

**Hors périmètre worker (VPS · #8)** : confirmation des 4 paramètres
réglementaires (avec `source`, dans `data_room PXX`) + tests E2E Playwright sur
le desk réel → métiers propriétaires / agent QA VPS.

**Détail complet** : voir
[`05_deliverables_mvp/daily_reports/2026-07-30-session17.md`](../05_deliverables_mvp/daily_reports/2026-07-30-session17.md).

**Auto-score 4Big** : 96/100.

## Session `20260730_075712` (session 16)

**Tâche** : **Sprint 5 · ONAPI/Legal** — Générateur du **DocType porteur
`CONFOTUR Application`** (roadmap **L55** « Refactor `oto_module_confotur_application.py`
→ dépôts automatiques »). Sprint 4 étant clos (sessions 11-15), c'est le premier
volet Sprint 5 réalisable en repo — Mobile (builds/submit stores) et déploiement
dépendent d'API externes / VPS (hors périmètre worker · #8).

**Gap comblé** : le DocType custom `CONFOTUR Application` est référencé par le
contrat RBAC (3 rôles) et par les états terminaux du workflow vente
(`confotur_depose`/`confotur_approuve`), mais **aucun générateur ne le produisait**
(la session 15 le listait comme DocType custom « à créer » côté VPS).

**Décision d'architecture (#1 ERPNext natif)** : le porteur d'un dossier CONFOTUR
**EST un DocType Frappe custom soumissible** → on livre le fixture natif, pas de
module externe.

**Fichiers créés** — `05_deliverables_mvp/legal/confotur/` :
- `confotur_spec.json` (structure métier seule · zéro chiffre)
- `cflib/{__init__,frappe,rbac_scan,builder}.py` (`frappe` VALID_PERMS incluant
  `report` · `rbac_scan` lit les rôles RBAC visant le DocType · réutilise le
  `RoleResolver` de `workflow_vente`)
- `confotur_application_gen.py` (CLI `build`/`validate` · **14 invariants**)
- `confotur.schema.json` (contrat de sortie draft-07)
- `out/{doctype_confotur_application,MANIFEST}.json` (hand-off) ·
  `tests/test_confotur.py` (**44 tests** dont 8 négatifs) · `README.md` · `.gitignore`

**Fichiers modifiés** :
- `.gitea/workflows/ci.yml` : job `legal-confotur-tests` + ajout au `gate`.

**Anti-invention (cœur · #6)** : les **permissions du DocType SONT, mot pour mot,
les `permissions_cibles` RBAC** (ventes-confotur/legal-onapi/legal-directeur) — ni
ajout ni retrait ; `is_submittable` déduit de l'action `submit` RBAC ;
`estado`/`dossier_vente` dérivés du workflow ; **aucun** taux/loi/montant/référence
d'autorité (deux invariants refusent tout champ de type montant et tout `default`) ;
paramètres légaux réels → `data_room P05/P07` côté VPS. Les `depot_events` (« dépôts
automatiques ») dérivent des transitions confotur du workflow.

**Résultat** : DocType `CONFOTUR Application` — 18 champs (14 de donnée), 4 sections,
3 rôles, soumissible, 2 évènements de dépôt.

**Vérifs** : 44/44 tests ; gate CI local vert (guard + JSON + docs + YAML) ;
régression **304 tests verts** au total ; build déterministe.

**Hors périmètre worker (VPS · #8)** : créer le module `OTOV7 CONFOTUR`, importer
le DocType, câbler les `depot_events` sur le Workflow, renseigner les paramètres
légaux/fiscaux depuis `data_room P05/P07` → agent ONAPI/Legal / ERPNext Backend.

**Détail complet** : voir
[`05_deliverables_mvp/daily_reports/2026-07-30-session16.md`](../05_deliverables_mvp/daily_reports/2026-07-30-session16.md).

**Auto-score 4Big** : 96/100.

## Session `20260730_072711` (session 15)

**Tâche** : Sprint 4 · Frontend Console — Générateur de **Workspaces ERPNext
(5 portails rôle)** (roadmap ligne 49 « 5 portails (Ventes/Construction/Achat/
Compta/Direction) » ; dernier volet ouvert de Sprint 4, les volets CRM et ERPNext
Backend ayant été livrés sessions 11-14).

**Décision d'architecture (#1 ERPNext natif)** : dans ERPNext v15, le portail de
landing par rôle **EST le DocType `Workspace`** → on livre 5 Workspaces natifs,
pas de framework de dashboard externe.

**Fichiers créés** — `05_deliverables_mvp/frontend/portails/` :
- `portails_spec.json` (mise en page seule : cartes/raccourcis/thème · aucun
  DocType ni rôle hors contrat)
- `wslib/{__init__,frappe,builder}.py` (connaissance Frappe `Workspace` + enfants ·
  dérive rôles et DocTypes du contrat `rbac_50_roles.json`)
- `workspaces_gen.py` (CLI `build`/`validate` · 12 invariants de cross-cohérence)
- `workspace.schema.json` (contrat de sortie draft-07)
- `out/{workspace,MANIFEST}.json` (hand-off) · `tests/test_workspaces.py`
  (19 tests dont 4 négatifs) · `README.md` · `.gitignore`

**Fichiers modifiés** :
- `.gitea/workflows/ci.yml` : job `frontend-portails-tests` + ajout au `gate`.

**Anti-invention (cœur · #6)** : la source de vérité est le contrat RBAC, jamais
la spec. Tout lien/raccourci vise un DocType présent dans les `permissions_cibles`
du portail (droit prouvé) ; couverture exhaustive sans doublon ; flag `custom`
issu du contrat ; aucun chiffre stocké (compteurs live du desk) ; tokens de marque
(`#0a0a12`/`#f0b429`/Fraunces/Cormorant) repris verbatim de CLAUDE.md #4 avec source.

**Résultat** : 5 Workspaces (Ventes/Construction/Achat/Compta/Direction), 44 rôles
restreints ; console technique `plateforme` exclue (roadmap = 5 portails métier).

**Vérifs** : 19/19 tests ; gate CI local vert (guard + JSON + docs + YAML) ;
régression **260 tests verts** au total ; build déterministe.

**Hors périmètre worker (VPS · #8)** : fixer `Workspace.module` à l'import + créer
les DocTypes custom (`CONFOTUR Application`, `Faisabilité`, `Publiciste Log`) +
appliquer le thème desk → agents ERPNext Backend / Frontend Console.

**Détail complet** : voir
[`05_deliverables_mvp/daily_reports/2026-07-30-session15.md`](../05_deliverables_mvp/daily_reports/2026-07-30-session15.md).

**Auto-score 4Big** : 96/100.

## Session `20260730_065711` (session 14)

**Tâche** : Sprint 4 · ERPNext Backend — Générateur de **configuration e-CF DGII
(Compupar)** (roadmap ligne 51 « e-CF DGII intégration (Compupar) » ; les
commissions ayant été livrées session 13, l'e-CF restait ouvert · GAP §Backend).

**Fichiers créés** — `05_deliverables_mvp/fiscal/ecf_dgii/` :
- `ecf_spec.json` (catalogue 10 types e-CF DGII · table FormaPago · format e-NCF ·
  moneda USD/DOP · RNC/ITBIS/TipoCambio `null` · provider Compupar · 2 évènements
  d'émission · `field_map` Dossier Vente → e-CF)
- `ecflib/{__init__,deps,ncf,builder}.py` (réutilise `is_filled`/`CANONICAL`/
  `validate` + `RoleResolver` du module `workflow_vente` · composeur e-NCF
  traçable `E+tipo(2)+seq(10)` façon `finance.py`)
- `ecf_dgii_gen.py` (CLI `build`/`validate` · 12 invariants de cross-cohérence)
- `ecf.schema.json` (contrat de sortie draft-07)
- `fixtures/dossier_exemple.json` (test only · opérandes fictifs sourcés)
- `out/{ecf_plan,MANIFEST}.json` (hand-off) · `tests/test_ecf_dgii.py`
  (39 tests) · `README.md` · `.gitignore`

**Fichiers modifiés** :
- `.gitea/workflows/ci.yml` : job `fiscal-ecf-tests` + ajout au `gate`.

**Anti-invention (cœur · #6)** : aucun chiffre fiscal OTO n'est documenté →
`rnc_emisor` / `taux ITBIS` / `TipoCambio` / endpoints Compupar restent `null`
(a_confirmer) ; un invariant refuse toute valeur fixée **sans `source`**. Seules
les données de référence DGII (types e-CF, FormaPago, format e-NCF) sont encodées,
avec source. Le composeur e-NCF reste `None` tant qu'un opérande manque.

**Cross-cohérence** : chaque émission se déclenche sur un état **soumis** du
workflow (réservation/contrat), sur un champ **Currency** réel du Dossier Vente,
par le rôle **compta** `compta-fiscaliste-ecf` résolu depuis RBAC ; FormaPago
défaut = 3 (Tarjeta) car **Cardnet** (#10).

**Vérifs** : 39/39 tests ; gate CI local vert (guard + JSON + docs + YAML) ;
régression **241 tests verts** au total.

**Hors périmètre worker (VPS · #8)** : confirmation RNC/ITBIS/TipoCambio par la
Compta + configuration Compupar (endpoints/certificat/credentials) + câblage sur
les transitions Workflow → agent ERPNext Backend.

**Détail complet** : voir
[`05_deliverables_mvp/daily_reports/2026-07-30-session14.md`](../05_deliverables_mvp/daily_reports/2026-07-30-session14.md).

**Auto-score 4Big** : 96/100.

## Session `20260730_062706` (session 13)

**Tâche** : Sprint 4 · ERPNext Backend — Générateur du **barème de commissions
vendeurs** (roadmap ligne 51 « commissions vendeurs auto »).

**Fichiers créés** — `05_deliverables_mvp/crm/commissions/` :
- `bareme_spec.json` (5 évènements · tous `taux_pct: null` · anti-invention #6)
- `commlib/{__init__,deps,finance,builder}.py` (réutilise `is_filled`/`CANONICAL`/
  `validate` + `RoleResolver` du module `workflow_vente` · calcul traçable
  `commission = base × taux` façon `banclib/finance.py`)
- `commissions_gen.py` (CLI `build`/`validate` · 10 invariants de cross-cohérence)
- `bareme.schema.json` (contrat de sortie draft-07)
- `fixtures/dossier_exemple.json` (test only · chiffres fictifs sourcés)
- `out/{commission_plan,MANIFEST}.json` (hand-off) · `tests/test_commissions.py`
  (25 tests) · `README.md` · `.gitignore`

**Fichiers modifiés** :
- `.gitea/workflows/ci.yml` : job `crm-commissions-tests` + ajout au `gate`.

**Anti-invention (cœur · #6)** : aucun taux de commission n'est documenté dans
CLAUDE.md → le barème livré porte `taux_pct: null` partout ; un invariant refuse
tout taux fourni **sans `source`**. Le calcul reste `None` tant qu'un opérande
manque (jamais 0-inventé · formule toujours affichée).

**Cross-cohérence** : chaque évènement paie sur un état **soumis** du workflow
(pas de brouillon), sur un champ **Currency** réel du Dossier Vente, pour un rôle
**ventes** résolu depuis `rbac_50_roles.json`.

**Vérifs** : 25/25 tests ; gate CI local vert (guard + JSON + docs + YAML) ;
régression **202 tests verts** au total.

**Hors périmètre worker (VPS · #8)** : confirmation des taux réels par la
Direction + câblage du calcul sur les transitions Workflow → agent ERPNext Backend.

**Détail complet** : voir
[`05_deliverables_mvp/daily_reports/2026-07-30-session13.md`](../05_deliverables_mvp/daily_reports/2026-07-30-session13.md).

**Auto-score 4Big** : 96/100.

## Session `20260730_055704` (session 12)

**Tâche** : Sprint 4 · CRM — Générateur du **DocType porteur `OTO Dossier Vente`**
(complète le hand-off du workflow vente : le document réel que le Workflow pilote).

**Fichiers créés** — `05_deliverables_mvp/crm/dossier_vente/` :
- `doctype_spec.json` (structure métier · zéro chiffre · Projet P01..P09 · USD/DOP)
- `dvlib/{__init__,frappe,builder}.py` (connaissance Frappe + assemblage
  cross-cohérent · réutilise `_UPDATE_FIELD` + `RoleResolver` de `workflow_vente`)
- `doctype_dossier_vente_gen.py` (CLI `build`/`validate` · 12 invariants)
- `doctype.schema.json` (contrat de sortie draft-07)
- `out/{doctype_oto_dossier_vente,MANIFEST}.json` (hand-off)
- `tests/test_dossier_vente.py` (31 tests) · `README.md` · `.gitignore`

**Fichiers modifiés** :
- `.gitea/workflows/ci.yml` : job `crm-dossier-vente-tests` + ajout au `gate`.

**Cross-cohérence (cœur du livrable)** : nom / champ d'état / valeurs de statut /
`is_submittable` / permissions tous **dérivés** de `workflow_vente_spec.json`
(source unique · anti-dérive) ; rôles résolus depuis `rbac_50_roles.json` (#6).

**Vérifs** : 31/31 tests ; gate CI local vert (guard + JSON + docs + YAML) ;
régression **177 tests verts** au total.

**Hors périmètre worker (VPS · #8)** : création module `OTO Ventes` + import réel
DocType puis Workflow → agent ERPNext Backend.

**Détail complet** : voir
[`05_deliverables_mvp/daily_reports/2026-07-30-session12.md`](../05_deliverables_mvp/daily_reports/2026-07-30-session12.md).

**Auto-score 4Big** : 96/100.

## Session `20260730_052701` (session 11)

**Tâche** : Sprint 4 · CRM — Générateur de workflow vente ERPNext
(`lead → visite → devis → réservation → contrat → CONFOTUR`).

**Fichiers créés** — `05_deliverables_mvp/crm/workflow_vente/` :
- `workflow_vente_spec.json` (contrat pipeline · 9 états / 11 transitions)
- `wflib/{__init__,rbac,erpnext,builder}.py` (résolution RBAC + connaissance
  Frappe + assemblage déterministe)
- `workflow_vente_gen.py` (CLI `build`/`validate` · 9 invariants de graphe)
- `workflow.schema.json` (contrat de sortie draft-07)
- `out/{workflow,workflow_state,workflow_action_master,MANIFEST}.json` (hand-off)
- `tests/test_workflow_vente.py` (25 tests) · `README.md` · `.gitignore`

**Fichiers modifiés** :
- `.gitea/workflows/ci.yml` : job `crm-workflow-vente-tests` + ajout au `gate`.

**Réutilisation (zéro duplication · #6)** : rôles résolus depuis
`rbac/rbac_50_roles.json` (jamais de nom Frappe en dur) + validateur maison
Publiciste.

**Vérifs** : 25/25 tests ; gate CI local vert (guard + JSON + docs + YAML) ;
régression **146 tests verts** au total.

**Hors périmètre worker (VPS)** : création DocType `OTO Dossier Vente` + import
fixtures (`bench migrate`) → agent ERPNext Backend (#8).

**Détail complet** : voir
[`05_deliverables_mvp/daily_reports/2026-07-30-session11.md`](../05_deliverables_mvp/daily_reports/2026-07-30-session11.md).

**Auto-score 4Big** : 96/100.

---

## Session 20260730_172819 · Doc agent Mobile (dernier stub → doc réelle honnête)

**Tâche** : dernier `AGENT.md` encore au format stub (29 lignes) — `03_agents/mobile/`.
Portée : passer de stub générique à documentation réelle, sourcée et **honnête**,
alignée sur le pattern des 12 autres agents déjà documentés (rendu, ifc_speckle, bim…).

**Fichier modifié** : `03_agents/mobile/AGENT.md` (29 → doc complète).

**Ancrage in-repo VÉRIFIÉ (2 contacts réels, pas inventés)** :
- `05_deliverables_mvp/rbac/rbac_50_roles.json` → rôle `plateforme-mobile` =
  **`OTO Plateforme Mobile`** (« Développeur Mobile » · famille `plateforme` ·
  entité **9060 QC** · niveau 2 · perm `API Access` custom R/W · Expo/RN + EAS).
- `05_deliverables_mvp/qa/acceptance/acceptance_spec.json` → row **S5** (roadmap
  L58) : builds Expo 54 + submit stores explicitement `out_of_scope` (#8).

**Honnêteté (anti-invention #6)** : contrairement à l'agent Rendu, le rôle mobile
est de famille `plateforme` (9060 QC), **PAS** construction/vente — donc
**volontairement AUCUN** contact workspace/chat_otoia revendiqué (ces surfaces
couvrent les portails construction/vente). Pas de faux contact inventé pour
gonfler la doc.

**Modules VPS refactorés (source `AGENTS_EXISTING_ASSETS.md §8`)** :
`oto_module_mobile_api.py` · `oto_module_mobile_download.py` ·
`staging/mobile_rbac/{deploy,seed}_mobile_rbac.*` · `static/oto_mobile.js` ·
Expo SDK 54 / React 19.1.0 / RN 0.81.5 (upgrade 2026-07) · EAS builds+submit.

**Hors périmètre worker (VPS/EAS/stores · #8)** : builds EAS, soumissions
App Store #32 / Play Store, updates OTA → aucun binaire/`.ipa`/`.aab` diffable
commité ; le prétendre serait une invention (#6).

**Vérifs** : `ci/check_docs.sh` → **0 lien interne cassé** ;
`ci/guard_constraints.sh` → toutes contraintes NON-NÉGOCIABLES vertes.

**État global** : les **13 agents** (`03_agents/*`) ont désormais une doc réelle ;
plus aucun stub restant.

---

## Session 20260730_175819 · Buffer S8 · Cohérence auto-score 4Big (2 modules gated)

**Contexte** : roadmap fonctionnellement complète — 13/13 agents documentés,
S1..S8 `in_repo` ou `out_of_scope` (acceptance_spec), **régression exhaustive
exécutée : 21/21 suites vertes · 534 tests · 0 échec / 0 erreur**. On est en
Sprint 8 « Bufer pour corrections finales » (roadmap L75).

**Tâche** : `ci/check_docs.sh` signalait 2 **vrais livrables gated** dépourvus de
la section `## Auto-score 4Big` que **tous** leurs modules-frères possèdent —
incohérence de finition :
- `05_deliverables_mvp/demo/scenarios/README.md` (32 tests)
- `05_deliverables_mvp/legal/confotur/README.md` (44 tests)

**Fichiers modifiés** (docs pures · aucun code touché) :
- `demo/scenarios/README.md` : + section Auto-score **96/100** (orchestration
  RFC 6901 re-résolue · couverture CI réutilisée · garde `pret` · 32 tests).
- `legal/confotur/README.md` : + section Auto-score **96/100** (DocType dérivé
  des contrats RBAC+workflow · anti-invention monétaire · 44 tests).

**Honnêteté (anti-invention #6)** : les avertissements restants — fixtures
`publiciste/fixtures/data_room/*` (entrées-échantillon consommées par le
générateur, **pas** des livrables) et `specs/CHOISIR_MON_UNITE_SPEC.md`
(placeholder « Attente vision précise Michel ») — sont **volontairement laissés
tels quels** : leur ajouter un score serait inventer une qualité sur des artefacts
qui n'en portent pas.

**Vérifs** : `ci/check_docs.sh` → conforme (seuls fixtures/placeholder attendus
restent en soft-warn) · `ci/guard_constraints.sh` → toutes contraintes vertes ·
`qa/regression run` → 534 tests verts (inchangé, docs uniquement).

**Auto-score 4Big** : 96/100.

---

## Session 20260730_192834 · Buffer S8 · Cohérence spec CHOISIR_MON_UNITE (header stale résolu)

**Contexte** : roadmap fonctionnellement complète — 13/13 agents documentés,
21/21 suites régression vertes (534 tests · 0 échec), `guard_constraints`,
`check_docs`, `validate_json` tous verts. Sprint 8 « Bufer corrections finales » (roadmap L75).

**Tâche (finition/cohérence · pas de doc-churn)** : `specs/CHOISIR_MON_UNITE_SPEC.md`
portait une **incohérence interne réelle** — son en-tête (L3-5) affichait
`Status: Attente vision précise Michel · placeholder` et une section
`Questions ouvertes pour Michel` (5 questions), alors que les L63-109 contiennent
`DÉCISIONS FINALES MICHEL (2026-07-28)` qui **tranchent chacune de ces questions**
+ un parcours vendeur finalisé. Header et bas de doc se contredisaient.

**Fichier modifié** (doc pure · 0 code) : `05_deliverables_mvp/specs/CHOISIR_MON_UNITE_SPEC.md`
- **Status** réécrit : « ✅ Vision finalisée par Michel (2026-07-28) · spec design-complete ».
  Implémentation de la page `/choisir-mon-unite` explicitement marquée **frontend VPS
  hors-périmètre worker (#8)** — même statut que les builds EAS mobile : aucun HTML
  de prod diffable dans le dépôt de mandat.
- Titre « Vision cible (à confirmer avec Michel) » → « (✅ confirmée · cf. Décisions finales) ».
- Section « Questions ouvertes » : conservée pour traçabilité mais chaque Q mappée
  à sa décision (1→Speckle 3D · 2→prix public « à partir de »/détails post-login ·
  3→réservation 10j ouvrables ERPNext · 4→DocuSign intégré · 5→pas de comparateur).

**Honnêteté (anti-invention #6)** : le fichier reste **volontairement non-scoré**
(soft-warn `check_docs` attendu). Rationale mis à jour : ce n'est plus « placeholder
attente vision » (framing devenu faux) mais une **spec design-complete dont
l'implémentation est hors-périmètre VPS (#8)** — lui coller un auto-score inventerait
une qualité de livrable sur un artefact non-implémenté ici. Cohérent avec le
traitement des builds EAS mobile (S5 `out_of_scope`).

**Références croisées vérifiées** : spec citée par `03_agents/frontend_console/AGENT.md`
(L116-117), `03_agents/ifc_speckle/AGENT.md`, roadmap L32, `tests/e2e/routes.json` —
aucun lien cassé introduit.

**Vérifs** : `ci/check_docs.sh` EXIT 0 (0 lien interne cassé · seuls fixtures
data_room + ce spec restent en soft-warn attendu) · `ci/guard_constraints.sh` EXIT 0
(contraintes NON-NÉGOCIABLES vertes) · `ci/validate_json.sh` EXIT 0 · régression
inchangée 534 tests verts (docs uniquement).

**Auto-score 4Big** : 96/100.

---

## Session 20260730_195844 · Buffer S8 · Fiche agent Publiciste cross-linke son livrable in-repo

**Contexte** : roadmap fonctionnellement complète — 13/13 agents documentés, 21/21
suites régression vertes (534 tests · 0 échec), `guard_constraints` / `check_docs` /
`validate_json` tous verts. Sprint 8 « Bufer corrections finales » (roadmap L75).

**Tâche (finition/cohérence · pas de doc-churn)** : audit de cohérence des 13
`03_agents/*/AGENT.md` sur le pattern « cross-link vers ses livrables in-repo »
(`grep -c 05_deliverables_mvp`). Résultat : **`publiciste` = 0 lien** — seul agent
possédant un **vrai module in-repo gaté** (`05_deliverables_mvp/publiciste/`, 23
tests, job `publiciste-tests`) à n'en cross-linker **aucun**, alors que ses pairs en
ont ≥3 (faisabilite 4 depuis session 36, qa/crm/devops/seo 3, etc.). Un lecteur
n'avait aucun chemin de la mission de l'agent vers l'artefact commité qui la réalise.
Défaut réel identique à celui corrigé pour `faisabilite` (session 36) — les 4 agents
restants à faible lien (`bim`/`ifc_speckle`/`rendu`/`mobile`) sont légitimement
VPS-only, sans livrable in-repo propre.

**Fichier modifié** (doc pure · 0 code) — `03_agents/publiciste/AGENT.md` : + section
**« Livrable Publiciste réellement produit »** (table calquée sur le pattern des pairs :
Module · Sprint · Rôle · Entrée CLI · Job CI · Tests), toutes cellules **vérifiées** :
- [`publiciste/`] — Sprint 2 (sourcé README `scaffold (Sprint 2)` + GAP §3.13, **pas**
  d'un n° de ligne roadmap qui ne nomme pas le module — anti-invention) · pipeline
  `data_room/PXX/` → `projets_master.json` → `index.html` luxury · CLI
  `publiciste.py {parse,validate,generate,run}` (lu via `--help`) · job `publiciste-tests`
  (lu dans `ci.yml`, présent au `gate`) · **23 tests** (`grep -c def test_` + confirmé
  `regression run`).
- Contrat `projets_master.json` explicitement attribué au **Faisabilité Agent**
  (`faisabilite/projets_master.schema.json`, Sprint 1) — source unique, zéro
  duplication (#5) ; le Publiciste en est le consommateur.
- Auto-score **95/100** cité depuis `publiciste/README.md` L79 (non fabriqué).

**Anti-invention (#6)** : la section rappelle que le générateur ne fabrique aucun
prix/positionnement (extraction faisabilité réelle uniquement) ; qu'aucun `index.html`
de prod n'est commité (publication VPS · #8) ; et explicite pourquoi les fixtures
`fixtures/data_room/P01…P02` restent **hors auto-score** (échantillons d'entrée du
parser, pas des livrables — cohérent avec les soft-warns `check_docs` attendus).

**Vérifs** : `ci/check_docs.sh` EXIT 0 (**0 lien interne cassé** — les 5 cibles
`../../05_deliverables_mvp/*` [README publiciste, GAP_ANALYSIS §3.13, schema faisabilité]
résolvent) · `ci/guard_constraints.sh` EXIT 0 · régression inchangée 534 tests verts
(doc-only, 0 code). `publiciste/AGENT.md` : links 0 → **5**.

**Hors périmètre worker (VPS · #8)** : néant (changement doc-only en-repo).

**Auto-score 4Big** : 96/100.

---

## Session 20260730_202854 · Buffer S8 · Fiche agent QA cross-linke ses 4 livrables in-repo

**Tâche** : **Sprint 8 · buffer L75 (corrections finales · doc)** — roadmap
fonctionnellement close (21/21 modules gated verts · 534 tests · guards verts).
Poursuite du chantier de cohérence des fiches agents (sessions 35-36 : `faisabilite`
puis `publiciste` ont reçu des liens cliquables vers leurs artefacts in-repo).

**État vérifié en début de session** :
- `ci/check_docs.sh` EXIT 0 · `ci/guard_constraints.sh` EXIT 0 · `ci/validate_json.sh` EXIT 0.
- Régression exhaustive : **22 suites** exécutées une à une → **toutes OK** ;
  matrice `qa/regression` → **21 suites gated · 534 méthodes · verdict PASS**.

**Défaut réel identifié** : la table « Livrables QA réellement produits » de
`03_agents/qa/AGENT.md` listait ses 4 modules (`audit_5d/`, `audit_4big/`,
`regression/`, `acceptance/`) en **code-spans nus, non cliquables** — alors que le
pattern établi par `faisabilite` (session ≤36) et `publiciste` (session 36) est un
**lien markdown cliquable** `[`module/`](../../05_deliverables_mvp/…/README.md)`.
Mesure objective : `grep -c "](../../05_deliverables_mvp"` → `faisabilite`=3,
`publiciste`=4, mais `qa`=**0** (idem crm/devops/erpnext_backend/frontend_console/
onapi_legal/seo — chantier restant, une fiche par commit). Un lecteur de la fiche QA
n'avait aucun chemin cliquable vers l'artefact réalisant chaque gate.

**Fichier modifié** (doc pure · 0 code) — `03_agents/qa/AGENT.md` : les 4 cellules
`Module` de la table deviennent des liens vers le `README.md` in-repo de chaque module.
Cibles **vérifiées existantes** (`test -f`) avant édition :
`05_deliverables_mvp/qa/{audit_5d,audit_4big,regression,acceptance}/README.md`.

**Anti-invention (#6)** : les 4 compteurs de tests de la table (37/35/25/31) ont été
**revérifiés** contre le disque (`grep -c "def test_"` par module) → identiques.
Note d'honnêteté sur `regression`=**25** : `unittest discover` n'en exécute que **24**,
car la 25ᵉ occurrence (`test_regression.py:47` `def test_case_{i}` dans une **f-string**)
est un gabarit de test synthétique généré par le harnais, pas une méthode exécutable.
Le **25** de la fiche suit la convention de recensement **faisant autorité** de la
matrice de régression (comptage par regex `def test_`, qui inclut ce gabarit) et
reste donc cohérent avec le total **534** ; le désynchroniser à 24 casserait la
bijection. Aucun chiffre n'a été fabriqué ni modifié.

**Vérifs post-édition** : `ci/check_docs.sh` EXIT 0 (**0 lien interne cassé** — les 4
nouvelles cibles résolvent) · `ci/guard_constraints.sh` EXIT 0 · régression inchangée
(doc-only, 0 code). `qa/AGENT.md` : links `](../../05_deliverables_mvp` 0 → **4**.

**Hors périmètre worker (VPS · #8)** : néant (changement doc-only en-repo).

**Reste du chantier fiches** (sessions futures, une par commit) : `crm`, `devops`,
`erpnext_backend`, `frontend_console`, `onapi_legal`, `seo` — encore 0 lien cliquable
vers leurs livrables in-repo propres. (`bim`/`ifc_speckle`/`rendu`/`mobile` = VPS-only,
sans livrable in-repo propre → hors chantier, légitimement 0.)

**Auto-score 4Big** : 96/100.

---

## Session 20260730_205901 · Buffer S8 · Fix CI check_docs (faux positif lien en code-span)

**Tâche** : **Sprint 8 · buffer L75 (corrections finales)**. Session ouverte pour
poursuivre le chantier de cross-linking des fiches agents (`crm` était la prochaine).
**Défaut bloquant découvert au baseline** : `ci/check_docs.sh` sortait **EXIT 1** —
la gate documentaire était **rouge**, ce qui prime sur le cosmétique.

**Cause racine** : le log de la session précédente (`05_activity_log/2026-07-30.md:1350`)
documente le *pattern* de lien cliquable via un **exemple de syntaxe entre backticks** :
`` `[`module/`](../../05_deliverables_mvp/…/README.md)` ``. La regex d'extraction du
checker (`\]\([^)]+\)`) **ne dé-échappe pas les code-spans** ; elle a donc capté cet
exemple comme un vrai lien et l'a déclaré cassé (la cible `…/README.md` avec ellipse
n'existe pas). Un lien **entre backticks n'est pourtant jamais cliquable au rendu** —
c'est de la doc, pas un lien réel à valider. (La ligne 1351, `"](../../05_deliverables_mvp"`
sans `)` fermante, n'était pas matchée → seule 1350 échouait.)

**2 solutions envisagées (workflow #4)** :
- **A (racine)** : le checker neutralise les code-spans avant extraction des liens.
- **B (local)** : réécrire l'exemple ligne 1350 pour casser sa forme de lien.
**Choix : A.** Le chantier de cross-linking **documente ce pattern via des exemples
backtick à chaque session** — B laisserait le piège rearmé au prochain log. A est la
cause racine et **ne peut que retirer des faux positifs**, jamais masquer un vrai lien
cliquable (par définition hors backticks).

**Fichier modifié** — `ci/check_docs.sh` : ajout d'un `sed -E 's/`[^`]*`//g'` en tête
du pipeline d'extraction (les code-spans sont vidés avant `grep -oE '\]\([^)]+\)'`).
Commentaire mis à jour pour tracer la règle.

**Vérifs post-fix** :
- `ci/check_docs.sh` **EXIT 1 → EXIT 0** (« Aucun lien interne cassé »).
- `ci/guard_constraints.sh` EXIT 0 · `ci/validate_json.sh` EXIT 0 (inchangés).
- **Test négatif** (fichier sonde temporaire, supprimé après) : un lien cassé **hors
  backticks** reste **détecté** (`does_not_exist_xyz.md` → ✗) ; le même **dans**
  backticks est **ignoré**. Le fix corrige sans affaiblir la gate.

**Anti-invention (#6)** : aucun chiffre touché. Le log historique (ligne 1350) est
laissé **tel quel** — c'est la gate qui était trop naïve, pas le log qui était faux.

**Hors périmètre worker (VPS · #8)** : néant (changement in-repo, gate CI locale).

**Reste du chantier fiches** (prochaine session) : `crm` (cibles README vérifiées
existantes : `workflow_vente`/`dossier_vente`/`commissions`, compteurs 25/31/25
reconfirmés au disque), puis `devops`, `erpnext_backend`, `frontend_console`,
`onapi_legal`, `seo`.

**Auto-score 4Big** : 96/100.

---

## Session 20260730_215901 · Buffer S8 · Fiche agent CRM cross-linke ses 3 livrables in-repo

**Tâche** : **Sprint 8 · buffer L75 (corrections finales)** — suite directe du chantier
de cross-linking des fiches agents. La session précédente désignait `crm` comme la
prochaine fiche à traiter (cibles README déjà vérifiées existantes, compteurs 25/31/25
reconfirmés). Baseline sain : `ci/check_docs.sh` EXIT 0 (faux positif code-span corrigé
la session d'avant).

**Défaut corrigé** : dans `03_agents/crm/AGENT.md`, la table « Livrables CRM réellement
produits » nommait ses 3 modules (`workflow_vente/`, `dossier_vente/`, `commissions/`)
en **texte brut** — aucun chemin cliquable vers l'artefact in-repo réalisant chaque
livrable. Alignement sur les fiches `publiciste`/`qa`/`erpnext_backend` déjà cross-linkées.

**Fichier modifié** (doc pure · 0 code) — `03_agents/crm/AGENT.md` : les 3 cellules
`Module` deviennent des liens vers le `README.md` in-repo de chaque module. Cibles
**vérifiées existantes** (`test -f`) avant édition :
`05_deliverables_mvp/crm/{workflow_vente,dossier_vente,commissions}/README.md`.

**Anti-invention (#6)** : les 3 compteurs de tests de la table (25/31/25) ont été
**revérifiés** contre le disque (`grep -rc "def test_" <module>/tests/`) → identiques.
Total CRM **81** (25+31+25) inchangé. Les taux de commission `null` (non documentés
dans CLAUDE.md) restent `null` — aucun chiffre fabriqué ni modifié.

**Vérifs post-édition** : `ci/check_docs.sh` EXIT 0 (**0 lien interne cassé** — les 3
nouvelles cibles résolvent) · `ci/guard_constraints.sh` EXIT 0. `crm/AGENT.md` : links
`](../../05_deliverables_mvp/crm` 0 → **3**. Doc-only, régression inchangée (0 code).

**Hors périmètre worker (VPS · #8)** : néant (changement doc-only en-repo).

**Reste du chantier fiches** (sessions futures, une par commit) : `devops`,
`erpnext_backend` (déjà fait S8 précédent — à vérifier), `frontend_console`,
`onapi_legal`, `seo` — encore à cross-linker vers leurs livrables in-repo propres.
(`bim`/`ifc_speckle`/`rendu`/`mobile` = VPS-only, sans livrable in-repo → hors chantier.)

**Auto-score 4Big** : 96/100.

---

## Session 20260730_225912 · Buffer S8 · Gate 4Big check_docs : 0 faux positif (fixtures exclues + spec scorée)

**Tâche** : **Sprint 8 · buffer L75 (corrections finales)**. Le chantier de cross-linking
des fiches agents étant **clos** (commit f68f2e2 : 4 dernières fiches SEO/DevOps/Frontend/
ONAPI), baseline sain établi : `check_docs.sh` EXIT 0, `guard_constraints.sh` EXIT 0,
`validate_json.sh` EXIT 0. Cible de la session : réduire le **bruit** de la gate
documentaire — la section « 2. Auto-score 4Big (SOFT) » émettait **9 avertissements ⚠**.

**Diagnostic (analyser avant agir · #1)** : les 9 ⚠ se répartissent en deux natures
**distinctes**, l'une un **faux positif**, l'autre un **vrai manque** :
- **8 sur 9** sous `publiciste/fixtures/data_room/PXX/…` — ce sont des **INPUTS de test
  synthétiques** consommés par le parser (`test_publiciste.py:25` `FIXTURES = fixtures/data_room`).
  Le README de ces fixtures les déclare explicitement « **DONNÉES SYNTHÉTIQUES DE TEST …
  ne doivent JAMAIS être publiés** » (`publiciste/fixtures/README.md:1-5`). Un input de
  test n'est **pas un livrable scoré 4Big** — exactement le même statut que
  `daily_reports/*`, déjà exclu de cette gate.
- **1 sur 9** — `specs/CHOISIR_MON_UNITE_SPEC.md`, un **vrai livrable** (spec design-complete
  validée par Michel, 5 décisions tranchées) qui n'affichait **aucun** auto-score.

**2 solutions par nature (workflow #4 · toujours 2+ options)** :
- *Fixtures* — A **exclure la racine** (root-cause : les inputs de test ne sont pas des
  livrables) vs B ajouter un faux score à des fixtures « fictives ». **Choix A** : B
  falsifierait des fichiers explicitement non-publiables. Portée **précise** :
  `*/fixtures/data_room/*` (le sous-arbre d'inputs), **pas** `*/fixtures/*` — sinon
  `fixtures/README.md` (doc réelle, déjà scorée) perdrait sa surveillance.
- *Spec* — A l'**exclure** (specs = design docs) vs B lui **donner un vrai score**.
  **Choix B** : la spec EST un livrable (contrainte #5 « score min 95 sur tout livrable »),
  l'exclure masquerait un manque au lieu de l'honorer.

**Fichiers modifiés (2)** :
1. `ci/check_docs.sh` — nouvelle branche `case` : `05_deliverables_mvp/*/fixtures/data_room/*)
   continue ;;` (SOFT gate section 2 uniquement ; liens internes de la section 1 restent
   vérifiés partout, fixtures comprises).
2. `05_deliverables_mvp/specs/CHOISIR_MON_UNITE_SPEC.md` — section **« Auto-score 4Big :
   95/100 »** ajoutée, avec table 4 volets + justification du **−5** (provisionnements
   externes DocuSign/Speckle/PROJECT_META non tranchés, à lever au build downstream).

**Anti-invention (#6)** : le seul chiffre chiffré cité dans le score (P01 = **2.484M USD
Dumar tasación**) est une **citation verbatim** de la spec elle-même (`…:63`, section
« Non-négociables ») — aucun nombre fabriqué. Le score 95 est une **auto-évaluation de
rigueur de la spec**, explicitement **pas** un score d'implémentation (le build
`/choisir-mon-unite` reste hors-périmètre worker · #8).

**Vérifs post-édition** :
- `check_docs.sh` : **9 ⚠ → 0 ⚠**, EXIT 0 (liens internes toujours OK).
- **Test de non-régression de portée** : `fixtures/README.md` reste **gaté** (✓ score
  présent) — seul le sous-arbre `data_room/` est exclu ; la spec affiche désormais ✓.
- `guard_constraints.sh` EXIT 0 · `validate_json.sh` EXIT 0 (inchangés).

**Hors périmètre worker (VPS · #8)** : néant (changements in-repo : gate CI locale + doc).

**Auto-score 4Big** : 96/100.

---

## Session 20260730_232914 · Buffer S8 · Gate reproductibilité des artefacts + fix dérive run_sheet demo (18→21)

**Tâche** : **Sprint 8 · « Regression tests exhaustifs » + DevOps CI/CD**. Baseline
sain confirmé au démarrage (4 gates statiques EXIT 0 ; 21/21 suites vertes · 534
tests via `qa/regression run`). Objectif : durcir la régression au-delà de
l'exécution des tests — prouver la **reproductibilité byte-for-byte** des artefacts
`out/` versionnés (aucun `out/*.json` n'a dérivé de sa source).

**Découverte d'un VRAI défaut (analyser avant agir · #1)** : en ré-exécutant le
`build` de chaque module vers un tmpdir et en diffant contre le commité, **1
artefact sur 18 dérivait** — `demo/scenarios/out/run_sheet.json` : `"valeur": 18`
là où le build frais produit `21`. Générateur **déterministe** (deux builds
identiques), donc pas de non-déterminisme : le fichier commité était **périmé**.

**Cause racine** : le run_sheet auto-résout ses valeurs de preuve depuis les
artefacts d'AUTRES modules — ici `qa/audit_4big` `/coverage/ci_modules_count`. Ce
compteur a grandi **18 → 21** (suites `regression`/`acceptance`/`deploy_runbook`
ajoutées depuis) mais le run_sheet — buildé au Sprint 7 (commit `cac6538`, 10:39)
— n'a jamais été régénéré. **Dérive silencieuse** qu'aucune suite `tests/` (qui
teste des FONCTIONS, pas le fichier commité) n'attrapait.

**2 solutions (workflow #4)** : A régénérer + gate systémique préventif ·
B régénérer seul. **Choix A** — B laisserait la dérive revenir au prochain ajout
de module. Correctif ponctuel : `demo_scenario_gen.py build -o out` (diff = 1
ligne, `18→21`) ; suite demo 32 tests OK ; consistance live re-vérifiée
(run_sheet `21` == audit_4big source `21`).

**Fichiers (4)** :
1. `ci/check_artifacts.sh` (**neuf**) — gate de reproductibilité. Découvre chaque
   `05_deliverables_mvp/**/out/` (zéro liste à la main · #6), ré-exécute le
   générateur `build -o <tmp>`, exige l'égalité byte-for-byte avec le commité.
   Artefacts d'exécution non produits par `build` (p.ex.
   `qa/regression/out/regression_run.json`) non comparés. stdlib pur (bash+python3),
   zéro pip (runner Gitea · #2).
2. `.gitea/workflows/ci.yml` — job bloquant `check-artifacts` + ajout au `needs`
   du `gate` agrégé.
3. `05_deliverables_mvp/demo/scenarios/out/run_sheet.json` — régénéré (`18→21`).
4. `ci/README.md` — table pipeline + section détail + bloc exécution locale.

**Anti-invention (#6)** : la valeur `21` n'est **pas saisie** — elle re-découle de
`qa/audit_4big/out/quality_report.json` (recalculé lui-même depuis le CI). Le gate
n'affirme QUE ce que le `build` déterministe produit.

**Vérifs** : **test négatif** du gate (dérive `21→18` réinjectée → EXIT 1 + message
« DÉRIVE ») puis test positif (EXIT 0, 18/18 modules reproductibles). 4 gates
statiques EXIT 0 · YAML `safe_load` OK · suites CI-parsing vertes
(regression 24 · acceptance 31 · audit_4big 34 · demo 32). `check-artifacts`
n'entre PAS comme « module » dans `parse_ci` (pas de working-directory) → compteurs
dérivés stables (21/534 inchangés).

**Hors périmètre worker (VPS · #8)** : néant (gate CI local + doc + artefact in-repo).

**Auto-score 4Big** : 96/100.
