Files
oto-enterprise-os-dtp/05_activity_log/2026-07-30.md
T
Claude Code DTP Worker c201d37d29 [DTP-Worker] Sprint 8 · buffer L75 · Fiche agent ERPNext Backend cross-linke ses 6 livrables in-repo
Table 'Livrables backend réellement produits' : les 6 modules (rbac spec + 4
générateurs RBAC + fiscal/ecf_dgii) passent de code-spans nus à liens markdown
cliquables vers leur README.md (ou RBAC_50_ROLES_SPEC.md pour le dir spec sans
README) — pattern déjà appliqué à faisabilite/publiciste/qa. Priorité #1 (ERPNext
natif). Cibles vérifiées existantes (test -f) avant édition. Compteurs de tests
(10/11/12/11/16/39) revérifiés vs disque (grep def test_) : identiques ; texte et
code inchangés, liens uniquement. check_docs EXIT 0 (0 lien cassé) · guard EXIT 0 ·
doc pure 0 code · régression inchangée 534 verts. Reste chantier :
crm/devops/frontend_console/onapi_legal/seo (bim/ifc/rendu/mobile = VPS-only).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-30 21:31:57 +00:00

1472 lines
83 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Activity Log · 2026-07-30 · Claude Code DTP
## 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.