# 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 `` / `