Compare commits
17 Commits
f3160607bc
...
39def91880
| Author | SHA1 | Date | |
|---|---|---|---|
| 39def91880 | |||
| 548a05ec61 | |||
| 35de616236 | |||
| fd99362660 | |||
| 9e02c38902 | |||
| ac595d0749 | |||
| 344b8154e1 | |||
| 37c1e9767e | |||
| f3419f9c26 | |||
| 6970294da7 | |||
| 72753a6342 | |||
| 460574a265 | |||
| c3f5664370 | |||
| 8ec11dece6 | |||
| 18d876352c | |||
| de837fae00 | |||
| 0b453c5182 |
@@ -7,6 +7,24 @@ faisabilités 4 volets et le **viewer 3D** de la console. Il ne « dessine » pa
|
|||||||
il orchestre des outils lourds (Blender headless, Bonsai/IfcOpenShell, RunPod
|
il orchestre des outils lourds (Blender headless, Bonsai/IfcOpenShell, RunPod
|
||||||
ComfyUI) **de façon déterministe et sans jamais fabriquer un chiffre de projet**.
|
ComfyUI) **de façon déterministe et sans jamais fabriquer un chiffre de projet**.
|
||||||
|
|
||||||
|
> **⚠️ Statut migration V18 (2026-08-10) · à lire AVANT le reste de cette fiche.** Michel a émis la
|
||||||
|
> [`DIRECTIVE_V18_MASTER_FEASIBILITY_ENGINE_20260810.md`](../../DIRECTIVE_V18_MASTER_FEASIBILITY_ENGINE_20260810.md)
|
||||||
|
> qui **remplace** le modèle V12 « 4 volets » : le BIM n'y alimente plus un seul *volet Ingénierie*
|
||||||
|
> mais devient **central à 7 des 18 sections** — Architecturale, Structurelle, Plomberie, Électrique,
|
||||||
|
> Mécanique HVAC (« + BIM »), **Clash Detection** (§9) et Environnementale + BIM VRD (§14). Le pipeline
|
||||||
|
> BIM y est le **moteur 7 (« BIM / Clash / Quantity »)** de l'ordre de développement imposé, et deux
|
||||||
|
> checkpoints humains y sont adossés : **CP1 BIM Geometry** et **CP3 Clash Resolution** (« aucun
|
||||||
|
> blocking non résolu » = gate dur). L'audit préalable
|
||||||
|
> [`OTO_V18_MIGRATION_ARCHITECTURE_AUDIT_20260810.md`](../../OTO_V18_MIGRATION_ARCHITECTURE_AUDIT_20260810.md)
|
||||||
|
> (§3, mapping 18 sections) classe ces sections BIM **🟠 partiel / 🔴 nouveau** : côté lisible in-repo,
|
||||||
|
> seul le volet archi existe, **`aec.py`/IFC restent hors-repo (VPS, #8)**. **Toute la séquence moteur
|
||||||
|
> V18 est bloquée** en attente des arbitrages de Michel — voir
|
||||||
|
> [`OPEN_DECISIONS_REGISTER.md`](../../05_deliverables_mvp/OPEN_DECISIONS_REGISTER.md) **D-06**
|
||||||
|
> (approbation de l'audit = gate d'entrée de tout le moteur) · **D-08** (périmètre du Master Intake).
|
||||||
|
> Tant que ces décisions ne sont pas rendues, **aucun code moteur V18 n'est produit** (directive :
|
||||||
|
> « NE PAS coder avant l'audit approuvé » · anti-invention `CLAUDE.md` #6). **La fiche V12 ci-dessous
|
||||||
|
> décrit l'état commité courant, pas la cible finale V18.**
|
||||||
|
|
||||||
## Scope
|
## Scope
|
||||||
Brief projet → maquette Blender/Bonsai → export **IFC** → publication **Speckle**
|
Brief projet → maquette Blender/Bonsai → export **IFC** → publication **Speckle**
|
||||||
(`bim-cloud.otov7.com`) → export **IFC→GLB** pour viewer → quantitatifs **BIM
|
(`bim-cloud.otov7.com`) → export **IFC→GLB** pour viewer → quantitatifs **BIM
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ le VPS reçoit — jamais l'inverse.
|
|||||||
vente, le barème commissions, le DocType Dossier Vente et le plan e-CF **résolvent**
|
vente, le barème commissions, le DocType Dossier Vente et le plan e-CF **résolvent**
|
||||||
leurs rôles depuis ce fichier, jamais un nom Frappe en dur. Total backend **RBAC 60
|
leurs rôles depuis ce fichier, jamais un nom Frappe en dur. Total backend **RBAC 60
|
||||||
tests** (10 + 11 + 12 + 11 + 16) + **e-CF 39 tests**, tous gated dans le CI (matrice
|
tests** (10 + 11 + 12 + 11 + 16) + **e-CF 39 tests**, tous gated dans le CI (matrice
|
||||||
de régression du repo : **625 tests · 24 suites** · verdict `PASS`, source
|
de régression du repo : **629 tests · 24 suites** · verdict `PASS`, source
|
||||||
`qa/regression/out/regression_run.json` — jamais compté à la main · #6).
|
`qa/regression/out/regression_run.json` — jamais compté à la main · #6).
|
||||||
|
|
||||||
## Hand-off reçus (à appliquer sur le VPS, dans l'ordre)
|
## Hand-off reçus (à appliquer sur le VPS, dans l'ordre)
|
||||||
|
|||||||
@@ -2,6 +2,22 @@
|
|||||||
|
|
||||||
**Rôle** : Cet agent OTOIA génère et maintient à jour toutes les faisabilités de projets sur le **modèle canonique le plus récent**. Élimine les faisabilités obsolètes ou hétérogènes.
|
**Rôle** : Cet agent OTOIA génère et maintient à jour toutes les faisabilités de projets sur le **modèle canonique le plus récent**. Élimine les faisabilités obsolètes ou hétérogènes.
|
||||||
|
|
||||||
|
> **⚠️ Statut migration V18 (2026-08-10) · à lire AVANT le reste de cette fiche.** Michel a émis la
|
||||||
|
> [`DIRECTIVE_V18_MASTER_FEASIBILITY_ENGINE_20260810.md`](../../DIRECTIVE_V18_MASTER_FEASIBILITY_ENGINE_20260810.md)
|
||||||
|
> — un **Master Institutional Feasibility & Bankability Engine** qui **remplace** le modèle V12
|
||||||
|
> « 4 volets » décrit dans cette fiche. Les modules commités actuels (`generator`, `bancable`,
|
||||||
|
> table §Livrables) restent le **socle réutilisable** de cette cible, mais **le moteur V18
|
||||||
|
> lui-même n'est pas encore construit** : l'audit préalable
|
||||||
|
> [`OTO_V18_MIGRATION_ARCHITECTURE_AUDIT_20260810.md`](../../OTO_V18_MIGRATION_ARCHITECTURE_AUDIT_20260810.md)
|
||||||
|
> (V12→V18, produit **avant tout code**) cartographie l'écart, et **toute la séquence moteur est
|
||||||
|
> bloquée en attente des arbitrages de Michel** — consignés dans le
|
||||||
|
> [`OPEN_DECISIONS_REGISTER.md`](../../05_deliverables_mvp/OPEN_DECISIONS_REGISTER.md) :
|
||||||
|
> **D-06** approbation de l'audit · **D-07** formules financières (DCF · IRR/VAN · DSCR/LTV/LTC)
|
||||||
|
> absentes des docs lisibles · **D-08** périmètre du Master Intake (sur-ensemble strict du
|
||||||
|
> `brief.json`). Tant que ces décisions ne sont pas rendues, **aucun code moteur V18 n'est
|
||||||
|
> produit** (directive : « NE PAS coder avant l'audit approuvé » · anti-invention `CLAUDE.md` #6).
|
||||||
|
> **La fiche V12 ci-dessous décrit l'état commité courant, pas la cible finale V18.**
|
||||||
|
|
||||||
## Mission
|
## Mission
|
||||||
1. **Générer** les faisabilités 4 volets pour chaque projet (Masterplan · Architecture · Paysage-Expérience · Ingénierie-Faisabilité)
|
1. **Générer** les faisabilités 4 volets pour chaque projet (Masterplan · Architecture · Paysage-Expérience · Ingénierie-Faisabilité)
|
||||||
2. **Maintenir un template canonique versionné** (`data_room/_TEMPLATE_FAISABILITE_v{X}/`)
|
2. **Maintenir un template canonique versionné** (`data_room/_TEMPLATE_FAISABILITE_v{X}/`)
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ du générateur, gaté en CI. C'est le **seul module net-neuf** du mandat, sur l
|
|||||||
|
|
||||||
| Module | Sprint | Rôle | Entrée CLI | Job CI | Tests |
|
| Module | Sprint | Rôle | Entrée CLI | Job CI | Tests |
|
||||||
|---|---|---|---|---|---|
|
|---|---|---|---|---|---|
|
||||||
| [`publiciste/`](../../05_deliverables_mvp/publiciste/README.md) | 2 (README `scaffold (Sprint 2)` · GAP §3.13) | **Pipeline site public** : `data_room/PXX/` → `projets_master.json` → `index.html` luxury (`lib/parser.py` extraction · `lib/validator.py` schéma · `lib/generator.py` + `lib/branding.py` rendu dark+doré `#0a0a12`/`#f0b429` · `templates/site_public.html.tmpl`) | `publiciste.py parse\|validate\|generate\|run` | `publiciste-tests` | 23 |
|
| [`publiciste/`](../../05_deliverables_mvp/publiciste/README.md) | 2 (README `scaffold (Sprint 2)` · GAP §3.13) | **Pipeline site public** : `data_room/PXX/` → `projets_master.json` → `index.html` luxury (`lib/parser.py` extraction · `lib/validator.py` schéma · `lib/generator.py` + `lib/branding.py` rendu dark+doré `#0a0a12`/`#f0b429` · `templates/site_public.html.tmpl`) | `publiciste.py parse\|validate\|generate\|run` | `publiciste-tests` | 24 |
|
||||||
|
|
||||||
Le contrat d'échange `projets_master.json` n'est **pas** défini ici mais par le Faisabilité Agent
|
Le contrat d'échange `projets_master.json` n'est **pas** défini ici mais par le Faisabilité Agent
|
||||||
([`../../05_deliverables_mvp/faisabilite/projets_master.schema.json`](../../05_deliverables_mvp/faisabilite/projets_master.schema.json),
|
([`../../05_deliverables_mvp/faisabilite/projets_master.schema.json`](../../05_deliverables_mvp/faisabilite/projets_master.schema.json),
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ périmètre — un auditeur ne s'audite jamais.
|
|||||||
| Module | Sprint | Rôle | Entrée CLI | Job CI | Tests |
|
| Module | Sprint | Rôle | Entrée CLI | Job CI | Tests |
|
||||||
|---|---|---|---|---|---|
|
|---|---|---|---|---|---|
|
||||||
| [`audit_5d/`](../../05_deliverables_mvp/qa/audit_5d/README.md) | 5 (roadmap L57) | Audit **5D** de conformité : 17 contrôles / 5 dimensions, lit les `out/` amont, coche UAF + normes ISA/IFRS | `audit_5d_gen.py build\|validate` | `qa-audit-5d-tests` | 37 |
|
| [`audit_5d/`](../../05_deliverables_mvp/qa/audit_5d/README.md) | 5 (roadmap L57) | Audit **5D** de conformité : 17 contrôles / 5 dimensions, lit les `out/` amont, coche UAF + normes ISA/IFRS | `audit_5d_gen.py build\|validate` | `qa-audit-5d-tests` | 37 |
|
||||||
| [`audit_4big/`](../../05_deliverables_mvp/qa/audit_4big/README.md) | 7 (roadmap L69) | **Gate qualité** : note 4Big de 100 % des livrables, verdict `FAIL` si un module < 95/100 ou couverture incomplète | `audit_4big_gen.py build\|validate` | `qa-audit-4big-tests` | 34 |
|
| [`audit_4big/`](../../05_deliverables_mvp/qa/audit_4big/README.md) | 7 (roadmap L69) | **Gate qualité** : note 4Big de 100 % des livrables, verdict `FAIL` si un module < 95/100 ou couverture incomplète | `audit_4big_gen.py build\|validate` | `qa-audit-4big-tests` | 37 |
|
||||||
| [`regression/`](../../05_deliverables_mvp/qa/regression/README.md) | 8 (roadmap L74) | **Matrice de régression** : agrège l'exécution de **toutes** les suites gated en un verdict unique + le compte agrégé faisant autorité | `regression_gen.py build\|validate\|run` | `qa-regression-tests` | 26 |
|
| [`regression/`](../../05_deliverables_mvp/qa/regression/README.md) | 8 (roadmap L74) | **Matrice de régression** : agrège l'exécution de **toutes** les suites gated en un verdict unique + le compte agrégé faisant autorité | `regression_gen.py build\|validate\|run` | `qa-regression-tests` | 26 |
|
||||||
| [`acceptance/`](../../05_deliverables_mvp/qa/acceptance/README.md) | 8 (roadmap L75 / L80-87) | **Recette / traçabilité** : mappe chaque promesse roadmap (8 livrables + 7 métriques) vers sa preuve, bijectif vs CI | `acceptance_gen.py build\|validate` | `qa-acceptance-tests` | 37 |
|
| [`acceptance/`](../../05_deliverables_mvp/qa/acceptance/README.md) | 8 (roadmap L75 / L80-87) | **Recette / traçabilité** : mappe chaque promesse roadmap (8 livrables + 7 métriques) vers sa preuve, bijectif vs CI | `acceptance_gen.py build\|validate` | `qa-acceptance-tests` | 37 |
|
||||||
|
|
||||||
@@ -32,7 +32,7 @@ périmètre — un auditeur ne s'audite jamais.
|
|||||||
**conformité** normative des hand-off.
|
**conformité** normative des hand-off.
|
||||||
|
|
||||||
## Verdict agrégé courant (source `qa/regression/out/regression_run.json`)
|
## Verdict agrégé courant (source `qa/regression/out/regression_run.json`)
|
||||||
**24 suites gated · 625 tests · 608 passés · 0 échec · 0 erreur → verdict `PASS`.**
|
**24 suites gated · 629 tests · 612 passés · 0 échec · 0 erreur → verdict `PASS`.**
|
||||||
Ce compte est **découvert automatiquement depuis le CI** (`q4lib.registry.parse_ci`,
|
Ce compte est **découvert automatiquement depuis le CI** (`q4lib.registry.parse_ci`,
|
||||||
réutilisé sans duplication) — jamais compté à la main.
|
réutilisé sans duplication) — jamais compté à la main.
|
||||||
Les **17 tests restants sont ignorés** (`skipped`) : ce sont les *oracles optionnels*
|
Les **17 tests restants sont ignorés** (`skipped`) : ce sont les *oracles optionnels*
|
||||||
|
|||||||
@@ -0,0 +1,308 @@
|
|||||||
|
# Activity Log · 2026-08-11 · Claude Code DTP Worker
|
||||||
|
|
||||||
|
## Session `20260811_015744` — FIX · CI RED → VERT · 2 régressions induites par les commits root V18 (archivage V10/V11 + 4 docs REFERENCE root-owned mode 600)
|
||||||
|
|
||||||
|
**Constat au démarrage.** `./run_ci.sh` = **31 PASS · 2 FAIL · 0 SKIP** (régression vs la baseline 33/0/0 du 2026-08-06). Deux gates rouges : `check-docs` et `check-readme-claims`. Cause racine commune : les **commits root de Michel** des 2026-08-10 (directives V18 + `f316060 archive · V10 V11 directives déprécies · seule V18 active`) ont muté l'arbre sans que les gates suivent.
|
||||||
|
|
||||||
|
**Régression 1 · `check_docs` — lien pendant.** `README.md:88` liait `DIRECTIVE_WORKFLOW_FAISABILITE_V10_20260803.md`, **supprimé** par l'archivage V18 (V10 n'est même plus dans `_archived_versions/` — seul `V11 .archived` y subsiste). Lien cassé → gate rouge.
|
||||||
|
- **Fix (édition worker légitime, doc du worker).** Repointé l'entrée README vers la directive **active** `DIRECTIVE_V18_MASTER_FEASIBILITY_ENGINE_20260810.md` (Master Institutional Feasibility & Bankability Engine · 18 sections · REMPLACE V12), en notant que le versionnage workflow ex-V10/V11/V12 est déprécié/archivé au profit de V18 (`_archived_versions/`). Le fragment-slug de section `#directives-michel-input-specs-datés` (cf. mémoire `markdown-anchor-fragment-integrity`) est intact.
|
||||||
|
|
||||||
|
**Régression 2 · `check_readme_claims` — 4 docs root-owned illisibles.** Le scan « VPS infra » énumère `git ls-files *.md`, ouvre chaque fichier en Python (`open()`) et vérifie IP/conteneurs. Or 4 nouveaux fichiers **tracked** sont **root-owned mode 600** (commits REFERENCE de Michel, illisibles ET non éditables par le worker `otoclaude`) : `AUDIT_FAISABILITE_DEEP_20260810.md`, `AUDIT_P1_COMPTE_CLIENT_20260810.md`, `DIRECTIVE_COMPTE_CLIENT_COURRIELS_20260810.md`, `GO_SIGNAL_20260810_1540.md`. `open()` lève `PermissionError` → `bad()` → gate rouge.
|
||||||
|
- **Précédent appliqué (mémoire `guard-tracked-files-exclusion`).** `guard_constraints.sh` gère déjà exactement cette classe : il **exclut** `DIRECTIVE_*.md` / `AUTORISATIONS_*.md` / `OTO_DESIGN_SYSTEM_*.md` de son scan et lit via `grep 2>/dev/null` (tolère l'illisible → aucun rouge). `check_readme_claims` n'avait pas l'équivalent.
|
||||||
|
- **Fix (chirurgical, honnête).** Dans la boucle VPS-infra : `except PermissionError` **spécifique** → note jaune `⋯ root-owned illisible (REFERENCE Michel · hors périmètre worker) — non scanné` + `continue`. **Tout autre `OSError` reste `bad()`** — un fichier worker-owned corrompu/absent RED toujours. La garde anti-évaporation (`ip_seen==0`/`cont_seen==0` sur le corpus **lisible**) préserve la couverture SSOT de l'identité VPS : l'IP `153.75.250.214` + les 2 conteneurs restent exigés cités quelque part dans les docs lisibles (11 ✓ VPS-infra confirmés post-fix). Distinction clé : seul `PermissionError` (= « pas notre fichier à auditer ») est toléré, pas les erreurs de lecture génériques.
|
||||||
|
|
||||||
|
**Pourquoi ne PAS éditer les 4 docs / ne PAS les untrack.** Root-owned mode 600, non éditables par le worker (#8 · docs de Michel) ; les untrack serait détruire des commits REFERENCE de Michel. La bonne réponse = rendre le gate robuste à cette classe (comme le précédent guard), pas toucher aux fichiers de Michel.
|
||||||
|
|
||||||
|
**Vérif.** `check_docs` PASS ; `check_readme_claims` PASS (les 4 docs en ⋯, non-fatals) ; **`./run_ci.sh` = 33 PASS · 0 FAIL · 0 SKIP** rétabli. Aucune commande VPS (#8). Fichiers : `README.md` + `ci/check_readme_claims.sh` + ce journal.
|
||||||
|
|
||||||
|
**Contexte V18 (prochaine étape, hors ce commit).** Le GO signal `V18_GO_SIGNAL_DEVELOPMENT_20260810.md` fixe la **PREMIÈRE ACTION OBLIGATOIRE** = produire `OTO_V18_MIGRATION_ARCHITECTURE_AUDIT` (audit V12→V18, 25-26 points) **avant tout code**, puis validation Michel, puis Phase 1 (Master Project Intake/Data Model). Ce document n'existe pas encore dans le repo ; le GO signal note « en cours de préparation par Claude en dispatch ». Les docs d'audit deep de Michel (`AUDIT_FAISABILITE_DEEP`, etc.) sont root-owned illisibles par le worker → un audit worker devra se fonder sur le code V12 **lisible** (`faisabilite/generator` + `faisabilite/bancable`, 4 volets → mapping 18 sections) et la directive V18 lisible. Signalé ici, non entamé dans ce commit (fix CI = priorité, unité verte discrète).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Session `20260811_022753` — LIVRABLE PRÉALABLE V18 · production de `OTO_V18_MIGRATION_ARCHITECTURE_AUDIT_20260810.md` (audit V12→V18 avant tout code)
|
||||||
|
|
||||||
|
**Tâche prioritaire identifiée.** CI vert au démarrage (`./run_ci.sh` = **33 PASS · 0 FAIL · 0 SKIP**, baseline rétablie session précédente). La prochaine tâche non-complétée la plus prioritaire n'est pas dans la roadmap 8-semaines classique mais dans le **GO signal V18** : la **PREMIÈRE ACTION OBLIGATOIRE** (directive V18 §PREMIÈRE ACTION + §INTERDICTIONS « NE PAS coder avant l'audit ») = produire l'**audit de migration V12→V18**. Le GO signal le disait « en cours de préparation par Claude en dispatch » mais le fichier **était absent du repo** (`git ls-files | grep -i migration` = vide). C'est le **gate bloquant** de toute la séquence V18 (audit → validation Michel → Phase 1). Rien d'autre ne peut avancer côté moteur avant lui.
|
||||||
|
|
||||||
|
**Cartographie préalable (code lisible uniquement, anti-invention #6).** Inventaire réel du « V12 » lisible dans `05_deliverables_mvp/faisabilite/` : **2 modules** — `generator/` (4 volets · 446 LOC lib · 17 tests · `model.py CANONICAL` impose 3 %/8.5 %/52 %/USD+DOP/Cardnet/Letter US, jamais du brief) + `bancable/` (dossier financier FR/EN/ES · 640 LOC lib · 22 tests · `finance.py` = sourced/typologies/derived, chaque valeur publie sa formule, opérande manquant ⇒ `null`). Arborescence data_room V12 (`_META/`+`10_masterplan/`→`50_financier_bancable/`) mappée aux 18 sections V18. **Confirmé grep :** aucun `DSCR/LTV/LTC` ni DCF multi-période dans `finance.py` → écart moteur Financial/Bankability (4/8) identifié sans le deviner.
|
||||||
|
|
||||||
|
**Contenu de l'audit (12 points de couverture, dérivés structurellement des directives lisibles).** §1 Inventaire V12 réel · §2 Cible V18 (18 sect./15 moteurs/7 CP/3 sorties/Master Intake) · §3 **Mapping 18 sections point-par-point** (verdict : 2 ✅ · 7 🟠 · 9 🔴 — socle réutilisable = Programme(3)+Bankability(15)) · §4 Data model « One Master Dataset » (V12 le respecte déjà : bancable consomme le MÊME brief.json ; Master Intake A1-A20 = sur-ensemble strict rétro-compat) · §5 Écart financier le plus technique (DCF/ratios absents · **risque d'invention max** → bloquer moteur 4/8 sur formules Michel) · §6 Checkpoints CP0-CP6 (workflow ERPNext natif) · §7 3 sorties = projections · §8 **Vérif préservation des 10 non-négociables CLAUDE.md** (aucun menacé si canoniques restent imposés-générateur) · §9 Addendum Sec.60 « HELIOS RD SRL only » + filtre anti-fuite vocabulaire IA en publication (règle 60.31) · §10 8 risques + mitigations (R1 invention formules · R2 2e base · R3 écrasement baseline = les 3 rouges) · §11 séquence 15 phases post-validation · §12 4 arbitrages Michel avant Phase 1.
|
||||||
|
|
||||||
|
**Honnêteté de sourçage (déclarée, non cachée · §0).** La « directive complète 57 chapitres + 5 annexes » et les audits deep de Michel sont **root-owned mode 600 illisibles** par le worker `otoclaude` (#8) → l'audit couvre la **structure lisible** ; les détails fins A1-A20 restent à confronter par Michel. La liste « 25 points » exacte étant dans la directive non lisible, l'audit organise **26 points de couverture sémantiquement équivalents** — divergence de numérotation signalée, non substantielle. **Aucun contenu deviné.**
|
||||||
|
|
||||||
|
**Interdiction respectée.** Conformément à la directive (« NE PAS coder avant l'audit ») et à la séquence GO signal (audit → **validation Michel** → Phase 1), **aucune ligne de code moteur V18 produite** dans ce commit. Le livrable EST le document. La suite est suspendue à l'approbation de Michel (§12 : approuver l'audit · fournir les formules financières · confirmer sur-ensemble Master Intake · trancher périmètre juridique Section 13).
|
||||||
|
|
||||||
|
**Vérif.** `./run_ci.sh` = **33 PASS · 0 FAIL · 0 SKIP** (inchangé — le nouveau `.md` passe `check_docs`/`guard_constraints` : chemins en code-spans donc non link-checkés, aucun URL/usage interdit). Aucune commande VPS (#8), aucune API externe. Fichiers : `OTO_V18_MIGRATION_ARCHITECTURE_AUDIT_20260810.md` (NEUF) + entrée README (bloc Directives Michel, sous l'entrée V18) + ce journal.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Session `20260811_025754` — CONSOLIDATION · les 3 arbitrages Michel bloquant la séquence V18 remontés dans `OPEN_DECISIONS_REGISTER.md` (D-06→D-08)
|
||||||
|
|
||||||
|
**État au démarrage.** `./run_ci.sh` = **33 PASS · 0 FAIL · 0 SKIP** (baseline verte). La séquence moteur V18 est **intégralement bloquée** : le GO signal impose audit → **validation Michel** → Phase 1 (`V18_GO_SIGNAL_DEVELOPMENT_20260810.md:79-84`) et la directive interdit de coder avant l'audit approuvé (`DIRECTIVE_V18_MASTER_FEASIBILITY_ENGINE_20260810.md:90-91`). L'audit **est** produit (commit `de837fa`) mais en attente de Michel + les formules financières manquent (§5 · risque d'invention #6 max). **Aucun code moteur V18 n'est légitime tant que ces arbitrages ne sont pas rendus** — travailler sur le moteur violerait la directive et #6.
|
||||||
|
|
||||||
|
**Tâche prioritaire non-bloquée identifiée.** L'audit §12 énumère **4 arbitrages Michel avant Phase 1**, mais ils n'étaient **consignés nulle part dans la punch-list produit**. Or `OPEN_DECISIONS_REGISTER.md` (dernière MàJ 2026-08-05, D-01→D-05) **est** exactement le point de consolidation prévu — l'audit §12.4 (:216) **pointait déjà** explicitement vers ce registre pour l'arbitrage juridique. Consolider les items V18 ici est donc conforme à la fonction du registre (« regroupe et source, ne tranche pas ») et à la discipline #5 (ne pas re-surfacer en doublon, pointer ici). **Non-bloqué, sans invention, doc worker éditable.**
|
||||||
|
|
||||||
|
**Fait.**
|
||||||
|
- **D-06 · 🟠 Approbation de l'audit** = gate d'entrée de TOUTE la séquence moteur. Sourcé GO signal `:79-84` (séquence à validation) + directive `:90-91` (« NE PAS coder avant l'audit ») + audit §12 (:207-218).
|
||||||
|
- **D-07 · 🟠 Formules financières absentes** (DCF · IRR/VAN · DSCR/LTV/LTC) → moteurs 4/8 bloqués, **risque d'invention #6 le plus grave (R1 🔴)**. Sourcé audit §5 (:102-114) + §10-R1 (:182) + §12.2 (:214) ; `grep` confirme `finance.py` = snapshot sans DSCR/LTV/LTC. Hypothèse déclarée : formules peut-être dans les docs deep **root-owned illisibles** (#8).
|
||||||
|
- **D-08 · 🟠 Master Intake A1-A20 = sur-ensemble strict du `brief.json`** (éviter 2e base R2 🔴 · préserver parser). Sourcé audit §4 (:86-100) + §10-R2 (:183) + §11 (:197) + §12.3 (:215).
|
||||||
|
- **D-01 enrichi** — l'arbitrage juridique Section 13 (§12.4 audit) **est** l'item D-01 existant (Promesa/Fideicomiso/HOA), désormais **remonté dans le chemin critique V18**. Cross-link ajouté, **pas de doublon** (#5).
|
||||||
|
- En-tête « Mise à jour » repointé 2026-08-11 avec note du bloc V18.
|
||||||
|
|
||||||
|
**Honnêteté de sourçage.** Toutes les citations `file:line` du registre ont été **vérifiées** contre la lecture réelle des fichiers cités (mémoire `prose-facts-vs-numeric-drift` : vérifier les citations verbatim). L'audit doc est worker-owned/lisible/git-tracked ; le GO signal et la directive sont lisibles. Aucun item n'est **tranché** — le worker les surface, Michel décide.
|
||||||
|
|
||||||
|
**Vérif.** `./run_ci.sh` = **33 PASS · 0 FAIL · 0 SKIP** (inchangé — ajouts en code-spans `file:line`, non link-checkés ; aucun décompte de gate ne parse le nombre d'items D-xx du registre — `grep` ci/ confirme : README pointe le fichier sans compter). Aucune commande VPS (#8), aucune API externe. Fichiers : `05_deliverables_mvp/OPEN_DECISIONS_REGISTER.md` + ce journal.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Session `20260811_032800` — CANAL STAKEHOLDER · rapport quotidien `2026-08-11` (currency + remontée du chemin critique V18 bloqué à Michel)
|
||||||
|
|
||||||
|
**État au démarrage.** `./run_ci.sh` = **33 PASS · 0 FAIL · 0 SKIP** (baseline verte). La séquence **moteur V18 reste intégralement bloquée** (D-06→D-08 en attente de Michel — cf. sessions précédentes) : aucun code moteur V18 n'est légitime tant que l'audit n'est pas approuvé et que les formules financières manquent (#6 · directive `:90-91`). Travailler sur le moteur violerait la directive.
|
||||||
|
|
||||||
|
**Tâche prioritaire non-bloquée identifiée.** Le **canal stakeholder** `05_deliverables_mvp/daily_reports/` s'arrêtait au **2026-08-06** (HEAD `a8342e9`). Depuis, **trois jalons worker** majeurs ont porté l'arbre à `18d8763` (fix CI RED→vert `0b453c5` · audit V18 `de837fa` · registre décisions `18d8763`) **sans jamais atteindre le canal roadmap de Michel**. Or c'est précisément le canal qui met les **arbitrages Michel dans son champ de vision** (mémoire `two-logging-channels` : daily_reports = snapshot stakeholder, à ne pas laisser lapser, chaque figure sourcée d'un artefact commité). Produire le rapport `2026-08-11` = **non-bloqué, sans invention, doc worker** — et surtout, remonter explicitement à Michel que **toute la séquence moteur attend ses décisions**.
|
||||||
|
|
||||||
|
**Fait.** Rapport `2026-08-11.md` : (a) currency du canal 08-06→18d8763 avec table des 3 jalons + opposabilité au merge ; (b) **section ⛔ chemin critique bloqué** — table D-06→D-08 + D-01 avec la décision attendue de chaque item et pourquoi elle bloque, + encart action Michel (escalation WhatsApp/email de la roadmap) ; (c) **État courant re-dérivé d'artefacts commités** au HEAD `18d8763`.
|
||||||
|
|
||||||
|
**Honnêteté de sourçage (tous chiffres re-calculés ce jour, aucun figé · #6).** Gate `33/0/0` = `run_ci.sh` · 8 statiques = `git ls-files 'ci/*.sh'` hors `lib.sh` · 25 suites = jobs `*-tests` `gate.needs` · régression **625/608/17/0-PASS** = `regression_run.json` `totals` (lu ce jour — a **évolué** 624→625 / 607→608 depuis le 08-06 via wiring `brief.schema.json`, la mémoire `regression-baseline-17-skips-by-design` disait 624/607 = **stale**, l'artefact fait foi) · audit 4Big **PASS · 24 modules · min 100** + bijection **24↔24 `ok`** = `quality_report.json` (`verdict`/`modules`/`coverage`). Les citations `file:line` V18 (GO signal `:79-84`, directive `:90-91`) reprises du registre déjà vérifié.
|
||||||
|
|
||||||
|
**Vérif.** `./run_ci.sh` = **33 PASS · 0 FAIL · 0 SKIP** (inchangé — le nouveau `.md` passe `check_docs` : chemins en code-spans, non link-checkés · `guard_constraints` : aucun URL/usage interdit). **0 code moteur V18** (bloqué #6/directive), **0 fichier de production édité**, **0 artefact reconstruit**, **0 gate** (#5). Aucune commande VPS (#8), aucune API externe. Fichiers : `05_deliverables_mvp/daily_reports/2026-08-11.md` (NEUF) + ce journal.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Session `20260811_035804` — FIX exactitude · claim LOC stale dans l'audit V18 (`generator` 446→622, contradiction interne avec son propre total)
|
||||||
|
|
||||||
|
**État au démarrage.** `./run_ci.sh` = **33 PASS · 0 FAIL · 0 SKIP** (baseline verte). Séquence moteur V18 toujours **intégralement bloquée** (D-06→D-08 en attente Michel · #6/directive `:90-91`) — aucun code moteur légitime. Tâche non-bloquée = audit d'exactitude d'un livrable worker récent.
|
||||||
|
|
||||||
|
**Défaut trouvé (classe `prose-facts-vs-numeric-drift`, sous-classe *present-tense-current-state = FIX*).** L'audit V18 fraîchement produit (`de837fa`, `OTO_V18_MIGRATION_ARCHITECTURE_AUDIT_20260810.md`) contient un claim numérique **hardcodé, non gaté et faux** : §1 table (`:30`) affirmait `generator/genlib` = **446 LOC** avec l'énumération explicite `(model+renderer+scorer+__init__)`. Le compte réel (`wc -l generator/genlib/*.py`) = **622** (`model 113 + renderer 315 + scorer 176 + __init__ 18`). Le `446` est une valeur **stale** — reprise d'un état antérieur du module / de la mémoire `module-suite-teeth-mutation` (« generator 446 LOC ») — le renderer a grossi depuis.
|
||||||
|
|
||||||
|
**Preuve interne décisive (le doc se contredit lui-même).** L'audit §0 (`:17`) donne un total « **1262 LOC lib** ». Or `446+640=1086 ≠ 1262`, tandis que `622+640 = 1262` **exactement**. Donc le total §0 était déjà calculé sur le **622 réel** ; seule la cellule table portait le `446` stale. La correction 446→622 **résout la contradiction interne** au lieu d'en créer une. Les autres chiffres du bloc sont **exacts et conservés** : `bancable/banclib` = 640 (`10+40+186+163+241`) ✓ · tests `17` + `22` = `39` ✓ (`python3 -m unittest discover` re-lancé sur les deux modules).
|
||||||
|
|
||||||
|
**Fix (chirurgical, 1 cellule).** `446` → `622` dans la table §1 de l'audit. **Aucun gate ajouté** — occurrence isolée d'origine (mémoire : ne pas gater un typo isolé, #5) ; le doc n'est parsé par aucun check (chemins/chiffres en prose, non link-checkés). Le doc audit est worker-owned/lisible/git-tracked (éditable, contrairement aux 4 docs deep root-owned #8).
|
||||||
|
|
||||||
|
**Ligne 26 de ce journal (même jour) laissée telle quelle — correction *forward*.** Le log de la session `022753` (`:26`, « Cartographie préalable … 446 LOC lib ») porte le même `446` stale. Convention `two-logging-channels` : le journal est un récit de session append-only ; on **corrige en avant** (cette entrée acte l'erreur et le vrai chiffre 622) plutôt que de réécrire l'historique. Le livrable authoritative (l'audit) est, lui, remis exact.
|
||||||
|
|
||||||
|
**Vérif.** `./run_ci.sh` = **33 PASS · 0 FAIL · 0 SKIP** (inchangé). **0 code moteur V18** (bloqué), **0 module de production touché**, **0 artefact reconstruit**, **0 gate** (#5). Aucune commande VPS (#8), aucune API externe. Fichiers : `OTO_V18_MIGRATION_ARCHITECTURE_AUDIT_20260810.md` (1 cellule) + ce journal.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Session `20260811_042804` — VÉRIF exactitude gate-doc V18 + Annexe A reproductible (audit auto-auditable anti-drift #6)
|
||||||
|
|
||||||
|
**État au démarrage.** `./run_ci.sh` = **33 PASS · 0 FAIL · 0 SKIP** (baseline verte). Séquence moteur V18 toujours **intégralement bloquée** : GO signal impose audit → **validation Michel** → Phase 1, directive interdit de coder avant l'audit approuvé (`:90-91`), formules financières manquantes (D-06→D-08 en attente Michel). **Aucun code moteur légitime.** Les 2 nouvelles directives 08-10 (`OTO_3D_STUDIO`, `COMPTE_CLIENT_COURRIELS`) référencent des chemins VPS/RunPod/Blender **hors périmètre repo + hors roadmap 8-sem** → non prises. Tâche non-bloquée = audit d'exactitude du livrable-gate le plus critique.
|
||||||
|
|
||||||
|
**Vérification menée (le doc que Michel lit pour décider).** Confronté **tous les claims factuels vérifiables** de `OTO_V18_MIGRATION_ARCHITECTURE_AUDIT_20260810.md` au code réel :
|
||||||
|
- `generator/genlib` = **622 LOC** ✓ (`wc -l`) · `bancable/banclib` = **640 LOC** ✓ · total **1262** ✓
|
||||||
|
- tests **17** (générateur, `Ran 17 tests`) + **22** (bancable, `Ran 22 tests`) = **39** ✓ *(re-exécutés — un premier comptage par grep `... ok` avait faussement donné 21 ; la ligne `Ran N tests` fait foi = 22)*
|
||||||
|
- 4 schémas machine (`version`/`brief`/`bancable`/`projets_master`) tous présents ✓
|
||||||
|
- `finance.py` = `sourced`/`typologies`/`derived`/`missing_fields` ✓ · **aucun `DSCR`/`LTV`/`LTC`/`IRR`/`VAN`/`DCF`** (grep vide) ✓ — l'écart moteur 4/8 est réel, pas deviné
|
||||||
|
- `legal/confotur/out/MANIFEST.json` présent (CONFOTUR seul) ✓ · bancable sort `50_financier_bancable/{fr,en,es}.md` + manifeste ✓
|
||||||
|
- commits directives sources `f00df20` (V18) + `be8bfda` (addendum Sec.60) ✓
|
||||||
|
|
||||||
|
**Résultat : l'audit est factuellement SAIN** — aucun défaut résiduel (le seul défaut historique, `LOC 446→622`, a été corrigé session `035804`, commit `c3f5664`). Figures stakeholder également recoupées aux artefacts commités : `regression_run.json totals` = **625/608/17/0-red** ✓ · `quality_report.json` = **PASS · 24 modules · bijection 24↔24 `ok`** ✓ (daily report `2026-08-11` confirmé exact).
|
||||||
|
|
||||||
|
**Contribution (non-bloquée, sans invention).** Le claim `446` a **déjà dérivé une fois** parce que les chiffres de l'audit étaient des **valeurs nues sans source rejouable** (classe `prose-facts-vs-numeric-drift` · `derived-arithmetic-integrity-sweep`). Ajout d'une **Annexe A · Vérification reproductible** : table appariant **chaque** chiffre factuel à la **commande exacte qui le re-dérive** + valeur attendue. Le document devient **auto-auditable** — Michel (ou un autre agent) peut vérifier indépendamment sans faire confiance à la prose. Chaque valeur y est celle re-exécutée ce jour ; portée strictement limitée au **lisible** (#8, redit dans l'annexe). Aucun nouveau fait inventé : l'annexe ne fait que documenter les commandes de vérification déjà exécutées.
|
||||||
|
|
||||||
|
**Vérif.** `./run_ci.sh` = **33 PASS · 0 FAIL · 0 SKIP** (inchangé — l'annexe passe `check_docs` : chemins/commandes en code-spans, non link-checkés · `guard_constraints` : aucun URL/usage interdit). **0 code moteur V18** (bloqué), **0 module de production touché**, **0 artefact reconstruit**, **0 gate ajouté** (#5 — occurrence isolée, doc non parsé par aucun check). Aucune commande VPS (#8), aucune API externe. Fichiers : `OTO_V18_MIGRATION_ARCHITECTURE_AUDIT_20260810.md` (Annexe A) + ce journal.
|
||||||
|
|
||||||
|
## Session `20260811_045813` — DOC AGENT.md · bannière statut V18 dans la fiche `faisabilite/` (le module le plus touché par le pivot, muet sur la migration)
|
||||||
|
|
||||||
|
**État au démarrage.** `./run_ci.sh` = **33 PASS · 0 FAIL · 0 SKIP** (baseline verte). Séquence moteur V18 toujours **intégralement bloquée** en attente Michel (D-06→D-08 · directive `:90-91` « NE PAS coder avant l'audit approuvé » · #6) — **aucun code moteur légitime**. Les sessions worker récentes convergeaient vers des sweeps « CLEAN · NON gate · 0 édition de prod » de plus en plus ésotériques (rendement décroissant). Tâche non-bloquée à **valeur produit réelle** recherchée plutôt qu'un énième sweep zéro-édition → repli explicite de la mission (« améliorer la doc d'un AGENT.md existant »).
|
||||||
|
|
||||||
|
**Défaut trouvé (classe accuracy/complétude des fiches · lacune informationnelle).** La fiche [`03_agents/faisabilite/AGENT.md`](../03_agents/faisabilite/AGENT.md) — le **module phare le plus directement impacté** par le pivot — est **entièrement V12-centrée et totalement muette sur la V18**. Un lecteur (agent ou humain) de cette fiche aujourd'hui n'a **aucune indication** que, le 2026-08-10, Michel a émis `DIRECTIVE_V18_MASTER_FEASIBILITY_ENGINE` qui **remplace** le modèle « 4 volets » décrit, qu'un audit de migration existe, ni que **toute la séquence moteur est bloquée** sur ses arbitrages. Écart de réalité-courante significatif sur le doc le plus consulté du domaine.
|
||||||
|
|
||||||
|
**Fix (doc worker · sourcé · zéro invention #6).** Bannière `> ⚠️ Statut migration V18` insérée en **tête de fiche** (juste après la ligne Rôle · visibilité maximale), avec **3 liens résolus** vers les sources lisibles commitées : la directive V18, l'audit de migration `OTO_V18_MIGRATION_ARCHITECTURE_AUDIT`, et le `OPEN_DECISIONS_REGISTER` (D-06 approbation audit · D-07 formules DCF/IRR/VAN/DSCR/LTV/LTC absentes · D-08 périmètre Master Intake). Libellés D-xx **vérifiés verbatim** contre le registre (mémoire `prose-facts-vs-numeric-drift`). La bannière **cadre explicitement** la fiche V12 en dessous comme « l'état commité courant, pas la cible finale V18 » et rappelle que le socle `generator`/`bancable` reste réutilisable — cohérent avec l'audit §3 (socle réutilisable) sans en recopier les décomptes internes non gatés.
|
||||||
|
|
||||||
|
**Sûreté des gates (vérifiée avant édition).** `ci/check_readme_claims.sh` parse la **colonne « Tests »** des tables de livrables (cellules `(\d+) tests`) + les attrs de rôles (mémoire `agent-fiche-role-attrs-gated`) ; la bannière est de la **prose hors-table sans compte recomputé** (aucun `N tests`, aucun attr de rôle, aucun décompte gaté) → surface non parsée. `check_docs` : les 3 liens ciblent des fichiers **existants sur disque** (directive root-owned mais lisible/tracked, déjà liée depuis `README.md:88` ; audit + registre worker-owned) ; aucun fragment-anchor. `guard_constraints` : aucun URL/usage interdit (DCF/IRR/DSCR/LTV/LTC ≠ termes proscrits).
|
||||||
|
|
||||||
|
**Incident auto-détecté (RED induit dans ce journal, corrigé avant push).** Première rédaction du lien vers la fiche dans ce log avec le préfixe `../../` **recopié de la bannière** — or la bannière vit à `03_agents/faisabilite/` (2 niveaux) tandis que ce journal est à `05_activity_log/` (**1 niveau**) → `check_docs` a signalé « lien cassé `../../03_agents/faisabilite/AGENT.md` » (RED transitoire capté par `run_ci.sh`). Corrigé en `../03_agents/…`. Leçon : la profondeur relative d'un lien dépend du fichier **hôte**, pas de la source copiée (mémoire `acceptance-evidence-paths-deliverables-root` — même piège de base relative). Le commit fautif n'a **jamais été poussé** ; amend appliqué sur un arbre vert.
|
||||||
|
|
||||||
|
**Vérif.** `./run_ci.sh` = **33 PASS · 0 FAIL · 0 SKIP** (rétabli après correction du lien). **0 code moteur V18** (bloqué), **0 module de production touché**, **0 artefact reconstruit**, **0 gate ajouté** (#5 — occurrence isolée, doc non parsé pour cette surface). Aucune commande VPS (#8), aucune API externe. Fichiers : `03_agents/faisabilite/AGENT.md` (bannière) + ce journal.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Session `20260811_052814` — DOC AGENT.md · bannière statut V18 dans la fiche `bim/` (2e module le plus impacté par le pivot — 7/18 sections « + BIM » + Clash Detection — muet dessus)
|
||||||
|
|
||||||
|
**État au démarrage.** `./run_ci.sh` = **33 PASS · 0 FAIL · 0 SKIP** (baseline verte). Séquence moteur V18 toujours **intégralement bloquée** en attente Michel (D-06→D-08 · directive `:90-91` « NE PAS coder avant l'audit approuvé » · #6) — **aucun code moteur légitime**. Roadmap 8-sem : les 24 modules commités sont tous **PASS** (`quality_report.json` verdict PASS · 24↔24 bijection). Les 2 nouvelles directives 08-10 (`OTO_3D_STUDIO`, `COMPTE_CLIENT_COURRIELS`) restent hors périmètre repo (chemins VPS/RunPod `/opt/oto/3d/`, sprints B-E) → non prises. Tâche non-bloquée à **valeur produit réelle** : poursuivre l'alignement des fiches AGENT.md sur le pivot V18 (repli explicite de mission — « améliorer la doc d'un AGENT.md existant »).
|
||||||
|
|
||||||
|
**Défaut trouvé (classe accuracy/complétude · lacune informationnelle · continuité de la session `045813`).** La session précédente a doté [`faisabilite/AGENT.md`](../03_agents/faisabilite/AGENT.md) d'une bannière V18. Or la fiche [`bim/AGENT.md`](../03_agents/bim/AGENT.md) est **le 2e module le plus directement impacté par le pivot** et en était **totalement muette**. Sous-estimation majeure : la fiche décrit le BIM comme alimentant **un seul « volet Ingénierie »** du modèle 4-volets — alors que V18 fait du BIM le **cœur de 7 des 18 sections** (Archi/Structure/Plomberie/Électrique/HVAC « + BIM » · **Clash Detection** §9 · Environnementale + BIM VRD §14), le **moteur 7 « BIM/Clash/Quantity »** de l'ordre de dev imposé, avec **2 checkpoints humains adossés (CP1 BIM Geometry · CP3 Clash Resolution)**. Un lecteur de la fiche n'avait aucune indication de cet élargissement de périmètre.
|
||||||
|
|
||||||
|
**Fix (doc worker · sourcé · zéro invention #6).** Bannière `> ⚠️ Statut migration V18` insérée en tête de fiche (après le paragraphe Rôle · visibilité max), **3 liens résolus** vers sources lisibles commitées : directive V18, audit de migration, `OPEN_DECISIONS_REGISTER` (D-06 approbation audit · D-08 périmètre Master Intake — les 2 items qui bloquent en amont le BIM ; D-07 formules financières écarté car non-BIM). **Chaque claim recoupé au code lisible et à l'audit :** les « 7 sections + BIM », « moteur 7 », « CP1/CP3 » proviennent verbatim de la directive V18 (`:24-40`, `:66-84`) et de l'audit §3 (`:66-76` verdicts 🟠/🔴) + §6 (`:125-128` checkpoints) — **aucune valeur devinée**. La bannière cadre explicitement la fiche V12 en dessous comme « l'état commité courant, pas la cible finale V18 », cohérent avec la bannière sœur de `faisabilite/`.
|
||||||
|
|
||||||
|
**Sûreté des gates (vérifiée avant édition).** `check_readme_claims` parse les cellules `(\d+) tests` + attrs de rôles → la bannière est de la prose hors-table sans compte recomputé (surface non parsée). `check_docs` : les 3 liens `../../` ciblent des fichiers **existants** (le fiche `bim/` est à 2 niveaux comme `faisabilite/` — profondeur `../../` correcte, cf. mémoire `acceptance-evidence-paths-deliverables-root` ; le piège de la session `045813` où `../../` avait été recopié dans un log à 1 niveau ne se reproduit pas ici : la bannière ET ses liens vivent bien à 2 niveaux). `guard_constraints` : aucun URL/usage interdit (BIM/Clash/HVAC/DCF ≠ termes proscrits).
|
||||||
|
|
||||||
|
**Vérif.** `./run_ci.sh` = **33 PASS · 0 FAIL · 0 SKIP** (inchangé). **0 code moteur V18** (bloqué), **0 module de production touché**, **0 artefact reconstruit**, **0 gate ajouté** (#5 — occurrence isolée, doc non parsé pour cette surface). Aucune commande VPS (#8), aucune API externe. Fichiers : `03_agents/bim/AGENT.md` (bannière) + ce journal.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Session `20260811_055819` — DOC module · bannière statut V18 dans le README du module `bancable` (la graine V12 des moteurs financiers 4/8 — le risque de migration R1 🔴 le plus grave — muet dessus)
|
||||||
|
|
||||||
|
**État au démarrage.** `./run_ci.sh` = **33 PASS · 0 FAIL · 0 SKIP** (baseline verte). Séquence moteur V18 toujours **intégralement bloquée** en gouvernance : D-06 (approbation de l'audit de migration par Michel) est le gate d'entrée de TOUTE la séquence ; D-07 (formules DCF/IRR/VAN/DSCR/LTV/LTC absentes) et D-08 (Master Data Model sur-ensemble strict) bloquent en aval (`OPEN_DECISIONS_REGISTER.md` · directive `:90-91` « NE PAS coder avant l'audit » · #6). Confirmé aussi via `V18_GO_SIGNAL_DEVELOPMENT_20260810.md:79-84` : le GO « n'active PAS le code direct », il active une **séquence à validation par étape**. Les 2 nouvelles directives 08-10 (`OTO_3D_STUDIO`, `COMPTE_CLIENT_COURRIELS`) restent hors périmètre repo (chemins VPS/RunPod). Tâche non-bloquée à **valeur produit réelle** : poursuivre l'alignement V18 des surfaces de doc — mais **au bon endroit et sans sur-attribuer**.
|
||||||
|
|
||||||
|
**Piège d'exactitude écarté avant d'agir (#6).** Candidat initial = bannière V18 sur la fiche `crm/AGENT.md` (module `crm/financement_bancaire`). **Rejeté** : `crm/financement_bancaire` est le **parcours hypothécaire CLIENT** (apport 20 %/30 % · Ley 189-11 · gate 4 conditions), **PAS** le moteur financier projet. La cartographie de l'audit elle-même (`OTO_V18_MIGRATION_ARCHITECTURE_AUDIT §3` :74,:77 et §5 :108-109) mappe les **moteurs Financial (4)** et **Bankability (8)** au module **`faisabilite/bancable`**, pas au crm. Bannière « moteur 4/8 » sur la fiche crm = **sur-attribution inventée** → écartée. (La seule ouverture V18-adjacente du crm — D-02, condition #4 humaine superséée par audit IA — est **déjà surfacée** dans sa fiche `:52-57`, ne pas re-litiger #5.)
|
||||||
|
|
||||||
|
**Défaut trouvé (classe accuracy/complétude · lacune informationnelle · le VRAI locus).** Le module [`faisabilite/bancable/README.md`](../05_deliverables_mvp/faisabilite/bancable/README.md) — la **graine V12 réelle** des moteurs financiers V18 (Section 15 Bankability « le plus mûr » du mapping §3 :77 · Section 12 Financier/DCF partielle :74) — était **entièrement V12-centré et totalement muet sur la V18**. Or c'est précisément le module au **cœur du risque de migration le plus grave** : l'audit classe **R1 🔴** (:182) « coder un moteur 4/8 en **inventant** des formules absentes des docs lisibles » comme le risque de plus haute gravité, mitigation = **bloquer sur validation Michel des formules DCF/ratios** (§5 :108-109 · §12.2 :214 · D-07). Un développeur qui reprend ce module post-approbation atterrit **d'abord** sur ce README — et n'y avait **aucune indication** qu'il touche le point le plus dangereux de la migration.
|
||||||
|
|
||||||
|
**Fix (doc worker · sourcé · zéro invention #6).** Bannière `> ⚠️ Statut migration V18` insérée en tête de corps (juste après le blockquote roadmap ancré Sprint 3, avant le paragraphe « Remplit le répertoire… » · visibilité max sans casser l'ancre roadmap). Chaque claim recoupé verbatim au code lisible et à l'audit : « graine V12 des moteurs 4/8 » ← mapping §3 :74/:77 ; « formules DCF/IRR/VAN/DSCR/LTV/LTC absentes du code lisible » ← §5 :108-109 + Annexe A :236 (`grep` sur `banclib/` rend vide — **fait re-vérifiable, pas deviné**) ; « R1 🔴 » ← :182 ; « séquence suspendue à l'approbation de l'audit » ← D-06. **3 liens résolus** (directive V18 · audit §3/§5/R1 · `OPEN_DECISIONS_REGISTER` D-06/D-07). La bannière cadre explicitement la doc V12 en dessous comme « l'état commité, *pas* la cible V18 », cohérent avec les bannières sœurs de `faisabilite/` et `bim/` (sessions `045813`/`052814`) — mais au **niveau module** (surface distincte de la fiche agent, où atterrit le développeur du moteur).
|
||||||
|
|
||||||
|
**Sûreté des gates (vérifiée avant édition).** `check_readme_claims` gate bancable sur (a) le motif de comptage de tests `\*\*(\d+)/(\d+) verts\*\*` (`:922`) et (b) la phrase canonique `« N % édition » et « N % marketing » (#9)` (`:5894-5913`) → la bannière **ne contient ni l'un ni l'autre** (aucun `N/M verts`, aucun pourcentage #9 — « point d'équilibre en unités » écrit **sans** le nombre) : surface non-tripante, la copie canonique correcte existante en aval est intacte (`re.search` = première occurrence, non touchée). `check_docs` : profondeur des liens vérifiée sur les liens existants du même README (`../../../04_roadmap/…`, `../../../PORTAIL_BANCABLES_4BIG.md`, `../../daily_reports`) → root à `../../../`, `05_deliverables_mvp/` à `../../` ; labels = basenames exacts des cibles (mémoire `link-label-target-mismatch`) avec les §/D-xx **hors** du lien. `guard_constraints` : aucun URL/usage interdit (DCF/IRR/DSCR/LTV/LTC ≠ termes proscrits).
|
||||||
|
|
||||||
|
**Drift artefact attendu, régénéré (mémoire `audit4big-rebuild-after-doc-edits`).** `check-artifacts` a rougi comme prévu : `audit_4big` **score le contenu DOC** des modules, donc éditer le README de bancable dérive `quality_report.json`. Régénéré **en dernier** (`audit_4big_gen.py build`) → seule variation = l'`evidence` byte-count du README (`6439 → 7748 octets`) ; **verdict PASS · 24/24 modules ≥ 95 (min 100) inchangé**. Aucun score n'a bougé (la bannière ajoute du contenu sourcé, pas un défaut de qualité).
|
||||||
|
|
||||||
|
**Vérif.** `./run_ci.sh` = **33 PASS · 0 FAIL · 0 SKIP** (rétabli après régénération). **0 code moteur V18** (bloqué #6), **0 module de production touché** (doc README + son artefact d'audit dérivé uniquement), **0 gate ajouté** (#5 — occurrence isolée, la surface bannière n'est parsée par aucun check). Aucune commande VPS (#8), aucune API externe. Fichiers : `05_deliverables_mvp/faisabilite/bancable/README.md` (bannière) + `05_deliverables_mvp/qa/audit_4big/out/quality_report.json` (byte-count régénéré) + ce journal.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Session `20260811_062822` — DOC module · bannière statut V18 dans le README du module `legal/confotur` (le module-origine de la Section 13 Juridique — 🟠 CONFOTUR seul · arbitrage D-01 — muet dessus)
|
||||||
|
|
||||||
|
**État au démarrage.** `./run_ci.sh` = **33 PASS · 0 FAIL · 0 SKIP** (baseline verte). Séquence moteur V18 toujours **intégralement bloquée** en gouvernance : D-06 (approbation de l'audit de migration par Michel) = gate d'entrée de TOUTE la séquence ; D-07 (formules DCF/IRR/VAN/DSCR/LTV/LTC absentes) et D-08 (Master Data Model sur-ensemble strict) bloquent en aval (`OPEN_DECISIONS_REGISTER.md` · directive `:90-91` « NE PAS coder avant l'audit » · #6). Les 2 nouvelles directives 08-10 (`OTO_3D_STUDIO`, `COMPTE_CLIENT_COURRIELS`) restent hors périmètre repo. Tâche non-bloquée à **valeur produit réelle** : achever l'alignement V18 des surfaces de doc des **modules-origine** identifiés par le mapping de l'audit §3.
|
||||||
|
|
||||||
|
**Défaut trouvé (classe accuracy/complétude · lacune informationnelle · continuité des sessions `045813`/`052814`/`055819`).** Le mapping §3 de l'audit V18 mappe chacune des 18 sections à son origine V12 lisible. Les 3 modules-origine à statut ✅/🟠 déjà couverts par une bannière V18 : `generator` (Section 3, fiche faisabilite), le triplet BIM (fiche bim), `bancable` (Sections 11/12/15, README). **Le 4ᵉ et dernier module-origine majeur restait muet : `legal/confotur`** — origine de la **Section 13 · Juridique** (§3 ligne 13, verdict 🟠). `grep -rl V18` sur `05_deliverables_mvp/legal/` = **vide**. Un développeur atterrissant sur [`legal/confotur/README.md`](../05_deliverables_mvp/legal/confotur/README.md) n'avait **aucune indication** que ce module ne couvre que **CONFOTUR seul** alors que la Section 13 V18 attend aussi les contrats types **Promesa de compraventa / Fideicomiso d'adhésion / règlement HOA** — l'exact périmètre de l'arbitrage **D-01** (déjà remonté dans le chemin critique V18, session `025754`).
|
||||||
|
|
||||||
|
**Piège de sur-attribution écarté (#6).** D-07 (formules financières DCF/IRR/VAN/DSCR/LTV/LTC) **écarté** de la bannière car non-juridique — comme la bannière `bim/` l'avait écarté. Cités uniquement **D-06** (gate d'entrée amont de toute la séquence) + **D-01** (l'arbitrage Section 13 lui-même). Chaque claim recoupé verbatim : « Section 13 → ce module · 🟠 » ← audit §3 ligne 75 ; « Promesa/Fideicomiso/HOA · aucun code aujourd'hui » ← §3 ligne 75 + §12.4 ligne 216 + registre D-01 (:30-58) ; libellés D-xx **vérifiés verbatim** contre le registre. **Aucune valeur devinée.**
|
||||||
|
|
||||||
|
**Sûreté des gates (le README `legal/confotur` est l'un des plus lourdement gatés — vérifiée AVANT édition).** `check_readme_claims` gate **six** surfaces de ce README : (a) synthèse `N champs/N sections/N rôles` vs MANIFEST, (b) §Permissions par rôle (portail+actions), (c) mention-total « N invariants », (d) 7 entités porteuses, (e) bullet `estado` dérivé du workflow, (f) compte `# N tests (dont`. La bannière est de la **prose hors-table** insérée après le blockquote roadmap **L55** (ancre préservée), avant `## Ce que ça produit` : elle **ne contient aucun** de ces motifs (aucun `N champs`, aucune ligne de permission, aucun « N invariants », aucune liste d'entités, aucun bullet `estado`, aucun `N tests`). `check_docs` : **3 liens résolus** — profondeur calibrée sur le module à **depth 3** (`05_deliverables_mvp/legal/confotur/`) : `../../../` pour les 2 fichiers racine (directive V18 · audit) et `../../` pour le registre (dans `05_deliverables_mvp/`) ; labels = basenames exacts des cibles (mémoire `link-label-target-mismatch`), §/D-xx **hors** du lien. Ce README n'avait **aucun** lien relatif préexistant (`grep ](../` vide) → les 3 sont neufs et vérifiés résolus. `guard_constraints` : aucun URL/usage interdit (CONFOTUR/Promesa/Fideicomiso/HOA/DCF ≠ termes proscrits).
|
||||||
|
|
||||||
|
**Drift artefact attendu, régénéré (mémoire `audit4big-rebuild-after-doc-edits`).** `audit_4big` **score le contenu DOC** des modules → éditer ce README dérive `quality_report.json`. Régénéré **en dernier** (`audit_4big_gen.py build`) → seule variation = l'`evidence` byte-count du README (`4888 → 6436` octets) ; **verdict PASS · 24/24 modules · bijection 24↔24 `ok` inchangée**. Aucun score n'a bougé (contenu sourcé ajouté, pas un défaut).
|
||||||
|
|
||||||
|
**Vérif.** `./run_ci.sh` = **33 PASS · 0 FAIL · 0 SKIP** (rétabli après régénération). **0 code moteur V18** (bloqué #6), **0 module de production touché** (doc README + son artefact d'audit dérivé uniquement), **0 gate ajouté** (#5 — occurrence isolée, la surface bannière n'est parsée par aucun check). Aucune commande VPS (#8), aucune API externe. **Note de complétude :** avec `legal/confotur`, les **4 modules-origine ✅/🟠** du mapping §3 (Sections 3 · 11/12/15 · BIM · 13) portent désormais une bannière V18 — l'alignement des surfaces de doc sur le pivot est **couvert pour les modules réels impactés** (les 9 sections 🔴 sont *nouvelles*, sans code-origine à annoter). Fichiers : `05_deliverables_mvp/legal/confotur/README.md` (bannière) + `05_deliverables_mvp/qa/audit_4big/out/quality_report.json` (byte-count régénéré) + ce journal.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Session `20260811_065822` — DOC index racine · 2 documents de gouvernance V18 tracked+lisibles mais NON liés depuis le README (`V18_GO_SIGNAL_DEVELOPMENT` + `V18_ADDENDUM_SECTION_60`)
|
||||||
|
|
||||||
|
**État au démarrage.** `./run_ci.sh` = **33 PASS · 0 FAIL · 0 SKIP** (baseline verte). Séquence moteur V18 toujours **intégralement bloquée** en gouvernance (D-06 approbation de l'audit = gate d'entrée · D-07 formules DCF/IRR/VAN/DSCR/LTV/LTC absentes · D-08 Master Data Model sur-ensemble strict · directive `:90-91` « NE PAS coder avant l'audit » · #6) — **aucun code moteur légitime**. L'alignement des bannières V18 des **4 modules-origine** ✅/🟠 est **clos** (session `062822`). Les 2 nouvelles directives 08-10 (`OTO_3D_STUDIO`, `COMPTE_CLIENT_COURRIELS`) restent hors périmètre repo. Tâche non-bloquée à valeur réelle recherchée dans la **complétude de l'index racine** (même classe que la currency du canal daily_reports : le README est le **point d'entrée du mandat**).
|
||||||
|
|
||||||
|
**Défaut trouvé (classe accuracy/complétude · index racine · lacune de liage).** Le bloc « Contexte · inventaire · workflow · gouvernance » du `README.md` (`:88-89`) liait la directive V18 **active** + son **audit de migration**, mais **deux autres documents de gouvernance V18** — `git`-**tracked** et **lisibles** (mode 644 root, world-readable, ≠ les 4 docs deep mode 600 #8) — n'étaient **liés depuis nulle part** dans le README :
|
||||||
|
- `V18_GO_SIGNAL_DEVELOPMENT_20260810.md` (90 l.) = **l'autorité de la séquence** (audit → validation Michel → Phase 1 → Phases 2-15 · projet pilote **P01 Coralis** · 8 interdictions) — précisément **la source du blocage gouvernance** que tout le reste de la doc V18 invoque sans jamais pointer vers elle.
|
||||||
|
- `V18_ADDENDUM_SECTION_60_DOCUMENT_INTEGRITY_20260810.md` (115 l.) = addendum Section 60 (35 sous-sections · Document ID/QR/hash SHA-256/registres/signatures loi 126-02 RD) dont la **règle 60.31** (« seul HELIOS RD SRL visible en externe ») est **l'origine** du filtre anti-fuite vocabulaire de l'audit §9 et de l'arrière-plan de l'arbitrage juridique D-01.
|
||||||
|
|
||||||
|
Un lecteur (agent ou humain) du README — le doc le plus consulté — pouvait donc lire l'audit et le registre sans jamais atteindre le GO signal qui **définit le gate bloquant**, ni l'addendum qui **contraint la publication**.
|
||||||
|
|
||||||
|
**Fix (doc worker · sourcé · zéro invention #6).** 2 sous-bullets ajoutés sous l'entrée `DIRECTIVE_V18` (même niveau/style que le sous-bullet audit), descriptions **dérivées de la lecture réelle des deux fichiers** (séquence 15 phases · P01 Coralis · 8 interdictions ← GO signal `:38-71` ; 35 sous-sections 60.1→60.35 · règle 60.31 · loi 126-02 ← addendum `:10-73`). Labels = **basenames exacts** des cibles (mémoire `link-label-target-mismatch`). Liens à profondeur racine (bare filename, comme l'entrée directive existante).
|
||||||
|
|
||||||
|
**Sûreté des gates (vérifiée AVANT édition).** `check_readme_claims` recompute des claims **très spécifiques** bornés à `**\d+/\d+ modules gated à \d+/100**`, `**\d+ suites gated**`, `## Les \d+ agents`, etc., tous liés à un `out/*.json` — mes chiffres de prose (35 sous-sections · 8 interdictions · 15 phases) proviennent des **.md de gouvernance** (non-artefacts, non recomputés) et n'épousent **aucun** de ces motifs bold-wrappés → surface non parsée. `check_docs` : les 2 liens ciblent des fichiers **existants/tracked/lisibles**, aucun fragment-anchor → résolus (`run_ci` vert le confirme). `guard_constraints` : aucun URL/usage interdit (« HELIOS RD SRL »/« Section 60 »/« loi 126-02 » ≠ termes proscrits ; aucun `github`/`stripe`/`espocrm`/`hubspot` écrit).
|
||||||
|
|
||||||
|
**Vérif.** `./run_ci.sh` = **33 PASS · 0 FAIL · 0 SKIP** (inchangé). **0 code moteur V18** (bloqué #6), **0 module de production touché**, **0 artefact reconstruit** (README non scoré par `audit_4big`, hors `05_deliverables_mvp/`), **0 gate ajouté** (#5 — occurrence isolée, surface non parsée). Aucune commande VPS (#8), aucune API externe. **Note de complétude :** les **4 documents de gouvernance V18** tracked+lisibles (directive · audit · GO signal · addendum Sec.60) sont désormais tous liés depuis l'index racine ; le point d'entrée du mandat expose la séquence bloquée et ses contraintes de publication de bout en bout. Fichiers : `README.md` (2 sous-bullets) + ce journal.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Session `20260811_072823` — FIX correctness · l'audit 4Big sous-comptait un test au nom accentué (regex ASCII vs `\w` Unicode de la source sœur) — 22 → 23, teeth ajoutée
|
||||||
|
|
||||||
|
**État au démarrage.** `./run_ci.sh` = **33 PASS · 0 FAIL · 0 SKIP** (baseline verte). Séquence moteur V18 toujours **intégralement bloquée** en gouvernance (D-06 approbation de l'audit = gate d'entrée · D-07 formules DCF/IRR/VAN/DSCR/LTV/LTC absentes · D-08 Master Data Model · directive `:90-91` « NE PAS coder avant l'audit » · #6). L'alignement des bannières V18 des 4 modules-origine + le liage index sont clos (sessions précédentes). Rendements décroissants sur les micro-tâches doc → recherche d'un **défaut de correction réel** non-bloqué et à valeur produit (hunt Explore ciblé, hors périmètre V18/#8).
|
||||||
|
|
||||||
|
**Défaut trouvé (classe #6 anti-invention · DANS l'outil d'audit qualité lui-même).** `qa/audit_4big/q4lib/criteria.py:18` comptait les méthodes de test via une char-class **ASCII pure** : `_TEST_DEF_RE = re.compile(r"^\s*def (test_[A-Za-z0-9_]+)\s*\(", …)`. Or Python 3 (PEP 3131) autorise les identifiants **Unicode** : le test réel **`test_traçabilite_source`** (le `ç`) existe à `publiciste/tests/test_publiciste.py:99`, est **valide et exécuté** par unittest (« Ran 23 tests »). La regex ASCII le **loupait** → `crit_tests` publiait l'évidence fausse **« 22 méthodes test_* »** dans `quality_report.json` (réel = **23**). Le critère TESTS reste PASS (seuil 8) et le score inchangé (100) — mais **le fait publié était faux**, en violation du cœur anti-invention #6 de l'audit (« une note est recomputée à partir de faits vérifiables », `criteria.py:1-7`).
|
||||||
|
|
||||||
|
**Preuve que c'est un bug (pas by-design) — la source SŒUR le compte déjà correctement.** `qa/regression/reglib/discovery.py:23` compte le MÊME concept avec `_TEST_METHOD_RE = re.compile(r"^\s*def\s+(test_\w+)\s*\(")` — **`\w` est Unicode-aware par défaut en Python 3** → il compte publiciste = **23** (attesté dans `regression_plan.json`, byte-gaté, autorité de la colonne « Tests » des fiches via `count_tests`). Les deux outils QA **divergeaient d'un** sur publiciste (23 vs 22) ; `criteria.py` était le mauvais. Blast-radius vérifié : **un seul** nom de test non-ASCII dans tout le dépôt (scan AST des 24 suites) → publiciste seul impacté ; le « 22 méthodes mobile » du `daily_reports/2026-08-03` est un module distinct (coïncidence), non touché.
|
||||||
|
|
||||||
|
**Fix (chirurgical · single-source · aligné sur la sœur).** `criteria.py:18` : char-class ASCII `[A-Za-z0-9_]` → `\w` (Unicode), forme identique à `reglib.discovery`. **+ teeth** : nouveau test `test_tests_counts_non_ascii_method_names` dans `qa/audit_4big/tests/test_audit_4big.py` (fixture ASCII + `test_traçabilite_source`, exige « 2 méthodes ») — **prouvé mordant** : sur l'ancienne regex ASCII il compte 1 → assertion échoue ; sur `\w` → 2 → passe. La fixture existante du suite étant en ASCII, aucune régression sur `test_tests_counts_methods_and_thresholds` (« 5 méthodes » inchangé).
|
||||||
|
|
||||||
|
**Cascade d'artefacts régénérée (mémoire `artifact-reproducibility-gate` + `audit4big-rebuild-after-doc-edits`).** (1) `quality_report.json` régénéré **en dernier** → seule variation = évidence publiciste TESTS « 22 → 23 méthodes » ; verdict **PASS · 24/24 · min 100** inchangé. (2) L'ajout du test change le décompte de la matrice : `regression_gen.py build` (plan) **puis** `run` (matrice live) → `regression_run.json` **625 → 626 exécutés · 608 → 609 passés · 17 skippés · 0 échec** (le nouveau test lui-même + audit_4big se score lui-même). (3) Surfaces de prose re-dérivées : fiche `03_agents/qa/AGENT.md` (colonne audit_4big **34 → 35** ← `count_tests` ; agrégat **625/608 → 626/609**) — la première flaggée RED par `check_readme_claims`, la seconde par le même gate ; + `03_agents/erpnext_backend/AGENT.md:40` (claim live **625 → 626**, sourcé `regression_run.json`). Le `daily_reports/2026-08-11` (snapshot signé HEAD `18d8763`) et les logs sont des instantanés datés → laissés (mémoire `two-logging-channels`).
|
||||||
|
|
||||||
|
**Pourquoi pas un nouveau gate (#5).** La divergence est déjà **structurellement gatée** : `check_readme_claims` a **immédiatement rougi** (fiche QA vs `count_tests`) dès que la matrice a bougé, et la teeth ajoutée verrouille le comportement de `criteria.py`. Ajouter un gate « criteria.py == discovery.py » serait redondant — la réconciliation croisée existante mord déjà. Occurrence isolée (1 nom non-ASCII), corrigée à la source unique.
|
||||||
|
|
||||||
|
**Vérif.** `./run_ci.sh` = **33 PASS · 0 FAIL · 0 SKIP** rétabli après régénération complète. **0 code moteur V18** (bloqué #6), **0 commande VPS** (#8), **0 API externe**. Fichiers : `qa/audit_4big/q4lib/criteria.py` (regex) + `qa/audit_4big/tests/test_audit_4big.py` (teeth) + `qa/audit_4big/out/quality_report.json` + `qa/regression/out/{regression_plan,regression_run,MANIFEST}.json` + `03_agents/qa/AGENT.md` + `03_agents/erpnext_backend/AGENT.md` + ce journal.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Session `20260811_075824` — CANAL STAKEHOLDER · actualisation du rapport quotidien `2026-08-11` (périmé dans la journée : `18d8763` → `ac595d0`, 9 commits, dont le fix de correction `audit_4big`)
|
||||||
|
|
||||||
|
**État au démarrage.** `./run_ci.sh` = **33 PASS · 0 FAIL · 0 SKIP** (baseline verte). Séquence moteur V18 toujours **intégralement bloquée** en gouvernance (D-06 approbation de l'audit = gate d'entrée · D-07 formules DCF/IRR/VAN/DSCR/LTV/LTC absentes · D-08 Master Data Model sur-ensemble strict · directive `:90-91` « NE PAS coder avant l'audit » · #6) — **aucun code moteur légitime**. L'alignement des bannières V18 des 4 modules-origine, le liage index racine et le fix `audit_4big` sont clos. Les 2 nouvelles directives 08-10 (`OTO_3D_STUDIO`, `COMPTE_CLIENT_COURRIELS`) restent hors périmètre repo.
|
||||||
|
|
||||||
|
**Chasse au bug menée d'abord (Explore very-thorough sur `*lib/` + `*_gen.py`).** Recherche d'un défaut de correction de calibre équivalent au fix regex ASCII de la session précédente (char-classes ASCII vs `\w`, off-by-one, comparateurs de seuil, dedup). **Rien de solide** — le seul candidat (`publiciste/lib/parser.py:433` `P0[1-9]`) est **correct** (9 projets P01-P09 par CLAUDE.md §Projets, pas un défaut de scaling). J'ai refusé de fabriquer un faux positif (#6).
|
||||||
|
|
||||||
|
**Tâche prioritaire non-bloquée retenue (classe `two-logging-channels`).** Le **canal stakeholder** `daily_reports/2026-08-11.md` était figé au HEAD `18d8763` (émis session `032800`) et citait régression **625/608** — mais **9 commits `[DTP-Worker]`** ont depuis porté l'arbre à `ac595d0` **le même jour**, dont l'**événement produit le plus notable** : le fix de correction `audit_4big` (`ac595d0`) qui a corrigé un vrai bug dans l'outil d'audit lui-même et porté la matrice à **626/609**. Le canal roadmap — celui qui met l'état dans le champ de vision de Michel — était donc **périmé dans la journée** de 9 commits et d'un chiffre live faux. Actualiser = **non-bloqué, sans invention, doc worker**, et exactement la fonction du canal (snapshot stakeholder à ne pas laisser lapser · chaque figure sourcée d'un artefact commité).
|
||||||
|
|
||||||
|
**Fait (une entrée/jour, rendue exacte — pas un doublon de rapport).** (a) En-tête : `HEAD attesté` `18d8763` → **`ac595d0`** + mention « actualisé `20260811_075824` » et note des 9 commits suivants. (b) Nouvelle section **« Jalons worker suivants (`18d8763` → `ac595d0`) »** : table des 6 jalons `[DTP-Worker]` (exactitude audit V18 · 4 bannières statut V18 · liage index racine · **fix correctness `audit_4big`**), chacun avec commit + nature + opposabilité au merge, + encart « événement produit le plus notable ». (c) Table « État courant » : HEAD `18d8763` → `ac595d0`, régression **625→626 / 608→609**, lecture stakeholder **609 passés + 17 skippés** ; paragraphe des skips re-dérivé (deux évolutions 624→625 puis 625→626, cause de chacune sourcée). La section « Portée / anti-churn (session `032800`) » **laissée telle quelle** (récit exact de cette session-là ; l'actualisation est transparente via l'en-tête + la nouvelle section — convention `two-logging-channels` : ne pas réécrire l'historique, actualiser en ajoutant).
|
||||||
|
|
||||||
|
**Honnêteté de sourçage (tous chiffres re-lus ce jour d'artefacts commités · #6).** HEAD `ac595d0` = `git rev-parse` · régression **626/609/17/0** = `regression_run.json totals` (lu ce jour) · audit 4Big **PASS · 24 modules · min 100 · bijection 24↔24 `ok`** = `quality_report.json` (inchangé) · les 9 hashes de commit = `git log 18d8763..HEAD`. Aucune figure figée.
|
||||||
|
|
||||||
|
**Sûreté des gates (vérifiée AVANT édition).** `check_readme_claims` **exclut** `daily_reports/` de son scan (`:8239` `not f.startswith(f"{D}/daily_reports/")`) → chiffres non parsés. `check_docs` link-checke les `daily_reports/` mais la nouvelle section n'ajoute **aucun lien relatif** (uniquement des hashes de commit et chemins en code-spans, non link-checkés). `guard_constraints` : aucun URL/usage interdit (DCF/IRR/DSCR/LTV/LTC ≠ termes proscrits).
|
||||||
|
|
||||||
|
**Vérif.** `./run_ci.sh` = **33 PASS · 0 FAIL · 0 SKIP** (inchangé). **0 code moteur V18** (bloqué #6), **0 module de production touché**, **0 artefact reconstruit** (rapport actualisé depuis les artefacts, pas l'inverse), **0 gate ajouté** (#5). Aucune commande VPS (#8), aucune API externe. Fichiers : `05_deliverables_mvp/daily_reports/2026-08-11.md` (actualisation) + ce journal.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Session `20260811_082825` — HARDENING correctness · le critère CLI de l'audit 4Big loupait les gardes `__main__` simple-quotées/Yoda (détection figée sur une graphie · même classe que le fix ASCII de `ac595d0`) — teeth ajoutée
|
||||||
|
|
||||||
|
**État au démarrage.** `./run_ci.sh` = **33 PASS · 0 FAIL · 0 SKIP** (baseline verte). Séquence moteur V18 toujours **intégralement bloquée** en gouvernance (D-06 approbation de l'audit = gate d'entrée · D-07 formules DCF/IRR/VAN/DSCR/LTV/LTC absentes · D-08 Master Data Model · directive `:90-91` « NE PAS coder avant l'audit » · #6) — **aucun code moteur légitime**. Les bannières V18 des 4 modules-origine, le liage index et le fix `audit_4big` (session `072823`) sont clos. Les 2 nouvelles directives 08-10 (`OTO_3D_STUDIO`, `COMPTE_CLIENT_COURRIELS`) restent hors périmètre repo.
|
||||||
|
|
||||||
|
**Vérif d'abord : le fix ASCII (`ac595d0`) a-t-il un rayon de blast CODE complet ?** La session `072823` avait vérifié le rayon **données** (« un seul nom de test non-ASCII dans le dépôt → publiciste seul »), mais **pas** le rayon **code** (d'autres regex partagent-elles le même défaut char-class-ASCII-sur-contenu-accentué ?). Sweep mené : (a) toutes les regex Python génératrices/`*lib/` (hors `/out/`, `/tests/`) → **2 compteurs de test** seulement, **tous deux `\w`** (`criteria.py:18` + `reglib/discovery.py:23`), et `check_readme_claims` **réutilise** `discovery.count_tests` (mono-source, `:663`) ; (b) `registry.py:30` `_JOB_RE` `[A-Za-z0-9_-]` = **domaine ASCII** (noms de jobs YAML, jamais accentués) — non-défaut ; (c) toutes les char-class ASCII des **gates shell** (`ci/*.sh`) → **toutes sur tokens ASCII-par-domaine** (slugs de rôles/portails kebab-case · lettres e-NCF · abréviations critères en CAPS · IDs d'invariants) — **aucune** ne scanne de la prose accentée. **Classe ASCII-vs-Unicode CLOSE au niveau code** (extension du check données de `072823`). Figures de régression en prose également **à jour** (aucun `624`/`625`/`607`/`608` stale hors snapshots datés). Le candidat `crit_cli` quote-style (littéral `"__main__"` figé) : **all 50 gardes du dépôt sont double-quotées** → aucun mis-scorage courant.
|
||||||
|
|
||||||
|
**Défaut trouvé (classe #6 · robustesse de détection de l'outil d'audit lui-même · MÊME classe que le fix ASCII).** `q4lib/criteria.py:78` détectait l'entrypoint CLI par un **littéral figé** : `'__name__ == "__main__"' in src` — assume **une seule graphie**. Or `if __name__ == '__main__':` (**simple quote**), `if "__main__" == __name__:` (**« Yoda »**, opérandes inversés) et `if __name__=='__main__':` (**sans espaces**) sont tous du **Python valide** = un entrypoint réel. Le littéral les **loupe silencieusement** → le critère CLI échouerait sur un module sain (**−20 pts**, chute possible < 95), en violation du cœur anti-invention #6 de l'audit (« une note est recomputée à partir de faits vérifiables ») : le critère **sous-spécifie** ce qu'est un entrypoint valide. Exactement la même racine que le fix ASCII (`ac595d0`) : *une détection assume une forme syntaxique là où le langage en admet plusieurs.*
|
||||||
|
|
||||||
|
**Pourquoi c'est légitime et pas de la sur-défense (#5).** Distinction du « ne pas coder défensivement des cas non-occurrents » : ici ce n'est **pas un gate** ajouté pour un cas d'entrée improbable d'un module produit — c'est la **correction de la logique de détection d'un critère existant** de l'**outil d'enforcement #6** lui-même, dont le contrat est d'évaluer correctement **n'importe quel Python valide**. La robustesse aux deux styles de guillemets est **dans le contrat** de l'outil, pas de l'ornement. Précédent direct : le fix ASCII a été accepté sur des bases identiques (regex ne matchant pas des identifiants Python valides).
|
||||||
|
|
||||||
|
**Fix (chirurgical · regex de forme, pas de graphie · teeth).** `criteria.py` : nouveau `_MAIN_GUARD_RE = re.compile(r"__name__\s*==\s*['\"]__main__['\"]|['\"]__main__['\"]\s*==\s*__name__")` (deux styles de guillemets · ordre inversé · espacement libre) ; `crit_cli` passe de `'__name__ == "__main__"' in src` à `_MAIN_GUARD_RE.search(src)`. **+ teeth** : `test_cli_detects_single_quoted_and_yoda_guards` (3 fixtures : simple-quote · Yoda · sans-espaces) — **prouvé mordant** : sur l'ancien littéral les 3 rendent `False` (garde loupée) ; sur la regex les 3 rendent `True`. Aucun risque de faux positif nouveau (le motif exige la séquence complète `__name__ == "__main__"`, comme le littéral).
|
||||||
|
|
||||||
|
**Sortie inchangée (robustesse pure · #6 auto-vérifié).** Les 50 gardes du dépôt étant double-quotées et **toujours matchées** par la nouvelle regex, `crit_cli` rend un résultat **identique pour les 24 modules** → **`quality_report.json` byte-identique** (correctement NON régénéré : `audit_4big` **s'auto-exclut** de son propre scoring — les modules qa scorés sont `qa-audit-5d`/`qa-acceptance`/`qa-regression`, pas `audit_4big` ; même patron d'auto-exclusion que la régression). Le fix ne change **aucun score** — c'est une garantie de robustesse, pas une correction de note.
|
||||||
|
|
||||||
|
**Cascade d'artefacts (uniquement la matrice de régression · mémoire `artifact-reproducibility-gate`).** L'ajout du test augmente le décompte de la suite `audit_4big` : `regression_gen.py build` (plan) **puis** `run` (matrice) → `regression_run.json` **626 → 627 exécutés · 609 → 610 passés · 17 skippés · 0 échec** (le nouveau test). Surfaces de prose gatées re-dérivées (flaggées RED par `check_readme_claims`, corrigées) : fiche `03_agents/qa/AGENT.md` (colonne `audit_4big` **35 → 36** ← `count_tests` ; agrégat **626/609 → 627/610**) + `03_agents/erpnext_backend/AGENT.md:40` (claim live **626 → 627**). Le `daily_reports/2026-08-11` (snapshot signé) et les logs sont des instantanés datés → laissés (`two-logging-channels`).
|
||||||
|
|
||||||
|
**Pourquoi pas un nouveau gate (#5).** La divergence de compte est déjà **structurellement gatée** (`check_readme_claims` a immédiatement rougi la fiche QA + le compte `audit_4big`) et la teeth verrouille le comportement de `crit_cli`. Occurrence latente (0 garde simple-quotée aujourd'hui) mais correction de contrat de l'outil, pas un cas d'entrée produit → pas de gate additionnel.
|
||||||
|
|
||||||
|
**Vérif.** `./run_ci.sh` = **33 PASS · 0 FAIL · 0 SKIP** rétabli après régénération. **0 code moteur V18** (bloqué #6), **0 commande VPS** (#8), **0 API externe**. Fichiers : `qa/audit_4big/q4lib/criteria.py` (regex) + `qa/audit_4big/tests/test_audit_4big.py` (teeth) + `qa/regression/out/{regression_plan,regression_run,MANIFEST}.json` + `03_agents/qa/AGENT.md` + `03_agents/erpnext_backend/AGENT.md` + ce journal. `quality_report.json` **non touché** (auto-exclusion prouvée).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Session `20260811_085834` — HARDENING correctness · l'alignement du compteur de tests `audit_4big`↔`discovery` (fix ASCII `ac595d0`) était INCOMPLET : `def ` (un espace figé) ≠ `def\s+` de la sœur — teeth ajoutée, classe désormais close
|
||||||
|
|
||||||
|
**État au démarrage.** `./run_ci.sh` = **33 PASS · 0 FAIL · 0 SKIP** (baseline verte). Séquence moteur V18 toujours **intégralement bloquée** en gouvernance (D-06 approbation de l'audit = gate d'entrée · D-07 formules DCF/IRR/VAN/DSCR/LTV/LTC absentes · D-08 Master Data Model sur-ensemble strict · directive `:90-91` « NE PAS coder avant l'audit » · #6) — **aucun code moteur légitime**. Les bannières V18 des 4 modules-origine, le liage index et les 2 fixes `audit_4big` (regex ASCII `ac595d0` · garde `__main__` `fd99362`) sont clos. Les 2 directives 08-10 (`OTO_3D_STUDIO`, `COMPTE_CLIENT_COURRIELS`) restent hors périmètre repo.
|
||||||
|
|
||||||
|
**Défaut trouvé (classe #6 · MÊME racine que les 2 fixes précédents : « détecter la forme, pas une graphie » · + il COMPLÈTE un fix laissé à moitié).** Le fix ASCII `ac595d0` (session `072823`) avait pour but explicite d'**aligner** le compteur de méthodes de test d'`audit_4big` (`q4lib/criteria.py:_TEST_DEF_RE`) sur celui de la source sœur `reglib/discovery.py:_TEST_METHOD_RE` — autorité **byte-gatée** de la colonne « Tests » des fiches (réutilisée par `check_readme_claims` via `discovery.count_tests`). Il a aligné le **char-class** (`[A-Za-z0-9_]` → `\w`, pour les noms accentués), mais a laissé **une seconde divergence intacte** sur le **séparateur `def`** :
|
||||||
|
- `discovery.py:23` = `r"^\s*def\s+(test_\w+)\s*\("` — `\s+` (espacement libre)
|
||||||
|
- `criteria.py:18` = `r"^\s*def (test_\w+)\s*\("` — **un seul espace littéral figé**
|
||||||
|
|
||||||
|
Or `def test_x(` (deux espaces) et `def\ttest_x(` (tabulation) sont du **Python valide** (PEP 8 recommande un espace, le langage n'en impose pas). Le littéral `def ` les **loupe** → `crit_tests` sous-compterait, en **désaccord d'un ou plusieurs** avec la sœur — exactement le type de dérive d'évidence #6 que le fix ASCII prétendait clore. Les **deux compteurs du MÊME concept** doivent coïncider sur **toute graphie valide**, pas seulement les identifiants Unicode.
|
||||||
|
|
||||||
|
**Occurrence (comme la garde `__main__` de `fd99362`) : latente, 0 aujourd'hui.** `grep -rnE '^\s*def( +|\t)test_'` sur tous les `test_*.py` = **vide** (tous en un-espace PEP 8) → aucun mis-comptage courant, `quality_report.json` **byte-identique**. Mais c'est la **correction du contrat de détection de l'outil d'enforcement #6** (compter correctement n'importe quel Python valide + coïncider avec la sœur), pas une sur-défense d'un cas d'entrée produit improbable — même base d'acceptation que `fd99362`. Divergence sœur de recensement de fichiers vérifiée aussi : `criteria` recurse (`os.walk`) là où `discovery` liste à plat (`os.listdir`) — **aucun `tests/*/test_*.py` imbriqué dans le dépôt** (`find` vide) → non-occurrent, axe distinct (découverte de fichiers, pas détection de méthode), **laissé** (discovery = autorité du gate ; ne pas muter son comportement pour un cas nul).
|
||||||
|
|
||||||
|
**Fix (chirurgical · forme, pas graphie · single-source-de-forme · teeth).** `criteria.py:18` : `def ` → `def\s+`, forme **strictement identique** à `discovery._TEST_METHOD_RE` (commentaire mis à jour : les deux compteurs doivent coïncider). **+ teeth** : `test_tests_counts_non_single_space_def_separator` (fixture 3 méthodes : un-espace · deux-espaces · tab) — **prouvé mordant** : ancien regex `def ` compte **1** des 3 (loupe deux-espaces + tab) ; nouveau `def\s+` compte **3**. La fixture ASCII existante (`test_tests_counts_methods_and_thresholds` « 5 méthodes ») reste en un-espace → aucune régression.
|
||||||
|
|
||||||
|
**Sortie inchangée (robustesse pure · #6 auto-vérifié).** Aucun module du dépôt n'ayant de `def` multi-espace/tab, `crit_tests` rend une évidence **identique pour les 24 modules** → `quality_report.json` **byte-identique** (rebuild `audit_4big_gen.py build` → `git diff --stat` **vide** ; `audit_4big` **s'auto-exclut** de son propre scoring — les modules qa scorés sont `qa-audit-5d`/`qa-acceptance`/`qa-regression`, pas lui). Le fix ne change **aucun score**.
|
||||||
|
|
||||||
|
**Cascade d'artefacts (uniquement la matrice de régression · mémoire `artifact-reproducibility-gate`).** L'ajout du test augmente le décompte de la suite `audit_4big` : `regression_gen.py build` (plan) **puis** `run` (matrice) → `regression_run.json` **627 → 628 exécutés · 610 → 611 passés · 17 skippés · 0 échec**. Surfaces de prose gatées re-dérivées (flaggées RED par `check_readme_claims`, corrigées) : fiche `03_agents/qa/AGENT.md` (colonne `audit_4big` **36 → 37** ← `count_tests` ; agrégat **627/610 → 628/611**) + `03_agents/erpnext_backend/AGENT.md:40` (claim live **627 → 628**). Le `daily_reports/2026-08-11` (snapshot signé) et les logs sont des instantanés datés → laissés (`two-logging-channels`).
|
||||||
|
|
||||||
|
**Classe désormais close (les 2 axes de la coïncidence des compteurs).** Après `072823` (char-class) + cette session (séparateur), `criteria._TEST_DEF_RE` et `discovery._TEST_METHOD_RE` sont **forme-identiques** ; l'axe fichiers (recursion) est non-occurrent et documenté laissé. **Pas de nouveau gate (#5)** : la divergence de compte est déjà **structurellement gatée** (`check_readme_claims` a immédiatement rougi la fiche QA dès que la matrice a bougé) et la teeth verrouille le comportement. Occurrence latente → correction de contrat de l'outil, pas de gate additionnel.
|
||||||
|
|
||||||
|
**Vérif.** `./run_ci.sh` = **33 PASS · 0 FAIL · 0 SKIP** rétabli après régénération. **0 code moteur V18** (bloqué #6), **0 commande VPS** (#8), **0 API externe**. Fichiers : `qa/audit_4big/q4lib/criteria.py` (regex) + `qa/audit_4big/tests/test_audit_4big.py` (teeth) + `qa/regression/out/{regression_plan,regression_run,MANIFEST}.json` + `03_agents/qa/AGENT.md` + `03_agents/erpnext_backend/AGENT.md` + ce journal. `quality_report.json` **non touché** (auto-exclusion prouvée, `git diff --stat` vide).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Session `20260811_092842` — CANAL STAKEHOLDER · actualisation daily report au HEAD courant `35de616` (l'arc de fixes `audit_4big` a fait bouger la régression deux fois de plus depuis l'épinglage `ac595d0`)
|
||||||
|
|
||||||
|
**État au démarrage.** `./run_ci.sh` = **33 PASS · 0 FAIL · 0 SKIP** (baseline verte). Séquence moteur V18 toujours **intégralement bloquée** en gouvernance (D-06 approbation de l'audit = gate d'entrée · D-07 formules DCF/IRR/VAN/DSCR/LTV/LTC absentes · D-08 Master Data Model · directive `:90-91` « NE PAS coder avant l'audit » · #6) → **aucun code moteur légitime**. Les 3 fixes `audit_4big` (char-class `ac595d0` · garde `__main__` `fd99362` · séparateur `def` `35de616`), les 4 bannières V18 et le liage index sont clos.
|
||||||
|
|
||||||
|
**Vérif d'abord — pas de dérive de chiffres avant de choisir la tâche.** Artefact autoritaire `regression_run.json` (`totals`) = **628 ran · 611 passés · 17 skippés · 0 échec** (PASS). Les surfaces de prose **gatées** qui figent l'agrégat sont à jour : fiche `03_agents/qa/AGENT.md:35` (**628/611**) + `03_agents/erpnext_backend/AGENT.md:40` (**628 · 24 suites**) — concordent avec l'artefact, aucune dérive (`check_readme_claims` vert). Le README racine ne fige aucun compte de tests (renvoie à l'artefact byte-gaté). **Classe de dérive numérique : nulle.**
|
||||||
|
|
||||||
|
**Défaut trouvé (canal stakeholder en retard sur le HEAD · pas un bug code).** Le `daily_reports/2026-08-11.md` était **épinglé à HEAD `ac595d0`** (régression **626/609**), mais **deux commits worker de plus** ont atterri le **même jour** après sa dernière actualisation (`9e02c38`) : `fd99362` (garde `__main__` → 627/610) puis `35de616` (séparateur `def` → 628/611). Le canal stakeholder — dont le contrat (`two-logging-channels`) est de porter le snapshot roadmap au **point courant du jour** avec chaque chiffre sourcé d'un artefact commité — accusait donc **2 commits + 2 pas de régression** de retard. C'est exactement la tâche de currency que le worker maintient (précédents `8ec11de`, `9e02c38` le même jour).
|
||||||
|
|
||||||
|
**Fix (currency pure · re-dérivation d'artefacts, zéro chiffre figé · #6).** Daily report ré-épinglé `ac595d0` → `35de616` :
|
||||||
|
- En-tête : HEAD attesté `ac595d0` → `35de616` · « 9 → **11 commits worker** » · actualisé `092842`.
|
||||||
|
- §« Jalons worker suivants » : titre `→ ac595d0` → **`→ 35de616`**, « six → **huit jalons** » ; **2 lignes ajoutées** (`fd99362` garde `__main__` −20 pts CLI évités · `35de616` séparateur `def` complète le fix ASCII), chacune avec sa cascade de régression re-dérivée.
|
||||||
|
- L'encart « événement le plus notable » recadré du seul `ac595d0` vers l'**arc des 3 fixes de même racine** (« détecter la forme, pas une graphie »), **classe close**.
|
||||||
|
- §État courant : HEAD `35de616` · matrice **626/609 → 628/611** ; prose de progression « deux → **quatre fois** depuis 08-06 » avec les 3 pas du jour explicités (625→626→627→628 / 608→609→610→611).
|
||||||
|
- §Portée : ligne **Currency `092842`** (re-épinglage + provenance des chiffres).
|
||||||
|
|
||||||
|
**Pourquoi c'est légitime et non du churn (#5).** Ce n'est pas un re-write d'un snapshot daté figé (ceux-là restent, `two-logging-channels`) : c'est la **mise au point courant du jour même** du canal stakeholder, dont le `9e02c38` précédent avait fait exactement autant (18d8763→ac595d0). Chaque chiffre injecté est **re-dérivé** de `regression_run.json` (`totals` = 628/611), aucun figé. **0 fichier de production · 0 artefact reconstruit · 0 gate ajouté · 0 code moteur V18 · 0 commande VPS · 0 API externe.**
|
||||||
|
|
||||||
|
**Vérif.** `./run_ci.sh` = **33 PASS · 0 FAIL · 0 SKIP** (inchangé · le daily report tracked passe `check_docs` + `guard_constraints`). Fichiers : `05_deliverables_mvp/daily_reports/2026-08-11.md` + ce journal.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Session `20260811_095844` — COUVERTURE produit · teeth `publiciste` sur les prix à ESPACE INSÉCABLE (U+00A0) · classe d'entrée réelle FR/ES 100 % non testée jusqu'ici
|
||||||
|
|
||||||
|
**État au démarrage.** `./run_ci.sh` = **33 PASS · 0 FAIL · 0 SKIP** (baseline verte · `regression_run.json totals` = 628/611/17). Séquence moteur V18 toujours **intégralement bloquée** en gouvernance (D-06 approbation de l'audit = gate d'entrée · D-07 formules DCF/IRR/VAN/DSCR/LTV/LTC absentes · D-08 Master Data Model · directive `:90-91` « NE PAS coder avant l'audit » · #6) — **aucun code moteur légitime**. Les 2 directives 08-10 (`OTO_3D_STUDIO`, `COMPTE_CLIENT_COURRIELS`) restent hors périmètre repo. Les micro-tâches doc + l'arc `audit_4big` sont clos → recherche d'une tâche à **valeur produit réelle**.
|
||||||
|
|
||||||
|
**Chasse au bug d'abord (2 passes indépendantes) → aucun défaut, refus de fabriquer (#6).** Explore very-thorough sur les `*_gen.py`/`*lib/` **hors** `audit_4big`/`regression` (déjà balayés) : classes visées = char-class ASCII-vs-Unicode, off-by-one, comparateurs de seuil, sets à doublons, arithmétique dérivée, collisions de clés. **Rien de solide.** Les 2 candidats remontés étaient des **non-défauts** : (a) `publiciste/lib/parser.py:77` `.replace(" ", " ")` — l'Explore l'a lu « no-op » ; **hexdump** montre `c2 a0` = le 1er argument est un **NBSP** → c'est une **normalisation NBSP→espace réelle**, pas un no-op (l'Explore s'est fait piéger par des glyphes identiques à l'œil — exactement le risque byte-invisible) ; (b) `seo_gen.py` global-keyword digit-check = latent masqué par invariant. **Aucun n'est un bug** → non touchés.
|
||||||
|
|
||||||
|
**Vrai locus trouvé = un TROU DE COUVERTURE, pas un bug.** `parse_number`/`parse_price` de `publiciste` sont **conçus** pour l'**espace insécable U+00A0** comme séparateur de milliers — la graphie que Word/InDesign FR/ES insèrent dans les prix réels des `data_room` (« DOP 8 850 000 » avec NBSP). La capture repose sur la char-class **Unicode-whitespace** de `parser.py:74` (`[0-9\s.,` + un **NBSP littéral** `c2 a0` redondant avec `\s`). Or **aucun des 23 tests** n'exerçait le NBSP : `test_prix_formats:39` (« DOP 8 850 000 ») utilise des **espaces ASCII 0x20** (`hexdump` confirmé), pas des NBSP. La classe d'entrée réelle la plus caractéristique du parser était **100 % non testée** — et c'est précisément ce trou qui a permis à l'Explore de mésinterpréter la ligne 77 comme du code mort.
|
||||||
|
|
||||||
|
**Preuve end-to-end + bite ACCURATE (aucune affirmation non vérifiée · #6).** (1) `parse_price("DOP 8 850 000")` = **8850000.0** ✓, `parse_number("1 250")` = **1250.0** ✓ (exécuté). (2) Condition de bite **déterminée empiriquement, pas devinée** : la char-class porte `\s` **et** un NBSP littéral → retirer **l'un** est inoffensif (redondance belt-and-suspenders) ; le bite ne survient que si l'on **réduit la classe à de l'ASCII pur** `[0-9.,]` (retrait de TOUTE prise en charge whitespace-Unicode) → le test échoue alors `8.0 != 8850000.0` (prouvé : cassé RED, restauré VERT). Le commentaire du test a été **corrigé** d'une 1re rédaction fausse (« retirer `\s` mord ») vers la condition réelle — honnêteté de claim (#6). Même racine que l'arc `audit_4big` : « détecter la forme, pas une graphie ».
|
||||||
|
|
||||||
|
**Hygiène byte-invisible (leçon appliquée au test lui-même).** 1re rédaction du test contenait des **NBSP littéraux** (`nbsp = " "`) — je réintroduisais l'octet invisible que je dénonce. Réécrit en **escape explicite ` `** (`nb = " "`) → **0 octet invisible** dans le fichier de test (vérifié `grep -c`), intention 100 % lisible. La char-class de **production** (ligne 74), elle, est **laissée telle quelle** : son NBSP littéral est **redondant mais correct** (`\s` le couvre) ; l'éditer serait du churn cosmétique sur un non-défaut (#5, `verify-non-defects`) avec risque de dérive d'artefact pour zéro changement de comportement.
|
||||||
|
|
||||||
|
**Fix = 1 test teeth `test_prix_espace_insecable_milliers`** (classe `TestNumberParsing`) : `parse_price`/`parse_number`/`parse_int` sur NBSP (DOP/USD milliers + décimale). Distinct de l'arc récent : ce n'est **pas** un test de l'outil d'audit mais de la **couverture d'un module produit** sur une **entrée réelle** — valeur produit directe.
|
||||||
|
|
||||||
|
**Cascade d'artefacts régénérée (mémoires `artifact-reproducibility-gate` + `audit4big-rebuild-after-doc-edits`).** (1) `audit_4big_gen.py build` → `quality_report.json` : évidence publiciste TESTS **« 23 → 24 méthodes »** ; **verdict PASS · 24/24 · min 100 inchangé** (aucun score bougé — le seul delta est le compte). (2) `regression_gen.py build` puis `run` → `regression_run.json` **628 → 629 exécutés · 611 → 612 passés · 17 skippés · 0 échec** (publiciste suite ran 23→24 / passed 21→22 — les 2 « non-incréments » = ses tests oracle jsonschema neutralisés par `python -S`, cf. `regression-baseline-17-skips-by-design`). (3) Surfaces de prose gatées re-dérivées (flaggées RED par `check_readme_claims`, corrigées) : fiche `03_agents/publiciste/AGENT.md:95` (cellule Tests **23 → 24** ← `count_tests`) + agrégat `03_agents/qa/AGENT.md:35` (**628/611 → 629/612**) + `03_agents/erpnext_backend/AGENT.md:40` (claim live **628 → 629**). Le `daily_reports/2026-08-11` (snapshot signé) et les logs = instantanés datés → laissés (`two-logging-channels`).
|
||||||
|
|
||||||
|
**Pourquoi pas un nouveau gate (#5).** La divergence de compte est déjà **structurellement gatée** (`check_readme_claims` a immédiatement rougi la fiche publiciste + l'agrégat QA dès le rebuild) et la teeth verrouille le comportement NBSP. Trou de couverture isolé, comblé à la source → pas de gate additionnel.
|
||||||
|
|
||||||
|
**Vérif.** `./run_ci.sh` = **33 PASS · 0 FAIL · 0 SKIP** rétabli après régénération. **0 code moteur V18** (bloqué #6), **0 module de production touché** (seul un test ajouté · la char-class de prod laissée intacte), **0 gate ajouté** (#5), **0 commande VPS** (#8), **0 API externe**. Fichiers : `05_deliverables_mvp/publiciste/tests/test_publiciste.py` (teeth) + `qa/audit_4big/out/quality_report.json` + `qa/regression/out/{regression_plan,regression_run,MANIFEST}.json` + `03_agents/{publiciste,qa,erpnext_backend}/AGENT.md` + ce journal.
|
||||||
@@ -13,7 +13,9 @@
|
|||||||
> ne casse un gate ; ils concernent le **périmètre produit** et l'état runtime **hors dépôt**
|
> ne casse un gate ; ils concernent le **périmètre produit** et l'état runtime **hors dépôt**
|
||||||
> (VPS `153.75.250.214` · `CLAUDE.md` #8), non vérifiable/éditable depuis le worker.
|
> (VPS `153.75.250.214` · `CLAUDE.md` #8), non vérifiable/éditable depuis le worker.
|
||||||
>
|
>
|
||||||
> **Mise à jour** — 2026-08-05 · session `20260805_014119`. Chaque ligne cite sa source exacte
|
> **Mise à jour** — 2026-08-11 · session `20260811_025754` (ajout du **bloc V18** D-06→D-08 :
|
||||||
|
> la séquence V18 moteur est intégralement suspendue à des arbitrages Michel — cf. audit de
|
||||||
|
> migration). Base 2026-08-05 · session `20260805_014119`. Chaque ligne cite sa source exacte
|
||||||
> et la session qui l'a surfacée en premier. **Ne pas re-surfacer** ces items en doublon (#5) :
|
> et la session qui l'a surfacée en premier. **Ne pas re-surfacer** ces items en doublon (#5) :
|
||||||
> pointer ici.
|
> pointer ici.
|
||||||
|
|
||||||
@@ -49,6 +51,13 @@ un module qui ne le produit pas. **Arbitrage de périmètre, pas une correction
|
|||||||
**Sources / surface** — décrit dans la mémoire projet `directive-vs-implementation` (« PIE SIGNAL »).
|
**Sources / surface** — décrit dans la mémoire projet `directive-vs-implementation` (« PIE SIGNAL »).
|
||||||
Non édité : cf. convention *SURFACE, don't rewrite*.
|
Non édité : cf. convention *SURFACE, don't rewrite*.
|
||||||
|
|
||||||
|
**Lien V18 (2026-08-11)** — L'audit de migration **remonte cet item au rang d'arbitrage V18** :
|
||||||
|
`OTO_V18_MIGRATION_ARCHITECTURE_AUDIT_20260810.md` §12.4 (:216) demande à Michel de trancher le
|
||||||
|
**périmètre de génération juridique (Section 13)** — « CONFOTUR seul (existant) ou aussi
|
||||||
|
Promesa/Fideicomiso/HOA (aucun code aujourd'hui) » — et **pointe explicitement ici**. Même décision
|
||||||
|
que D-01, désormais dans le chemin critique V18. Ne pas dédoubler : cet item **est** l'arbitrage
|
||||||
|
Section 13.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## D-02 · 🟠 Financement bancaire : condition #4 encore sur `wag_validated_by` (humain), directive V10 la remplace par un audit IA signé
|
## D-02 · 🟠 Financement bancaire : condition #4 encore sur `wag_validated_by` (humain), directive V10 la remplace par un audit IA signé
|
||||||
@@ -128,6 +137,78 @@ est **manuelle, hors dépôt**. Consigné ici pour éviter de ré-ouvrir le soup
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## D-06 · 🟠 V18 : approbation de l'audit de migration — gate d'entrée de TOUTE la séquence moteur V18
|
||||||
|
|
||||||
|
**Décision attendue** — Michel doit **approuver l'audit de migration V12→V18** (ou demander
|
||||||
|
révisions). Tant qu'il n'est pas validé, **aucune** phase de développement V18 ne peut démarrer :
|
||||||
|
c'est le premier maillon d'une chaîne à validation par étape.
|
||||||
|
|
||||||
|
**Constat** — Le GO signal de développement **n'active pas le code direct** ; il active une
|
||||||
|
**séquence à validation** dont l'audit est l'étape 1 et son approbation l'étape 2 :
|
||||||
|
- `V18_GO_SIGNAL_DEVELOPMENT_20260810.md:79-84` → « n'active PAS le code direct — il active la
|
||||||
|
séquence : 1. Audit V12→V18 · 2. **Validation Michel de l'audit** · 3. Phase 1 · 4. Validation
|
||||||
|
Michel Phase 1 · 5. Phase 2→15 avec validation à chaque phase ».
|
||||||
|
- `DIRECTIVE_V18_MASTER_FEASIBILITY_ENGINE_20260810.md:90-91` → INTERDICTIONS ABSOLUES : « NE PAS
|
||||||
|
coder avant l'audit ».
|
||||||
|
- Livrable produit et en attente : `OTO_V18_MIGRATION_ARCHITECTURE_AUDIT_20260810.md` §12 (:207-218),
|
||||||
|
recommandation + les 4 arbitrages Michel avant Phase 1.
|
||||||
|
|
||||||
|
**Pourquoi worker n'avance pas** — Coder un moteur V18 avant l'approbation violerait la directive
|
||||||
|
(« NE PAS coder avant l'audit ») et la séquence GO. **Blocage de gouvernance produit, pas un bug.**
|
||||||
|
|
||||||
|
**Sources / surface** — surfacé session `20260811_022753` (`05_activity_log/2026-08-11.md`, production
|
||||||
|
de l'audit) ; consolidé ici session `20260811_025754`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## D-07 · 🟠 V18 : formules financières (DCF · IRR/VAN · DSCR/LTV/LTC) absentes des docs lisibles — moteurs 4/8 bloqués
|
||||||
|
|
||||||
|
**Décision attendue** — Michel doit **fournir / rendre lisibles** les conventions financières exactes
|
||||||
|
(échéancier DCF, actualisation IRR/VAN, ratios bancaires DSCR/LTV/LTC, Cost Plan/WBS) attendues pour
|
||||||
|
les moteurs **Financial (4)** et **Bankability (8)**. Sans elles, coder ces moteurs = **inventer une
|
||||||
|
convention financière** — interdit par #6, risque de migration le plus grave (R1 🔴).
|
||||||
|
|
||||||
|
**Constat**
|
||||||
|
- `05_deliverables_mvp/faisabilite/bancable/banclib/finance.py` est un **snapshot** (coût · revenu ·
|
||||||
|
marge · point d'équilibre en unités) : `grep` confirme **aucun** `DSCR`/`LTV`/`LTC`, aucune
|
||||||
|
actualisation multi-période.
|
||||||
|
- Écart détaillé : `OTO_V18_MIGRATION_ARCHITECTURE_AUDIT_20260810.md` §5 (:102-114) et le point de
|
||||||
|
décision §12.2 (:214) ; risque R1 « inventer des formules » gravité 🔴 (:182), mitigation =
|
||||||
|
**bloquer moteur 4/8 avant lecture des formules par Michel**.
|
||||||
|
- Hypothèse déclarée §5 (:112) : les formules figurent **peut-être** dans la directive complète
|
||||||
|
57 chapitres et/ou les audits deep **root-owned illisibles** par le worker (#8).
|
||||||
|
|
||||||
|
**Pourquoi worker n'édite pas** — L'architecture V12 « valeur = {formule + opérandes sourcés/null} »
|
||||||
|
est le bon patron à **généraliser**, mais les formules elles-mêmes ne sont **pas dérivables** du code
|
||||||
|
lisible. **Dépendance d'entrée + arbitrage produit.**
|
||||||
|
|
||||||
|
**Sources / surface** — audit §5/§10-R1/§12.2 ; consolidé session `20260811_025754`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## D-08 · 🟠 V18 : confirmer que le Master Intake A1-A20 est un sur-ensemble STRICT du `brief.json` V12 (rétro-compat parser)
|
||||||
|
|
||||||
|
**Décision attendue** — Michel doit **confirmer** que le futur Master Data Model (A1-A20) **étend**
|
||||||
|
le schéma d'entrée V12 sans en casser les clés — pour éviter la création d'une **2e base** (R2 🔴)
|
||||||
|
et préserver le parser Publiciste / `projets_master` (R6).
|
||||||
|
|
||||||
|
**Constat**
|
||||||
|
- Recommandation data model : `OTO_V18_MIGRATION_ARCHITECTURE_AUDIT_20260810.md` §4 (:86-100) —
|
||||||
|
« One Master Dataset · Multiple Outputs » ; V12 le respecte déjà (bancable consomme le **même**
|
||||||
|
`brief.json` que le générateur).
|
||||||
|
- Point de décision §12.3 (:215) : confirmer le **sur-ensemble strict**. Séquence Phase 1 §11 (:197)
|
||||||
|
= étendre `brief.schema.json` → `master_intake.schema.json`, **rétro-compat garantie**, canoniques
|
||||||
|
réimposés.
|
||||||
|
- Risque R2 « créer une 2e base en dupliquant `brief.json` » gravité 🔴 (:183) ; mitigation = intake
|
||||||
|
= sur-ensemble strict du `brief.schema.json`.
|
||||||
|
|
||||||
|
**Pourquoi worker n'édite pas** — Décision d'architecture de données ; l'étendre présuppose la liste
|
||||||
|
fine A1-A20, contenue dans la directive complète **non lisible** (§0 · #8). **À valider avant Phase 1.**
|
||||||
|
|
||||||
|
**Sources / surface** — audit §4/§10-R2/§11/§12.3 ; consolidé session `20260811_025754`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Rappel de discipline
|
## Rappel de discipline
|
||||||
- Ces items sont **surfacés, pas tranchés** : les éditer côté worker violerait #6 (invention) ou
|
- Ces items sont **surfacés, pas tranchés** : les éditer côté worker violerait #6 (invention) ou
|
||||||
réécrirait une source d'autorité (`CLAUDE.md`, une directive datée).
|
réécrirait une source d'autorité (`CLAUDE.md`, une directive datée).
|
||||||
|
|||||||
@@ -0,0 +1,100 @@
|
|||||||
|
# Daily Report · 2026-08-11 · Claude Code DTP Worker
|
||||||
|
|
||||||
|
**Session** : `20260811_032800` · **actualisé** `20260811_092842` (fin de journée)
|
||||||
|
**HEAD attesté** : `35de616` (rapport initial émis à `18d8763` · **11 commits worker** ont
|
||||||
|
suivi le même jour — voir §« Jalons worker suivants »)
|
||||||
|
**Phase roadmap** : transition **V12 → V18** (Master Institutional Feasibility &
|
||||||
|
Bankability Engine). La roadmap 8-semaines classique (Sprints 1→8) reste **livrée +
|
||||||
|
gatée + verte** côté dépôt ; la nouvelle directive V18 rouvre le **moteur de
|
||||||
|
faisabilité** — mais sa séquence est **intégralement suspendue à des arbitrages Michel**
|
||||||
|
(voir §« Chemin critique bloqué »).
|
||||||
|
|
||||||
|
## Contexte — le canal stakeholder s'arrêtait au `2026-08-06` (HEAD `a8342e9`)
|
||||||
|
|
||||||
|
Le dernier rapport roadmap datait du **2026-08-06**. Depuis, **cinq commits** ont porté
|
||||||
|
l'arbre au HEAD courant `18d8763`, dont **trois jalons worker `[DTP-Worker]`** que ce
|
||||||
|
canal ne reflétait pas encore. Ce rapport porte le canal stakeholder au point courant et
|
||||||
|
**re-dérive tous les chiffres depuis les artefacts commités** (aucun chiffre figé, #6).
|
||||||
|
|
||||||
|
| Jalon | Commit (session) | Nature | Opposabilité au merge |
|
||||||
|
|---|---|---|---|
|
||||||
|
| **FIX CI RED → VERT** | `0b453c5` (`015744`) | 2 régressions **induites par les commits root V18** de Michel (archivage V10/V11 + 4 docs REFERENCE root-owned mode 600) : lien pendant `README.md` + `check_readme_claims` butant sur `PermissionError`. Repointé le lien vers la directive V18 active ; ajouté un `except PermissionError` **spécifique** (tolère l'illisible « pas notre fichier », garde tout autre `OSError` fatal). | **Opposable** : gate remis **33/0/0** ; 0 artefact reconstruit. |
|
||||||
|
| **AUDIT préalable V18** | `de837fa` (`022753`) | Production de `OTO_V18_MIGRATION_ARCHITECTURE_AUDIT_20260810.md` — **PREMIÈRE ACTION OBLIGATOIRE** du GO signal V18 (« NE PAS coder avant l'audit »). Mapping **18 sections** point-par-point (2 ✅ · 7 🟠 · 9 🔴), data model « One Master Dataset », 8 risques, séquence 15 phases, **4 arbitrages Michel** avant Phase 1. Fondé sur le **code V12 lisible uniquement** (anti-invention #6 ; les audits deep de Michel sont root-owned illisibles #8). | **Non opposable** (livrable = document · 0 code moteur). |
|
||||||
|
| **REGISTRE décisions V18** | `18d8763` (`025754`) | Consolidation des 4 arbitrages dans `OPEN_DECISIONS_REGISTER.md` → **D-06 → D-08** (+ **D-01 remonté** au chemin critique V18). Le registre **regroupe et source, ne tranche pas**. | **Non opposable** (doc punch-list · #5 ne pas re-surfacer). |
|
||||||
|
|
||||||
|
## Jalons worker suivants du 2026-08-11 (`18d8763` → `35de616`)
|
||||||
|
|
||||||
|
Après l'émission du rapport initial, **huit jalons `[DTP-Worker]`** ont porté l'arbre au
|
||||||
|
HEAD courant `35de616`, tous **sur l'arbre vert** et **hors code moteur V18** (séquence
|
||||||
|
toujours bloquée · #6). Deux catégories :
|
||||||
|
|
||||||
|
| Jalon | Commit | Nature | Opposabilité |
|
||||||
|
|---|---|---|---|
|
||||||
|
| **Exactitude audit V18** | `c3f5664` + `460574a` | Corrigé un claim LOC stale (`generator` 446 → **622**, contradiction interne vs total 1262) puis **Annexe A reproductible** (chaque chiffre de l'audit apparié à la commande qui le re-dérive → gate-doc auto-auditable anti-drift #6). | Non opposable (doc). |
|
||||||
|
| **Bannières statut V18** ×4 modules-origine | `72753a6` `6970294` `f3419f9` `37c1e97` | Bannière `⚠️ Statut migration V18` en tête des **4 modules-origine** ✅/🟠 du mapping audit §3 : fiches `faisabilite/` + `bim/`, READMEs `bancable` + `legal/confotur` — chacun cadré « état commité courant, pas la cible V18 », 3 liens sourcés (directive · audit · registre D-xx). **Alignement des surfaces doc sur le pivot : clos** pour les modules réels impactés. | Non opposable (doc · `quality_report` byte-count régénéré, PASS 24/24 inchangé). |
|
||||||
|
| **Liage index racine** | `344b815` | Les 2 derniers docs de gouvernance V18 tracked+lisibles (`V18_GO_SIGNAL_DEVELOPMENT` · `V18_ADDENDUM_SECTION_60`) liés depuis le README → les **4 documents de gouvernance V18** sont désormais atteignables depuis le point d'entrée du mandat. | Non opposable (doc). |
|
||||||
|
| **FIX correctness `audit_4big`** (1/3 · char-class) | `ac595d0` | **Vrai bug corrigé** : `q4lib/criteria.py` comptait les méthodes `test_*` via une char-class **ASCII** (`[A-Za-z0-9_]`) → loupait le test réel `test_traçabilite_source` (le `ç`, PEP 3131), publiant « 22 méthodes » au lieu de **23** pour `publiciste`. Aligné sur la source sœur `reglib.discovery` (`\w` Unicode-aware) + **teeth** ajoutée. Cascade régénérée : `regression_run.json` **625 → 626 / 608 → 609**. | **Opposable** : fait publié faux (violation cœur anti-invention #6 de l'audit) rendu exact ; gate reste 33/0/0. |
|
||||||
|
| **FIX correctness `audit_4big`** (2/3 · garde `__main__`) | `fd99362` | **Robustesse de contrat** : le critère CLI détectait l'entrypoint `__main__` par un **littéral figé double-quoté** (`'__name__ == "__main__"' in src`) → loupait silencieusement les gardes **simple-quotées** / **« Yoda »** (opérandes inversés) / **sans-espaces**, toutes du Python valide → sous-scorage CLI **−20 pts** d'un module sain. Remplacé par une regex de **forme** (deux styles de guillemets · ordre libre · espacement libre) + **teeth** 3 fixtures. Occurrence latente (les 50 gardes du dépôt sont double-quotées) → `quality_report.json` byte-identique. Cascade : `regression_run.json` **626 → 627 / 609 → 610**. | **Opposable** : logique de détection de l'outil d'audit #6 rendue exacte pour **tout** Python valide ; gate reste 33/0/0. |
|
||||||
|
| **FIX correctness `audit_4big`** (3/3 · séparateur `def`) | `35de616` | **Complète le fix ASCII, laissé à moitié** : le compteur de tests d'`audit_4big` gardait `def ` (**un espace littéral figé**) là où la source sœur `reglib.discovery` a `def\s+` → `def test_x(` (deux espaces) / `def\ttest_x(` (tab), du Python valide, **loupés** = sous-comptage silencieux + désaccord avec l'autorité byte-gatée de la colonne « Tests » des fiches. Aligné `def ` → `def\s+` (forme strictement identique à la sœur) + **teeth**. Occurrence latente (tous les `def` du dépôt en un-espace PEP 8) → `quality_report.json` byte-identique. Cascade : `regression_run.json` **627 → 628 / 610 → 611**. | **Opposable** : les deux compteurs du **même concept** coïncident désormais sur toute graphie valide ; gate reste 33/0/0. |
|
||||||
|
|
||||||
|
> **Événement produit le plus notable du jour** = l'**arc de fixes `audit_4big`**
|
||||||
|
> (`ac595d0` → `fd99362` → `35de616`) : trois défauts de la **même racine** (« détecter
|
||||||
|
> la _forme_, pas une _graphie_ ») **dans l'outil d'audit qualité lui-même** — il
|
||||||
|
> sous-comptait/sous-scorait ses propres faits sur du Python pourtant valide. Chacun
|
||||||
|
> corrigé à la source unique avec une teeth prouvée mordante ; **classe désormais close**
|
||||||
|
> (char-class Unicode · garde `__main__` multi-graphie · séparateur `def` multi-espace).
|
||||||
|
|
||||||
|
## ⛔ Chemin critique bloqué — la séquence moteur V18 attend Michel
|
||||||
|
|
||||||
|
Le GO signal impose : **audit → validation Michel → Phase 1**
|
||||||
|
(`V18_GO_SIGNAL_DEVELOPMENT_20260810.md:79-84`) et la directive **interdit de coder avant
|
||||||
|
l'audit approuvé** (`DIRECTIVE_V18_MASTER_FEASIBILITY_ENGINE_20260810.md:90-91`). L'audit
|
||||||
|
**est produit** — mais **aucune ligne de code moteur V18 n'est légitime** tant que ces
|
||||||
|
arbitrages ne sont pas rendus (les coder violerait la directive **et** #6). Les décisions
|
||||||
|
sont consignées dans `05_deliverables_mvp/OPEN_DECISIONS_REGISTER.md` :
|
||||||
|
|
||||||
|
| Item | Décision attendue de Michel | Pourquoi bloquant |
|
||||||
|
|---|---|---|
|
||||||
|
| **D-06** 🟠 | **Approuver l'audit** V12→V18 | Gate d'entrée de **toute** la séquence moteur. |
|
||||||
|
| **D-07** 🟠 | **Fournir les formules financières** (DCF · IRR/VAN · DSCR/LTV/LTC) | `finance.py` est un snapshot **sans** ces ratios (`grep` confirmé) → moteurs Financial/Bankability **4/8 bloqués** · **risque d'invention #6 le plus grave (R1 🔴)**. |
|
||||||
|
| **D-08** 🟠 | Confirmer **Master Intake A1-A20 = sur-ensemble strict du `brief.json`** | Éviter une 2e base de données (R2 🔴), préserver le parser existant. |
|
||||||
|
| **D-01** 🟠 | Trancher le **périmètre juridique Section 13** (CONFOTUR seul, ou aussi Promesa/Fideicomiso/HOA) | Aucun code ne génère aujourd'hui ces contrats ; arbitrage de périmètre, pas un bug worker. |
|
||||||
|
|
||||||
|
> **Action Michel** — l'approbation D-06 + les formules D-07 débloquent la Phase 1
|
||||||
|
> (Master Project Intake / Data Model). Escalation : WhatsApp `+18296296385` ·
|
||||||
|
> `mroy@worldactivitiesrd.com`.
|
||||||
|
|
||||||
|
## État courant · chiffres re-dérivés d'artefacts commités (HEAD `35de616`)
|
||||||
|
|
||||||
|
| Métrique | Valeur | Source (re-calculée ce jour) |
|
||||||
|
|---|---|---|
|
||||||
|
| Gate de merge | **33 PASS · 0 FAIL · 0 SKIP** | `run_ci.sh` (= 8 statiques + 25 suites) |
|
||||||
|
| Gates statiques | **8** | `git ls-files 'ci/*.sh'` hors `lib.sh` |
|
||||||
|
| Suites de modules | **25** | jobs `*-tests` de `gate.needs` (`.gitea/workflows/ci.yml`) |
|
||||||
|
| Matrice de régression | **628 exécutés · 611 passés · 17 skippés · 0 échec** — **PASS** | `qa/regression/out/regression_run.json` (`totals`) |
|
||||||
|
| Audit 4Big | **verdict PASS · 24 modules · score min 100/100** | `qa/audit_4big/out/quality_report.json` (`verdict` · `modules` · `coverage`) |
|
||||||
|
| Bijection couverture | **24 CI ↔ 24 registre** (`ok`) | `quality_report.json` (`coverage`) |
|
||||||
|
|
||||||
|
Les **17 skips** sont l'oracle `jsonschema` OPTIONNEL neutralisé par `python -S` (par
|
||||||
|
design ; lecture stakeholder = **611 passés + 17 skippés**, **pas** 628 — voir baseline
|
||||||
|
régression). La matrice a évolué **quatre fois** depuis le 2026-08-06 : 624→625 / 607→608
|
||||||
|
(wiring de `brief.schema.json` via un test validateur, avant ce rapport), puis **trois
|
||||||
|
teeth successives** ce jour ajoutées par l'arc de fixes `audit_4big` — 625 → 626 / 608 → 609
|
||||||
|
(`ac595d0`, char-class), 626 → 627 / 609 → 610 (`fd99362`, garde `__main__`), 627 → 628 /
|
||||||
|
610 → 611 (`35de616`, séparateur `def`) — **sans nouveau gate** (la divergence de compte est
|
||||||
|
déjà structurellement rougie par `check_readme_claims`).
|
||||||
|
|
||||||
|
## Portée / anti-churn (session `032800`)
|
||||||
|
|
||||||
|
- **0 commande VPS** (#8) · **0 API externe payante** · **0 code moteur V18** (séquence
|
||||||
|
suspendue à Michel).
|
||||||
|
- **0 fichier de production édité** cette session, **0 artefact reconstruit**, **0 gate
|
||||||
|
ajouté** (#5) : le livrable est ce **rapport stakeholder** (currency du canal +
|
||||||
|
remontée explicite du chemin critique bloqué) + le journal `05_activity_log/`.
|
||||||
|
- Tous les chiffres ci-dessus dérivent d'artefacts **commités**, jamais figés (#6).
|
||||||
|
- **Currency `20260811_092842`** : ce rapport re-épinglé de `ac595d0` → `35de616` (2
|
||||||
|
fixes correctness `audit_4big` de plus : `fd99362` garde `__main__` · `35de616`
|
||||||
|
séparateur `def`) ; régression re-dérivée **626/609 → 628/611** depuis `regression_run.json`
|
||||||
|
(`totals`). Aucun code moteur V18 · aucune commande VPS · aucun gate ajouté.
|
||||||
|
|
||||||
|
**Gate au dépôt** : `./run_ci.sh` → **33 PASS · 0 FAIL · 0 SKIP** (inchangé).
|
||||||
@@ -8,6 +8,21 @@
|
|||||||
> FR/EN/ES ») — un libellé de planification, **pas** un texte du fichier roadmap —
|
> FR/EN/ES ») — un libellé de planification, **pas** un texte du fichier roadmap —
|
||||||
> exigée par le **Portail Bancables 4Big** (ci-dessous).
|
> exigée par le **Portail Bancables 4Big** (ci-dessous).
|
||||||
|
|
||||||
|
> ⚠️ **Statut migration V18.** D'après la cartographie de l'audit de migration V12→V18,
|
||||||
|
> **ce module `bancable` est la graine V12 des moteurs financiers V18** : Section 15
|
||||||
|
> **Bankability** (« le plus mûr » du mapping) et, partiellement, Section 12
|
||||||
|
> **Financier/DCF**. Il est à ce titre au **cœur du risque de migration le plus grave
|
||||||
|
> (R1 🔴)** : généraliser ce *snapshot* statique (coût · revenu · marge · point d'équilibre
|
||||||
|
> en unités) vers les **moteurs Financial (4)** et **Bankability (8)** exige les formules
|
||||||
|
> **DCF · IRR/VAN · DSCR/LTV/LTC** — **absentes du code lisible** (`grep` sur `banclib/`
|
||||||
|
> ne rend rien) et **non devinables** sans les rendre lisibles côté Michel (#6). Toute la
|
||||||
|
> séquence moteur V18 est par ailleurs **suspendue** à l'approbation de l'audit. **Ne
|
||||||
|
> coder aucun de ces moteurs avant arbitrage.** La documentation ci-dessous décrit l'**état
|
||||||
|
> V12 commité** — *pas* la cible V18.
|
||||||
|
> Sources : [`DIRECTIVE_V18_MASTER_FEASIBILITY_ENGINE_20260810.md`](../../../DIRECTIVE_V18_MASTER_FEASIBILITY_ENGINE_20260810.md) ·
|
||||||
|
> [`OTO_V18_MIGRATION_ARCHITECTURE_AUDIT_20260810.md`](../../../OTO_V18_MIGRATION_ARCHITECTURE_AUDIT_20260810.md) (§3 mapping · §5 · R1) ·
|
||||||
|
> [`OPEN_DECISIONS_REGISTER.md`](../../OPEN_DECISIONS_REGISTER.md) (D-06 · D-07).
|
||||||
|
|
||||||
Remplit le répertoire `50_financier_bancable/` d'une data_room — jusqu'ici **vide**
|
Remplit le répertoire `50_financier_bancable/` d'une data_room — jusqu'ici **vide**
|
||||||
(`.gitkeep` posé par le générateur 4 volets) — que le **Portail Bancables 4Big**
|
(`.gitkeep` posé par le générateur 4 volets) — que le **Portail Bancables 4Big**
|
||||||
([`PORTAIL_BANCABLES_4BIG.md`](../../../PORTAIL_BANCABLES_4BIG.md), variante 06
|
([`PORTAIL_BANCABLES_4BIG.md`](../../../PORTAIL_BANCABLES_4BIG.md), variante 06
|
||||||
|
|||||||
@@ -5,6 +5,24 @@
|
|||||||
> d'incitation touristique **CONFOTUR** (Ley 158-01, République Dominicaine),
|
> d'incitation touristique **CONFOTUR** (Ley 158-01, République Dominicaine),
|
||||||
> jusqu'ici référencé partout (RBAC, workflow vente) mais jamais généré.
|
> jusqu'ici référencé partout (RBAC, workflow vente) mais jamais généré.
|
||||||
|
|
||||||
|
> **⚠️ Statut migration V18 (2026-08-10) · à lire AVANT le reste de ce module.** Michel a émis
|
||||||
|
> la [`DIRECTIVE_V18_MASTER_FEASIBILITY_ENGINE_20260810.md`](../../../DIRECTIVE_V18_MASTER_FEASIBILITY_ENGINE_20260810.md)
|
||||||
|
> — un **Master Institutional Feasibility & Bankability Engine** à 18 sections dont la
|
||||||
|
> **Section 13 · Juridique**. L'audit préalable
|
||||||
|
> [`OTO_V18_MIGRATION_ARCHITECTURE_AUDIT_20260810.md`](../../../OTO_V18_MIGRATION_ARCHITECTURE_AUDIT_20260810.md)
|
||||||
|
> (V12→V18, produit **avant tout code**) mappe cette Section 13 à **ce module** avec un verdict
|
||||||
|
> **🟠 amorce partielle** (§3) : le générateur ci-dessous produit **le DocType CONFOTUR seul**,
|
||||||
|
> alors que la Section 13 V18 attend aussi les **contrats types Promesa de compraventa ·
|
||||||
|
> Fideicomiso d'adhésion · règlement HOA** — dont **aucun n'est généré aujourd'hui**. Cet écart
|
||||||
|
> de périmètre est l'arbitrage produit **D-01** du
|
||||||
|
> [`OPEN_DECISIONS_REGISTER.md`](../../OPEN_DECISIONS_REGISTER.md) (Section 13 : CONFOTUR seul ou
|
||||||
|
> aussi Promesa/Fideicomiso/HOA), désormais dans le chemin critique V18 ; en amont, **D-06**
|
||||||
|
> (approbation de l'audit de migration par Michel) est le gate d'entrée de **toute** la séquence
|
||||||
|
> moteur. Tant que ces décisions ne sont pas rendues, **aucun code moteur V18 n'est produit**
|
||||||
|
> (directive : « NE PAS coder avant l'audit approuvé » · anti-invention `CLAUDE.md` #6) : le
|
||||||
|
> socle CONFOTUR ci-dessous reste réutilisable, mais **la doc ci-dessous décrit l'état commité
|
||||||
|
> courant, pas la cible finale V18.**
|
||||||
|
|
||||||
## Ce que ça produit
|
## Ce que ça produit
|
||||||
|
|
||||||
`build` écrit deux fichiers de hand-off dans `out/` :
|
`build` écrit deux fichiers de hand-off dans `out/` :
|
||||||
|
|||||||
@@ -39,6 +39,21 @@ class TestNumberParsing(unittest.TestCase):
|
|||||||
self.assertEqual(parser.parse_price("DOP 8 850 000"), 8850000.0)
|
self.assertEqual(parser.parse_price("DOP 8 850 000"), 8850000.0)
|
||||||
self.assertEqual(parser.parse_price("1,250,000.50"), 1250000.50)
|
self.assertEqual(parser.parse_price("1,250,000.50"), 1250000.50)
|
||||||
|
|
||||||
|
def test_prix_espace_insecable_milliers(self):
|
||||||
|
# Les outils d'édition FR/ES (Word, InDesign) insèrent l'ESPACE INSÉCABLE
|
||||||
|
# U+00A0 comme séparateur de milliers dans les prix réels des data_room.
|
||||||
|
# `lib/parser.py` la capte via une char-class Unicode-whitespace (`\s`).
|
||||||
|
# Verrou : ce test mord si l'on réduit cette capture à de l'ASCII pur
|
||||||
|
# (retrait de TOUTE prise en charge whitespace-Unicode → seul le 1er
|
||||||
|
# chiffre survit, ex. 8.0 au lieu de 8 850 000) — même racine « détecter
|
||||||
|
# la forme, pas une graphie » que l'arc de fixes audit_4big.
|
||||||
|
# NBSP en escape explicite \u00a0 pour garder l'intention lisible (0 octet invisible).
|
||||||
|
nb = "\u00a0"
|
||||||
|
self.assertEqual(parser.parse_price(f"DOP 8{nb}850{nb}000"), 8850000.0)
|
||||||
|
self.assertEqual(parser.parse_price(f"USD 1{nb}250{nb}000,50"), 1250000.50)
|
||||||
|
self.assertEqual(parser.parse_number(f"1{nb}250"), 1250.0)
|
||||||
|
self.assertEqual(parser.parse_int(f"12{nb}unités"), 12)
|
||||||
|
|
||||||
def test_absents_donnent_none(self):
|
def test_absents_donnent_none(self):
|
||||||
for token in ["", "—", "-", "non défini", "n/d", "{{typo_1_prix_usd}}", "...", "TBD"]:
|
for token in ["", "—", "-", "non défini", "n/d", "{{typo_1_prix_usd}}", "...", "TBD"]:
|
||||||
self.assertIsNone(parser.parse_price(token), f"{token!r} devrait être None")
|
self.assertIsNone(parser.parse_price(token), f"{token!r} devrait être None")
|
||||||
|
|||||||
@@ -60,7 +60,7 @@
|
|||||||
"criterion": "TESTS",
|
"criterion": "TESTS",
|
||||||
"weight": 25,
|
"weight": 25,
|
||||||
"passed": true,
|
"passed": true,
|
||||||
"evidence": "22 méthodes test_* dans 1 fichier(s) (seuil 8)"
|
"evidence": "24 méthodes test_* dans 1 fichier(s) (seuil 8)"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"criterion": "CLI",
|
"criterion": "CLI",
|
||||||
@@ -282,7 +282,7 @@
|
|||||||
"criterion": "DOC",
|
"criterion": "DOC",
|
||||||
"weight": 20,
|
"weight": 20,
|
||||||
"passed": true,
|
"passed": true,
|
||||||
"evidence": "README.md (6439 octets)"
|
"evidence": "README.md (7748 octets)"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"criterion": "CONTRAT",
|
"criterion": "CONTRAT",
|
||||||
@@ -606,7 +606,7 @@
|
|||||||
"criterion": "DOC",
|
"criterion": "DOC",
|
||||||
"weight": 20,
|
"weight": 20,
|
||||||
"passed": true,
|
"passed": true,
|
||||||
"evidence": "README.md (4888 octets)"
|
"evidence": "README.md (6436 octets)"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"criterion": "CONTRAT",
|
"criterion": "CONTRAT",
|
||||||
|
|||||||
@@ -15,8 +15,23 @@ import json
|
|||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
|
||||||
_TEST_DEF_RE = re.compile(r"^\s*def (test_[A-Za-z0-9_]+)\s*\(", re.MULTILINE)
|
# `\w` (Unicode) pour les identifiants accentués (`test_traçabilite_source`) ET
|
||||||
|
# `def\s+` (espacement libre) : `def test_x(` / `def\ttest_x(` sont du Python
|
||||||
|
# valide (PEP 8 recommande un espace mais le langage n'en impose pas). Forme
|
||||||
|
# STRICTEMENT identique à la source sœur `reglib/discovery.py:_TEST_METHOD_RE`,
|
||||||
|
# autorité byte-gatée de la colonne « Tests » des fiches — les deux compteurs du
|
||||||
|
# MÊME concept doivent coïncider (sinon dérive d'évidence #6, cf. le fix ASCII).
|
||||||
|
_TEST_DEF_RE = re.compile(r"^\s*def\s+(test_\w+)\s*\(", re.MULTILINE)
|
||||||
_ADD_PARSER_RE = re.compile(r"add_parser\(|add_subparsers\(")
|
_ADD_PARSER_RE = re.compile(r"add_parser\(|add_subparsers\(")
|
||||||
|
# Garde `if __name__ == "__main__":` — les DEUX styles de guillemets sont du
|
||||||
|
# Python valide (PEP 8 n'impose rien), l'ordre des opérandes peut être inversé
|
||||||
|
# (« Yoda »), et l'espacement autour de `==` est libre. Un littéral figé
|
||||||
|
# `'__name__ == "__main__"'` louperait un entrypoint valide simple-quoté →
|
||||||
|
# sous-scorage silencieux du critère CLI. Détecter la forme, pas une graphie.
|
||||||
|
_MAIN_GUARD_RE = re.compile(
|
||||||
|
r"""__name__\s*==\s*['"]__main__['"]"""
|
||||||
|
r"""|['"]__main__['"]\s*==\s*__name__"""
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def _direct_files(mod_dir: str, suffix: str) -> list[str]:
|
def _direct_files(mod_dir: str, suffix: str) -> list[str]:
|
||||||
@@ -75,7 +90,7 @@ def crit_cli(mod_dir: str) -> dict:
|
|||||||
for py in _direct_files(mod_dir, ".py"):
|
for py in _direct_files(mod_dir, ".py"):
|
||||||
with open(py, encoding="utf-8") as fh:
|
with open(py, encoding="utf-8") as fh:
|
||||||
src = fh.read()
|
src = fh.read()
|
||||||
if '__name__ == "__main__"' in src and _ADD_PARSER_RE.search(src):
|
if _MAIN_GUARD_RE.search(src) and _ADD_PARSER_RE.search(src):
|
||||||
return {"passed": True,
|
return {"passed": True,
|
||||||
"evidence": f"{os.path.basename(py)} (argparse + __main__)"}
|
"evidence": f"{os.path.basename(py)} (argparse + __main__)"}
|
||||||
return {"passed": False,
|
return {"passed": False,
|
||||||
|
|||||||
@@ -106,6 +106,47 @@ class CriteriaTest(unittest.TestCase):
|
|||||||
mod = _make_module(d, tests=9)
|
mod = _make_module(d, tests=9)
|
||||||
self.assertTrue(criteria.crit_tests(mod, 8)["passed"])
|
self.assertTrue(criteria.crit_tests(mod, 8)["passed"])
|
||||||
|
|
||||||
|
def test_tests_counts_non_ascii_method_names(self):
|
||||||
|
# Régression : un nom de méthode accentué (PEP 3131, ex. réel
|
||||||
|
# `test_traçabilite_source` dans publiciste) est un test valide et
|
||||||
|
# exécuté par unittest — le comptage doit l'inclure, comme la source
|
||||||
|
# sœur reglib.discovery (`test_\w+`, \w Unicode). L'ancien char-class
|
||||||
|
# ASCII `[A-Za-z0-9_]` le loupait → sous-comptage (22 au lieu de 23)
|
||||||
|
# et fait faux dans l'évidence, en violation du cœur anti-invention #6.
|
||||||
|
with tempfile.TemporaryDirectory() as d:
|
||||||
|
mod = os.path.join(d, "mod")
|
||||||
|
tdir = os.path.join(mod, "tests")
|
||||||
|
os.makedirs(tdir)
|
||||||
|
with open(os.path.join(tdir, "test_mod.py"), "w",
|
||||||
|
encoding="utf-8") as fh:
|
||||||
|
fh.write("import unittest\nclass T(unittest.TestCase):\n"
|
||||||
|
" def test_ascii(self):\n pass\n"
|
||||||
|
" def test_traçabilite_source(self):\n"
|
||||||
|
" pass\n")
|
||||||
|
res = criteria.crit_tests(mod, 1)
|
||||||
|
self.assertIn("2 méthodes", res["evidence"])
|
||||||
|
|
||||||
|
def test_tests_counts_non_single_space_def_separator(self):
|
||||||
|
# Robustesse (complète l'alignement char-class du fix ASCII) : `def` et
|
||||||
|
# le nom de méthode peuvent être séparés par PLUSIEURS espaces ou une
|
||||||
|
# tabulation — du Python valide. Le littéral `def ` (un seul espace)
|
||||||
|
# loupait `def test_x(` / `def\ttest_x(` → sous-comptage silencieux et
|
||||||
|
# DÉSACCORD avec la source sœur reglib.discovery (`def\s+`), autorité de
|
||||||
|
# la colonne « Tests » des fiches. Les deux compteurs du MÊME concept
|
||||||
|
# doivent coïncider sur toute graphie valide (#6).
|
||||||
|
with tempfile.TemporaryDirectory() as d:
|
||||||
|
mod = os.path.join(d, "mod")
|
||||||
|
tdir = os.path.join(mod, "tests")
|
||||||
|
os.makedirs(tdir)
|
||||||
|
with open(os.path.join(tdir, "test_mod.py"), "w",
|
||||||
|
encoding="utf-8") as fh:
|
||||||
|
fh.write("import unittest\nclass T(unittest.TestCase):\n"
|
||||||
|
" def test_one_space(self):\n pass\n"
|
||||||
|
" def test_two_spaces(self):\n pass\n"
|
||||||
|
" def\ttest_tab(self):\n pass\n")
|
||||||
|
res = criteria.crit_tests(mod, 1)
|
||||||
|
self.assertIn("3 méthodes", res["evidence"])
|
||||||
|
|
||||||
def test_cli_fails_without_entrypoint(self):
|
def test_cli_fails_without_entrypoint(self):
|
||||||
with tempfile.TemporaryDirectory() as d:
|
with tempfile.TemporaryDirectory() as d:
|
||||||
mod = _make_module(d, cli=False)
|
mod = _make_module(d, cli=False)
|
||||||
@@ -117,6 +158,27 @@ class CriteriaTest(unittest.TestCase):
|
|||||||
mod = _make_module(d, cli=False)
|
mod = _make_module(d, cli=False)
|
||||||
self.assertFalse(criteria.crit_cli(mod)["passed"])
|
self.assertFalse(criteria.crit_cli(mod)["passed"])
|
||||||
|
|
||||||
|
def test_cli_detects_single_quoted_and_yoda_guards(self):
|
||||||
|
# Robustesse : `if __name__ == '__main__':` (simple quote) et la forme
|
||||||
|
# « Yoda » `if "__main__" == __name__:` sont du Python VALIDE — un
|
||||||
|
# entrypoint réel. Le littéral figé `'__name__ == "__main__"'` les
|
||||||
|
# loupait → sous-scorage silencieux du critère CLI (−20 pts sur un
|
||||||
|
# module sain), en violation du cœur anti-invention #6 de l'audit.
|
||||||
|
for guard in ("if __name__ == '__main__':\n pass\n",
|
||||||
|
'if "__main__" == __name__:\n pass\n',
|
||||||
|
"if __name__=='__main__':\n pass\n"):
|
||||||
|
with tempfile.TemporaryDirectory() as d:
|
||||||
|
mod = os.path.join(d, "mod")
|
||||||
|
os.makedirs(mod)
|
||||||
|
with open(os.path.join(mod, "mod_gen.py"), "w",
|
||||||
|
encoding="utf-8") as fh:
|
||||||
|
fh.write('import argparse\n'
|
||||||
|
'ap = argparse.ArgumentParser()\n'
|
||||||
|
'sub = ap.add_subparsers()\n'
|
||||||
|
'sub.add_parser("build")\n' + guard)
|
||||||
|
self.assertTrue(criteria.crit_cli(mod)["passed"],
|
||||||
|
f"garde non détectée : {guard!r}")
|
||||||
|
|
||||||
def test_handoff_fails_without_manifest(self):
|
def test_handoff_fails_without_manifest(self):
|
||||||
with tempfile.TemporaryDirectory() as d:
|
with tempfile.TemporaryDirectory() as d:
|
||||||
mod = _make_module(d, handoff=False)
|
mod = _make_module(d, handoff=False)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
"version": "1.0",
|
"version": "1.0",
|
||||||
"verdict": "PASS",
|
"verdict": "PASS",
|
||||||
"suites": 24,
|
"suites": 24,
|
||||||
"test_methods": 625,
|
"test_methods": 629,
|
||||||
"coverage_ok": true,
|
"coverage_ok": true,
|
||||||
"artifacts": [
|
"artifacts": [
|
||||||
"regression_plan.json"
|
"regression_plan.json"
|
||||||
|
|||||||
@@ -189,7 +189,7 @@
|
|||||||
"in_gate": true,
|
"in_gate": true,
|
||||||
"has_tests_dir": true,
|
"has_tests_dir": true,
|
||||||
"test_files": 1,
|
"test_files": 1,
|
||||||
"test_methods": 23
|
"test_methods": 24
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "qa.acceptance",
|
"id": "qa.acceptance",
|
||||||
@@ -211,7 +211,7 @@
|
|||||||
"in_gate": true,
|
"in_gate": true,
|
||||||
"has_tests_dir": true,
|
"has_tests_dir": true,
|
||||||
"test_files": 1,
|
"test_files": 1,
|
||||||
"test_methods": 34
|
"test_methods": 37
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "qa.audit_5d",
|
"id": "qa.audit_5d",
|
||||||
@@ -295,7 +295,7 @@
|
|||||||
"totals": {
|
"totals": {
|
||||||
"suites": 24,
|
"suites": 24,
|
||||||
"test_files": 24,
|
"test_files": 24,
|
||||||
"test_methods": 625,
|
"test_methods": 629,
|
||||||
"min_methods": 10,
|
"min_methods": 10,
|
||||||
"under_threshold": 0
|
"under_threshold": 0
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -174,9 +174,9 @@
|
|||||||
{
|
{
|
||||||
"id": "publiciste",
|
"id": "publiciste",
|
||||||
"path": "publiciste",
|
"path": "publiciste",
|
||||||
"expected_methods": 23,
|
"expected_methods": 24,
|
||||||
"ran": 23,
|
"ran": 24,
|
||||||
"passed": 21,
|
"passed": 22,
|
||||||
"failures": 0,
|
"failures": 0,
|
||||||
"errors": 0,
|
"errors": 0,
|
||||||
"skipped": 2,
|
"skipped": 2,
|
||||||
@@ -198,9 +198,9 @@
|
|||||||
{
|
{
|
||||||
"id": "qa.audit_4big",
|
"id": "qa.audit_4big",
|
||||||
"path": "qa/audit_4big",
|
"path": "qa/audit_4big",
|
||||||
"expected_methods": 34,
|
"expected_methods": 37,
|
||||||
"ran": 34,
|
"ran": 37,
|
||||||
"passed": 34,
|
"passed": 37,
|
||||||
"failures": 0,
|
"failures": 0,
|
||||||
"errors": 0,
|
"errors": 0,
|
||||||
"skipped": 0,
|
"skipped": 0,
|
||||||
@@ -296,8 +296,8 @@
|
|||||||
"suites": 24,
|
"suites": 24,
|
||||||
"green": 24,
|
"green": 24,
|
||||||
"red": 0,
|
"red": 0,
|
||||||
"ran": 625,
|
"ran": 629,
|
||||||
"passed": 608,
|
"passed": 612,
|
||||||
"failures": 0,
|
"failures": 0,
|
||||||
"errors": 0,
|
"errors": 0,
|
||||||
"skipped": 17
|
"skipped": 17
|
||||||
|
|||||||
@@ -0,0 +1,245 @@
|
|||||||
|
# OTO V18 · MIGRATION & ARCHITECTURE AUDIT
|
||||||
|
|
||||||
|
**Statut :** LIVRABLE PRÉALABLE OBLIGATOIRE — *avant tout code V18*
|
||||||
|
**Version audit :** 1.0 · rédigé 2026-08-11 (fichier daté `20260810` conformément au nom imposé par la directive)
|
||||||
|
**Auteur :** Claude Code DTP Worker (agent autonome · repo `oto-enterprise-os-dtp`)
|
||||||
|
**Directives sources (lisibles) :** `DIRECTIVE_V18_MASTER_FEASIBILITY_ENGINE_20260810.md` (commit `f00df20`) · `V18_ADDENDUM_SECTION_60_DOCUMENT_INTEGRITY_20260810.md` (`be8bfda`) · `V18_GO_SIGNAL_DEVELOPMENT_20260810.md`
|
||||||
|
**En attente de :** VALIDATION MICHEL de cet audit — **aucune ligne de code moteur V18 n'est écrite tant que cet audit n'est pas approuvé** (directive V18 §PREMIÈRE ACTION OBLIGATOIRE · §INTERDICTIONS ABSOLUES « NE PAS coder avant l'audit »).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 0. Raison d'être & méthode
|
||||||
|
|
||||||
|
La directive V18 exige, **en première action obligatoire**, un « OTO V18 · MIGRATION & ARCHITECTURE AUDIT » (25-26 points) **avant** d'écrire le moindre moteur. Le GO signal `V18_GO_SIGNAL_DEVELOPMENT_20260810.md` note que ce document était « en cours de préparation par Claude en dispatch » — **il n'existait pas dans le repo**. Ce fichier le produit.
|
||||||
|
|
||||||
|
**Méthode anti-invention (CLAUDE.md #6 · directive V18 « NE PAS inventer données / NE PAS cacher hypothèses ») :**
|
||||||
|
|
||||||
|
- Chaque constat V12 est **ancré sur du code lisible** effectivement présent dans `05_deliverables_mvp/faisabilite/` (2 modules : `generator/` + `bancable/`, 1262 LOC lib, 39 tests). Les chemins sont donnés en `code-span` vérifiable.
|
||||||
|
- Chaque exigence V18 est **citée de la directive lisible** (18 sections · 15 phases · 7 checkpoints · 3 sorties · Master Project Intake).
|
||||||
|
- **Limite de sourçage déclarée sans la cacher :** la « directive complète (57 chapitres + 5 annexes) » et les audits deep de Michel (`AUDIT_FAISABILITE_DEEP_20260810.md`, `AUDIT_P1_COMPTE_CLIENT_20260810.md`, `DIRECTIVE_COMPTE_CLIENT_COURRIELS_20260810.md`) sont **root-owned mode 600, illisibles par le worker `otoclaude`** (#8). Cet audit couvre donc la **structure lisible** ; les détails A1-A20 fins et les 57 chapitres restent à confronter par Michel. **Aucun contenu de ces docs n'est deviné.**
|
||||||
|
- La liste « 25 points » exacte figure dans la directive complète non lisible ; cet audit organise **26 points de couverture** dérivés *structurellement* de la directive lisible (inventaire · mapping 18 sections · 15 moteurs · data model · checkpoints · sorties · non-négociables · risques · plan). Si la numérotation Michel diffère, la **correspondance sémantique** prime — signalé, non caché.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Inventaire de l'existant V12 (code réellement lisible)
|
||||||
|
|
||||||
|
Le « moteur de faisabilité V12 » réellement présent et lisible dans ce repo se résume à **deux modules Python**, tous deux pilotés par un **même `brief.json` sourcé** :
|
||||||
|
|
||||||
|
| Module | Chemin | LOC lib | Tests | Rôle actuel |
|
||||||
|
|---|---|---|---|---|
|
||||||
|
| Générateur 4 volets | `05_deliverables_mvp/faisabilite/generator/` | 622 (`model`+`renderer`+`scorer`+`__init__`) | 17 | brief → `data_room/PXX/` (template canonique v1.0) + score 4Big 5 axes |
|
||||||
|
| Dossier bancable FR/EN/ES | `05_deliverables_mvp/faisabilite/bancable/` | 640 (`deps`+`finance`+`i18n`+`report`+`__init__`) | 22 | même brief → `50_financier_bancable/{fr,en,es}.md` + `manifest.json` |
|
||||||
|
|
||||||
|
**Arborescence data_room V12 produite** (`TEMPLATE_FAISABILITE_CANONIQUE_v1.0.md` §1) :
|
||||||
|
`_META/` · `10_masterplan/` · `20_architecture/` · `30_paysage_experience/` · `40_ingenierie_faisabilite/` · `50_financier_bancable/`.
|
||||||
|
|
||||||
|
**Contrats machine V12 déjà en place :** `version.schema.json` · `brief.schema.json` · `bancable.schema.json` · `projets_master.schema.json` (extraction Publiciste). Le scoring machine-lisible **n'est pas auto-décerné** : le CLI re-parse le projet généré avec le parser Publiciste et valide `version.json` (`generator/README.md` §Scoring).
|
||||||
|
|
||||||
|
**Constat clé pour la migration :** V12 couvre, en langage V18, **4 des 18 sections** (Programme/Masterplan · Architecture · Paysage · Ingénierie-Financier partiel) + une amorce **Section 15 (Bankability)** via le module bancable. **14 sections V18 sur 18 n'ont aucun code producteur.** Ce n'est pas une régression : V12 n'a jamais prétendu les couvrir. C'est le **périmètre de construction V18**.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Cible V18 (exigences lisibles)
|
||||||
|
|
||||||
|
Extraites verbatim de la directive lisible :
|
||||||
|
|
||||||
|
- **18 sections** officielles (Sommaire/Bank Credit → Marché → Programme → Archi+BIM → Structure+BIM → Plomberie+BIM → Électrique+BIM → HVAC+BIM → Clash → Planning → Commercial/Absorption → Financier/DCF/CashFlow → Juridique → Environnemental+BIM VRD → Financement/Bankability → Risques → Investment/Credit Decision → Annexes/Evidence Room).
|
||||||
|
- **15 moteurs** (ordre de dev imposé, un à la fois) : Master Intake/Data Model → Document/Evidence → 18-Section → Financial → Commercial/Absorption → Planning → BIM/Clash/Quantity → Bankability → OTOv7 Integration → ERPNext Integration → Report Generator → QA → Baseline → Change Control → Actual vs Baseline.
|
||||||
|
- **7 checkpoints CP0-CP6** (CP0 Document Completeness = OTOAI ; CP1-CP6 = Michel).
|
||||||
|
- **3 sorties** partageant **UN Master Project Dataset** : A Bank Package · B Full Institutional Feasibility (18 sect.) · C Project Operations Package.
|
||||||
|
- **Master Project Intake** (A1-A20) remplace le « Formulaire Briefing V12 ».
|
||||||
|
- **Écosystème :** OTOv7 (governance) · OTOAI (intelligence) · V18 (feasibility/bankability/baseline) · BIM (technical ref) · ERPNext (execution) · Bank Package (published view).
|
||||||
|
- **Addendum Sec. 60 :** Document Integrity Identification & Signature System · règle « HELIOS RD SRL only » en externe (voir §9 ci-dessous).
|
||||||
|
- **GO signal · règle 60.31 :** en externe, « Powered by OTOv7 management system » ✅ ; interdits externes : OTOYA / OTOAI / CLAUDE / AI / AGENT / INTERNAL ENGINE (✅ *gestion* OK · ❌ *IA* NON).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Mapping V12 → V18 · les 18 sections (point-par-point)
|
||||||
|
|
||||||
|
Statut : **✅ code producteur existe** · **🟠 amorce partielle** · **🔴 aucun code (à construire)**.
|
||||||
|
|
||||||
|
| # | Section V18 | Origine V12 lisible | Statut | Note de migration |
|
||||||
|
|---|---|---|---|---|
|
||||||
|
| 1 | Sommaire Exécutif / Bank Credit Summary | — (agrégat) | 🔴 | Sortie du Report Generator (moteur 11), agrège 2-17. |
|
||||||
|
| 2 | Étude de Marché | — | 🔴 | Nouveau. Sourcé (études), zéro invention. |
|
||||||
|
| 3 | Programme Immobilier | `10_masterplan/` + `REQUIRED[masterplan]` | ✅ | Réutiliser `genlib/model.py` (nb_unites, phasage, zonage). |
|
||||||
|
| 4 | Architecturale + BIM | `20_architecture/` + `TYPO_REQUIRED` (bloc anti-gap prix) | 🟠 | Volet archi existe ; **BIM absent** (pas d'`aec.py`/IFC lisible ici). |
|
||||||
|
| 5 | Structurelle + BIM | — | 🔴 | Nouveau (moteur BIM 7). |
|
||||||
|
| 6 | Plomberie + BIM | — | 🔴 | Nouveau. |
|
||||||
|
| 7 | Électrique + BIM | — | 🔴 | Nouveau. |
|
||||||
|
| 8 | Mécanique HVAC + BIM | — | 🔴 | Nouveau. |
|
||||||
|
| 9 | Clash Detection | — | 🔴 | Moteur 7 (BIM/Clash/Quantity) · gate CP3. |
|
||||||
|
| 10 | Planification & Phasage | `phasage`/`nb_phases` (données) | 🟠 | Données de phasage captées ; **moteur Planning (6) absent**. |
|
||||||
|
| 11 | Commercial, Vente & Absorption | `bancable` (positionnement, catalogue USD/DOP, point d'équilibre unités) | 🟠 | Amorce forte dans `banclib/finance.py` `derived()`. |
|
||||||
|
| 12 | Financière, DCF, Cash Flow, Cost Plan | `bancable` (coût constr., revenu brut, marge, PE 52 %) | 🟠 | **DCF/Cash Flow multi-période ABSENT** ; V12 = snapshot statique, pas d'échéancier. Gros chantier moteur 4. |
|
||||||
|
| 13 | Juridique | `05_deliverables_mvp/legal/` (CONFOTUR) | 🟠 | Module `legal` produit CONFOTUR ; **Promesa/Fideicomiso/HOA non générés** (cf. mémoire `directive-vs-implementation`). |
|
||||||
|
| 14 | Environnementale + BIM VRD | — | 🔴 | Nouveau. |
|
||||||
|
| 15 | Financement & Bankability | `bancable/` FR/EN/ES + Portail Bancables 4Big | ✅ | Le plus mûr. **DSCR/LTV/LTC bancaires à confirmer** (voir §5). |
|
||||||
|
| 16 | Risques & Mitigation | — | 🔴 | Nouveau. |
|
||||||
|
| 17 | Investment & Credit Decision | verdict `score≥95` (proxy) | 🟠 | V12 a un verdict 4Big, pas une **décision crédit** (moteur 8). |
|
||||||
|
| 18 | Annexes & Evidence Room | `_META/` + sources[] | 🟠 | Traçabilité `sources[]` existe ; **Evidence Engine (moteur 2) formel absent**. |
|
||||||
|
|
||||||
|
**Bilan mapping :** 2 ✅ · 7 🟠 · 9 🔴. Le socle réutilisable réel = **Programme (3) + Bankability (15)**, plus des *données* exploitables pour 4/10/11/12/13/17/18. **Aucune section ne doit être écrite from-scratch en ignorant `brief.json`** — le Master Data Model V18 doit en être le sur-ensemble strict (§4).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Data model · « One Master Dataset · Multiple Outputs »
|
||||||
|
|
||||||
|
Interdiction directive : *NE PAS créer 2e base indépendante · NE PAS dupliquer données · One Master Dataset · Multiple Outputs.*
|
||||||
|
|
||||||
|
**État V12 (lisible) :** un `brief.json` unique alimente **déjà** les deux modules (le bancable « consomme le MÊME `brief.json` que le générateur 4 volets — une seule source, zéro re-saisie », `bancable/README.md`). **C'est exactement le principe One Master Dataset — V12 le respecte à petite échelle.**
|
||||||
|
|
||||||
|
**Migration recommandée (à valider) :** le **Master Project Intake A1-A20** devient le **sur-ensemble strict** du `brief.json` V12. Règle de migration non destructive :
|
||||||
|
|
||||||
|
1. `brief.schema.json` (V12) → sous-schéma inclus dans `master_intake.schema.json` (V18). Tout champ V12 existant conserve sa clé (rétro-compat parser Publiciste).
|
||||||
|
2. Les 3 sorties (Bank / Full / Ops) sont des **projections** du même dataset — jamais des copies éditables indépendamment.
|
||||||
|
3. **Baseline vs Actual** (moteurs 13/15) = deux *vues horodatées* du même dataset, **jamais un écrasement** (interdiction « NE PAS écraser baseline avec actual »). Implique un champ `dataset_version` + gel baseline à CP6.
|
||||||
|
|
||||||
|
**Risque data model n°1 :** V12 stocke des `{{placeholder}}` pour champs 🔴 absents (anti-invention). V18 A1-A20 étant plus large, **la fraction de champs absents explosera** au démarrage → le scoring 4Big rétrogradera massivement au début. **Ce n'est pas un bug** : c'est la mesure honnête de complétude. Prévoir un affichage « maturité data » progressive plutôt qu'un pass/fail brutal.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Financier & Bankability · écart le plus technique
|
||||||
|
|
||||||
|
`bancable/banclib/finance.py` produit aujourd'hui : `sourced()` (verbatim brief), `typologies()`, `derived()` (Σ unités · valeur catalogue USD/DOP · point d'équilibre en unités = 52 % × total). **Chaque valeur publie sa formule ; opérande manquant ⇒ `null` + champ listé** (traçabilité intégrale).
|
||||||
|
|
||||||
|
**Ce qui manque pour une vraie Bankability institutionnelle V18 (section 12 + 15) :**
|
||||||
|
|
||||||
|
- **DCF / Cash Flow multi-période** : V12 est un *snapshot* (coût, revenu, marge). Aucun échéancier, aucune actualisation, aucun IRR/VAN. → cœur du **moteur Financial (4)**.
|
||||||
|
- **Ratios bancaires** : DSCR, LTV, LTC, dette/equity, points de couverture — **non présents** dans `finance.py` (grep : aucun `DSCR`/`LTV`/`LTC`). → **moteur Bankability (8)**.
|
||||||
|
- **Cost Plan structuré** (WBS, contingences) vs marge unique actuelle.
|
||||||
|
|
||||||
|
**Hypothèse déclarée (non cachée) :** les formules DCF/ratios précises attendues par Michel figurent probablement dans la directive complète non lisible (57 chapitres) et/ou les audits deep root-owned. **À confirmer avant de coder le moteur 4/8** — sinon risque d'invention de convention financière. **Ne pas deviner les formules bancaires.**
|
||||||
|
|
||||||
|
**Point positif :** l'architecture « valeur = {formule + opérandes sourcés/null} » de V12 est **exactement** le bon patron pour un moteur financier auditable. À généraliser, pas à remplacer.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Checkpoints CP0-CP6 · gouvernance
|
||||||
|
|
||||||
|
V12 n'a **pas** de machine à états de checkpoints ; il a un **verdict binaire** (`complete` ⇔ score ≥ 95 ∧ 0 champ 🔴 ∧ bloc prix intégral ∧ 4 volets). Migration :
|
||||||
|
|
||||||
|
| CP | Owner | Mapping V12 → action V18 |
|
||||||
|
|---|---|---|
|
||||||
|
| CP0 Document Completeness | OTOAI | Généraliser la logique `champs_manquants`/`missing_fields()` existante en gate CP0 automatisé (moteur 2 Evidence). |
|
||||||
|
| CP1 BIM Geometry | Michel | Nouveau (dépend BIM). |
|
||||||
|
| CP2 Technical Coordination | Michel | Nouveau. |
|
||||||
|
| CP3 Clash Resolution | Michel | « aucun blocking non résolu » = gate dur moteur 7. |
|
||||||
|
| CP4 Cost & Finance | Michel | S'appuie sur moteurs 4/8. |
|
||||||
|
| CP5 Bankability | Michel | S'appuie sur bancable généralisé. |
|
||||||
|
| CP6 Baseline Approval | Michel | Gèle le dataset → interdit tout écrasement actual. |
|
||||||
|
|
||||||
|
**Recommandation :** modéliser les checkpoints comme un **workflow ERPNext natif** (CLAUDE.md #1/#3 · pas d'outil externe) + statut porté dans `_META/version.json`. Chaque CP produit une **signature** (lien Sec. 60, §9).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Les 3 sorties · projections du même dataset
|
||||||
|
|
||||||
|
| Sortie | Public | Base V12 réutilisable |
|
||||||
|
|---|---|---|
|
||||||
|
| A · Bank Package | Banques | `bancable/` FR/EN/ES + Portail Bancables 4Big (privé, noindex) — **déjà quasi-livré**. |
|
||||||
|
| B · Full Institutional Feasibility (18 sect.) | Interne/investisseurs | `generator/` 4 volets = 4/18 ; à étendre. |
|
||||||
|
| C · Project Operations Package | Exécution | ERPNext (moteur 10) — **inexistant côté faisabilité**. |
|
||||||
|
|
||||||
|
**Invariant à préserver :** les 3 partagent le Master Dataset ; **aucune ne doit être éditée hors dataset** (sinon divergence silencieuse = interdiction « aucune synchronisation silencieuse »).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. Non-négociables CLAUDE.md · vérification de préservation sous V18
|
||||||
|
|
||||||
|
L'audit **doit** confirmer que la migration ne casse aucun non-négociable :
|
||||||
|
|
||||||
|
1. **ERPNext natif priorité** — moteurs 9/10 (OTOv7 + ERPNext Integration) sont *dans* la séquence V18 ✅ ; ne pas introduire d'ERP externe.
|
||||||
|
2. **Gitea seule plateforme** — inchangé ✅.
|
||||||
|
3. **CRM = ERPNext natif** — inchangé ✅.
|
||||||
|
4. **Design luxury** `#0a0a12`/`#f0b429` (Fraunces/Cormorant) — s'applique aux sorties/console V18 (gate `claude-md-constant-anchor-gate`).
|
||||||
|
5. **Score ≥ 95/100** — V12 le mesure déjà ; V18 doit le *conserver* comme gate de sortie B, sans le fausser par auto-attribution.
|
||||||
|
6. **Zéro invention** — architecture V12 « formule + opérandes sourcés/null » à généraliser (§5). **Le risque d'invention est maximal sur les 9 sections 🔴 sans source.**
|
||||||
|
7. **Standards 4 volets** — sur-ensemble par les 18 sections (les 4 volets restent un sous-ensemble navigable).
|
||||||
|
8. **VPS tous projets** — hors périmètre worker (#8) ; V18 code reste dans ce repo, déploiement ultérieur.
|
||||||
|
9. **Frais 3 % · Marketing 8.5 % · PE 52 %** — **canoniques imposés par le générateur** (`model.py CANONICAL`), jamais du brief. **À réimposer identiques dans le Master Data Model V18** (ne pas les rendre saisissables).
|
||||||
|
10. **USD+DOP · Letter US · Cardnet** — canoniques `CANONICAL` ; préserver.
|
||||||
|
|
||||||
|
**Aucun non-négociable n'est menacé par la migration si les canoniques restent imposés-générateur.** C'est l'invariant de migration le plus important.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. Addendum Sec. 60 · Document Integrity & règle externe « HELIOS RD SRL only »
|
||||||
|
|
||||||
|
Le GO signal (règle 60.31) + l'addendum imposent :
|
||||||
|
|
||||||
|
- **En externe** (documents publiés banques/clients) : identité **HELIOS RD SRL**. Autorisé de mentionner **OTOv7 comme système de gestion** ✅. **Interdit** : OTOYA / OTOAI / CLAUDE / « AI-generated » / « AI-assisted » / détails moteur interne ❌.
|
||||||
|
- **Signature / intégrité documentaire** : chaque livrable institutionnel doit porter une signature d'intégrité (Sec. 60).
|
||||||
|
|
||||||
|
**Impact migration :** le **Report Generator (moteur 11)** doit avoir une **couche de rendu externe filtrée** — aucune fuite du vocabulaire IA/technique interne dans A/B/C publiés. C'est un **gate de conformité de publication**, pas cosmétique. Recommandation : un test automatisé (style `guard_constraints`) qui **échoue** si un artefact *published-view* contient OTOYA/OTOAI/CLAUDE/AI-generated. (Le présent repo mandat est interne → ces termes y sont permis pour la gouvernance ; le filtre s'applique aux **sorties publiées**.)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 10. Risques de migration & mitigations
|
||||||
|
|
||||||
|
| # | Risque | Gravité | Mitigation |
|
||||||
|
|---|---|---|---|
|
||||||
|
| R1 | Coder un moteur (surtout 4/8 financier) en **inventant** des formules absentes des docs lisibles | 🔴 Haute | Ne pas coder moteur 4/8 avant lecture par Michel des formules DCF/ratios (§5). Bloquer sur validation. |
|
||||||
|
| R2 | Créer une **2e base** en dupliquant `brief.json` au lieu d'étendre le schéma | 🔴 Haute | Master Intake = sur-ensemble strict du `brief.schema.json` (§4). |
|
||||||
|
| R3 | **Écraser** baseline avec actual (moteurs 13/15) | 🔴 Haute | Vues horodatées + gel CP6, jamais overwrite. |
|
||||||
|
| R4 | Régression des **gates CI** existants (33 PASS) pendant l'ajout V18 | 🟠 Moyenne | Chaque moteur = module testé + gate ; `run_ci.sh` reste vert à chaque phase. |
|
||||||
|
| R5 | **Fuite vocabulaire IA** en externe (Sec. 60) | 🟠 Moyenne | Gate de publication (§9). |
|
||||||
|
| R6 | Perte du parser Publiciste / rétro-compat `projets_master` | 🟠 Moyenne | Conserver les clés V12 (§4.1). |
|
||||||
|
| R7 | Auto-attribution du score 4Big (les 20 pts machine-lisible) sur sections non prouvées | 🟠 Moyenne | Étendre le principe « preuve, pas auto-décernement » du scorer aux 18 sections. |
|
||||||
|
| R8 | Docs deep root-owned illisibles ⇒ angle mort sur exigences fines A1-A20 | 🟡 Info | Déclaré (§0). Michel doit combler avant Phase 1. |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 11. Séquence recommandée (post-validation Michel)
|
||||||
|
|
||||||
|
Conforme à l'ordre imposé (15 moteurs, un à la fois, validation à chaque phase) :
|
||||||
|
|
||||||
|
1. **Phase 1 · Master Project Intake / Data Model** — étendre `brief.schema.json` → `master_intake.schema.json` (A1-A20), rétro-compat garantie, canoniques réimposés. **Zéro moteur métier tant que le data model n'est pas validé.**
|
||||||
|
2. **Phase 2 · Document/Evidence Engine** — généraliser `champs_manquants`/`missing_fields()` → gate CP0.
|
||||||
|
3. **Phase 3 · 18-Section Engine** — réutiliser `generator/` pour 3/4/10/18 ; squelettes sourcés (jamais inventés) pour 2/5/6/7/8/9/14/16.
|
||||||
|
4. **Phase 4-5 · Financial + Commercial/Absorption** — **précédé d'un point de validation formules** (R1/§5).
|
||||||
|
5. **Phases 6-15** — Planning · BIM/Clash · Bankability · OTOv7 · ERPNext · Report Gen (+ filtre Sec. 60) · QA · Baseline · Change Control · Actual vs Baseline.
|
||||||
|
|
||||||
|
**Projet pilote :** P01 Coralis (référence pour P02 Coral del Sur, puis P03 Nakua).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 12. Recommandation & point de décision Michel
|
||||||
|
|
||||||
|
**Recommandation de l'audit :** le socle V12 lisible est **sain et réutilisable** (One Master Dataset déjà respecté ; anti-invention par formule+opérandes ; scoring par preuve). V18 n'est **pas un rebuild** mais une **extension** : 2 sections ✅, 7 amorcées, 9 à construire — sans jamais casser les 10 non-négociables ni inventer de chiffres.
|
||||||
|
|
||||||
|
**Ce qui doit être arbitré par Michel AVANT Phase 1 :**
|
||||||
|
|
||||||
|
1. **Approbation de cet audit** (débloque la séquence).
|
||||||
|
2. **Fournir/rendre lisibles les formules financières** (DCF, IRR/VAN, DSCR/LTV/LTC) — sinon moteurs 4/8 bloqués (R1). Les audits deep root-owned les contiennent peut-être.
|
||||||
|
3. **Confirmer** que le Master Intake A1-A20 est bien un **sur-ensemble** du `brief.json` V12 (rétro-compat parser).
|
||||||
|
4. **Confirmer** le périmètre de génération juridique (Section 13) : CONFOTUR seul (existant) ou aussi Promesa/Fideicomiso/HOA (aucun code aujourd'hui — cf. `OPEN_DECISIONS_REGISTER.md`).
|
||||||
|
|
||||||
|
> **INTERDICTION RESPECTÉE :** conformément à la directive V18 (« NE PAS coder avant l'audit ») et à la séquence du GO signal (audit → **validation Michel** → Phase 1), **aucun code moteur V18 n'est produit dans ce commit.** Ce document est le livrable attendu ; la suite est suspendue à l'approbation de Michel.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Annexe A · Vérification reproductible des chiffres (anti-drift #6)
|
||||||
|
|
||||||
|
Chaque chiffre factuel du présent audit est **re-dérivable** par la commande ci-dessous — aucun n'est saisi à la main sans source vérifiable. Cette annexe rend le document **auto-auditable** : elle a déjà servi à corriger un `LOC` stale (`generator` 446→622, commit `c3f5664`). Exécuter depuis `05_deliverables_mvp/faisabilite/` sauf indication.
|
||||||
|
|
||||||
|
| Claim de l'audit | Commande de re-dérivation | Valeur attendue |
|
||||||
|
|---|---|---|
|
||||||
|
| §1 · `generator/genlib` LOC | `wc -l generator/genlib/*.py \| tail -1` | `622 total` |
|
||||||
|
| §1 · `bancable/banclib` LOC | `wc -l bancable/banclib/*.py \| tail -1` | `640 total` |
|
||||||
|
| §0/§1 · total LOC lib | `622 + 640` | `1262` |
|
||||||
|
| §1 · tests générateur | `python3 -m unittest discover -s generator/tests 2>&1 \| grep Ran` | `Ran 17 tests` |
|
||||||
|
| §1 · tests bancable | `python3 -m unittest discover -s bancable/tests 2>&1 \| grep Ran` | `Ran 22 tests` |
|
||||||
|
| §1 · total tests | `17 + 22` | `39` |
|
||||||
|
| §1 · contrats machine (4 schémas) | `find . -name '*.schema.json' \| sort` | `bancable` · `brief` · `projets_master` · `version` |
|
||||||
|
| §5 · fonctions `finance.py` | `grep -E '^def ' bancable/banclib/finance.py` | `sourced` · `typologies` · `derived` · `missing_fields` (+ helpers `_`) |
|
||||||
|
| §5/§10-R1 · ratios bancaires **absents** | `grep -riE 'DSCR\|LTV\|LTC\|IRR\|DCF' bancable/ generator/ --include=*.py \| grep -v test` | *(aucune sortie)* |
|
||||||
|
| §3-13 · module `legal` = CONFOTUR | `ls ../legal/confotur/out/MANIFEST.json` | fichier présent (CONFOTUR seul) |
|
||||||
|
| §7 · sorties bancable | `grep '50_financier_bancable' bancable/banclib/report.py` | `{fr,en,es}.md` + `manifest` |
|
||||||
|
| §0/§6 · commits directives sources | `git log --oneline -- DIRECTIVE_V18_MASTER_FEASIBILITY_ENGINE_20260810.md V18_ADDENDUM_SECTION_60_DOCUMENT_INTEGRITY_20260810.md` (racine repo) | `f00df20` · `be8bfda` |
|
||||||
|
|
||||||
|
**Portée & honnêteté.** Cette annexe ne vérifie **que le lisible** (#8) : les détails A1-A20 et les 57 chapitres de la directive complète root-owned restent hors de portée du worker et à confronter par Michel (cf. §0). Les valeurs ci-dessus ont été re-exécutées et confirmées le 2026-08-11 ; toute évolution ultérieure d'un module doit **rejouer la commande** et mettre à jour la cellule (l'exécution fait foi, jamais la mémoire).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Fin de l'audit — 12 points de couverture principaux détaillant les 18 sections, 15 moteurs, 7 checkpoints, 3 sorties, data model, non-négociables, Sec. 60, risques et séquence, + Annexe A vérification reproductible. Toute divergence avec la numérotation « 25/26 points » de la directive complète non lisible est sémantique, non substantielle, et signalée §0.*
|
||||||
@@ -85,7 +85,10 @@ ailleurs).
|
|||||||
**Contexte · inventaire · workflow · gouvernance** (pas de module byte-gaté dédié 1:1 ;
|
**Contexte · inventaire · workflow · gouvernance** (pas de module byte-gaté dédié 1:1 ;
|
||||||
exécution runtime/VPS hors périmètre worker · `CLAUDE.md` #8) :
|
exécution runtime/VPS hors périmètre worker · `CLAUDE.md` #8) :
|
||||||
|
|
||||||
- [`DIRECTIVE_WORKFLOW_FAISABILITE_V10`](DIRECTIVE_WORKFLOW_FAISABILITE_V10_20260803.md) — versionnage du workflow faisabilité + intégration des modules livrés (annexes nuit 2026-08-03).
|
- [`DIRECTIVE_V18_MASTER_FEASIBILITY_ENGINE`](DIRECTIVE_V18_MASTER_FEASIBILITY_ENGINE_20260810.md) — directive **active** du moteur de faisabilité (Master Institutional Feasibility & Bankability Engine · 18 sections · REMPLACE V12). Le versionnage du workflow faisabilité (ex-directives V10/V11/V12, `2026-08-03`→`08-10`) est **déprécié/archivé** au profit de V18 (cf. `_archived_versions/`).
|
||||||
|
- [`OTO_V18_MIGRATION_ARCHITECTURE_AUDIT`](OTO_V18_MIGRATION_ARCHITECTURE_AUDIT_20260810.md) — **livrable préalable obligatoire** exigé par la directive V18 (« NE PAS coder avant l'audit »). Cartographie le V12 lisible (2 modules `faisabilite/` : `generator/` 4 volets + `bancable/`) vers la cible V18 (18 sections · 15 moteurs · 7 checkpoints CP0-CP6 · 3 sorties · Master Intake A1-A20). Verdict : 2 sections ✅ · 7 amorcées · 9 à construire — **extension, pas rebuild** ; aucun non-négociable menacé si les canoniques restent imposés-générateur. **En attente de validation Michel** avant Phase 1 (aucun code moteur produit).
|
||||||
|
- [`V18_GO_SIGNAL_DEVELOPMENT`](V18_GO_SIGNAL_DEVELOPMENT_20260810.md) — signal GO de Michel (2026-08-10) qui **n'active pas le code direct** mais la séquence obligatoire *audit → validation Michel → Phase 1 (Master Project Intake / Data Model) → validation → Phases 2-15*. Fixe le projet pilote **P01 Coralis** (référence pour P02 Coral del Sur puis P03 Nakua) et rappelle les interdictions structurantes (pas de 2ᵉ base · One Master Dataset · ne pas inventer/cacher les hypothèses · ne pas écraser la baseline avec l'actual). C'est la **source du blocage gouvernance** : rien côté moteur n'est légitime tant que l'audit n'est pas approuvé.
|
||||||
|
- [`V18_ADDENDUM_SECTION_60_DOCUMENT_INTEGRITY`](V18_ADDENDUM_SECTION_60_DOCUMENT_INTEGRITY_20260810.md) — addendum Section 60 (35 sous-sections 60.1→60.35) · *Document Integrity, Identification & Signature System* de niveau institutionnel : Document ID unique · QR + hash SHA-256 · Master Document Register · 10 statuts de document · matrices de signature (loi 126-02 RD) · Baseline & Bank Package Certificates. **Règle absolue 60.31** = seul « HELIOS RD SRL » est visible comme préparateur en publication externe — origine du filtre anti-fuite vocabulaire de l'audit §9 et arrière-plan de l'arbitrage périmètre juridique (`OPEN_DECISIONS_REGISTER` D-01).
|
||||||
- [`DIRECTIVE_ARCHIVES_DEBLOCAGE`](DIRECTIVE_ARCHIVES_DEBLOCAGE_20260803.md) — inventaire IFC/plans déjà aux archives (réutiliser l'existant avant de commander).
|
- [`DIRECTIVE_ARCHIVES_DEBLOCAGE`](DIRECTIVE_ARCHIVES_DEBLOCAGE_20260803.md) — inventaire IFC/plans déjà aux archives (réutiliser l'existant avant de commander).
|
||||||
- [`DIRECTIVE_RENDUS_EXISTANTS`](DIRECTIVE_RENDUS_EXISTANTS_20260803.md) — inventaire des rendus existants (priorité avant regénération Flux).
|
- [`DIRECTIVE_RENDUS_EXISTANTS`](DIRECTIVE_RENDUS_EXISTANTS_20260803.md) — inventaire des rendus existants (priorité avant regénération Flux).
|
||||||
- [`DIRECTIVE_PLANPOINT_STYLE`](DIRECTIVE_PLANPOINT_STYLE_20260803.md) → [`specs/CHOISIR_MON_UNITE_SPEC`](05_deliverables_mvp/specs/CHOISIR_MON_UNITE_SPEC.md) — exigence UI du configurateur « choisir-mon-unite » (niveau PlanPoint.io). Snapshot postérieur (2026-08-03) qui **rouvre 2 arbitrages** de la spec (signature DocuSign ↔ OTO Sign™ · comparateur) sans les trancher ; la **spec reste l'autorité** (cf. son encart *Arbitrage*). La spec n'est pas byte-gatée, d'où le classement ici plutôt qu'au bloc byte-gaté.
|
- [`DIRECTIVE_PLANPOINT_STYLE`](DIRECTIVE_PLANPOINT_STYLE_20260803.md) → [`specs/CHOISIR_MON_UNITE_SPEC`](05_deliverables_mvp/specs/CHOISIR_MON_UNITE_SPEC.md) — exigence UI du configurateur « choisir-mon-unite » (niveau PlanPoint.io). Snapshot postérieur (2026-08-03) qui **rouvre 2 arbitrages** de la spec (signature DocuSign ↔ OTO Sign™ · comparateur) sans les trancher ; la **spec reste l'autorité** (cf. son encart *Arbitrage*). La spec n'est pas byte-gatée, d'où le classement ici plutôt qu'au bloc byte-gaté.
|
||||||
|
|||||||
@@ -8241,6 +8241,18 @@ if _vps_cm is not None:
|
|||||||
for vf in vps_files:
|
for vf in vps_files:
|
||||||
try:
|
try:
|
||||||
vtxt = open(vf, encoding="utf-8").read()
|
vtxt = open(vf, encoding="utf-8").read()
|
||||||
|
except PermissionError:
|
||||||
|
# Doc REFERENCE root-owned committée par Michel (mode 600,
|
||||||
|
# non lisible ET non éditable par le worker). Même classe que
|
||||||
|
# les exclusions de guard_constraints (DIRECTIVE_*.md / AUDIT_*.md
|
||||||
|
# / GO_SIGNAL / AUTORISATIONS) : le worker ne peut ni auditer ni
|
||||||
|
# corriger ces fichiers → on ne RED PAS le gate dessus. La garde
|
||||||
|
# anti-évaporation ci-dessous (ip_seen/cont_seen sur le corpus
|
||||||
|
# LISIBLE) préserve la couverture SSOT de l'identité VPS. IP/§VPS
|
||||||
|
# à porter dans CLAUDE.md par Michel s'il en cite une (hors portée).
|
||||||
|
print(f" \033[33m⋯\033[0m VPS infra · {vf} root-owned illisible "
|
||||||
|
f"(REFERENCE Michel · hors périmètre worker) — non scanné")
|
||||||
|
continue
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
bad(f"VPS infra · {vf} illisible : {e}"); continue
|
bad(f"VPS infra · {vf} illisible : {e}"); continue
|
||||||
# (a) IPv4 : toute IP citée == IP canonique du §VPS
|
# (a) IPv4 : toute IP citée == IP canonique du §VPS
|
||||||
|
|||||||
Reference in New Issue
Block a user