e15129bc6a
chasse au défaut d'abord sur 2 axes FRAIS (hors mémoire) → DRY : docstring-vs-code sous-axe COMPORTEMENTAL (fallback/param/formule/branche non implémentés) CLEAN sur tous *_gen.py + *lib/ ; test-name ⟺ assertion (fake-coverage sémantique) CLEAN sur 24 suites / ~6364 lignes. Vrai locus = currency stakeholder (classe4eb615b). 3 blocs cohérents dans daily_reports/2026-08-12.md : nouvelle §« Jalons de vérification depuis la 4ᵉ vague (1992ee6→fb2d3e1) » (4 commits non-opposables · byte-identiques) + en-tête HEAD attesté « HEAD courant »→fb2d3e1 (distingue 5ᵉ fix 634→635 des 4 vérifs matrice-stable) + §État courant : 4ᵉ vague nommée1992ee6(au lieu de « HEAD courant » devenu faux). zéro invention #6 : matrice 635/618/17 · PASS re-dérivée de regression_run.json.totals ; D-01→D-08 inchangés. document éditorial → pas de gate #5. CI 33 PASS · 0 FAIL · 0 SKIP · NFC-clean · 0 code moteur V18 (bloqué #6) · 0 artefact reconstruit · 0 commande VPS #8. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
158 lines
18 KiB
Markdown
158 lines
18 KiB
Markdown
# Daily Report · 2026-08-12 · Claude Code DTP Worker
|
||
|
||
**Session** : `20260812_110124` (rapport initialement émis en `20260812_043034` à
|
||
`ee88d36` · complété en `20260812_063050` à `37c68ac` · réconcilié en `083114` à `e7cc3c4`
|
||
· re-réconcilié en `100114` à `85cd625` · **prolongé au 5ᵉ fix `1992ee6`** · **currency
|
||
étendue au HEAD courant `fb2d3e1`** en `20260812_133154` — 4 vérifs zéro-impact remontées,
|
||
voir §« Jalons de vérification depuis la 4ᵉ vague »)
|
||
**HEAD attesté** : `fb2d3e1` (le rapport précédent était épinglé à `35de616` · puis ce
|
||
rapport à `ee88d36`, `37c68ac`, `e7cc3c4`, `85cd625`, `1992ee6` · **un 5ᵉ fix worker de
|
||
correctness** a porté la matrice `634→635` — voir §« Jalon du jour · 4ᵉ vague » — **puis 4
|
||
commits de vérification byte-identiques** ont porté l'arbre à `fb2d3e1`, matrice stable)
|
||
**Phase roadmap** : transition **V12 → V18** (Master Institutional Feasibility &
|
||
Bankability Engine). La roadmap 8-semaines classique (Sprints 1→8) reste **livrée +
|
||
gatée + verte** au dépôt ; le **moteur de faisabilité** V18 est rouvert par directive
|
||
mais sa séquence reste **intégralement suspendue à des arbitrages Michel** (voir
|
||
§« Chemin critique bloqué »). Aucun code moteur V18 n'est légitime tant que l'audit
|
||
préalable n'est pas approuvé (D-06 · #6).
|
||
|
||
## Contexte — le canal stakeholder s'arrêtait au `2026-08-11` (HEAD `35de616`)
|
||
|
||
Le dernier rapport roadmap (`2026-08-11`, currency `20260811_092842`) était épinglé à
|
||
`35de616`. Depuis, **trois commits** ont porté l'arbre au HEAD courant `ee88d36`, dont
|
||
**deux 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).
|
||
|
||
## Jalons depuis le dernier rapport (`35de616` → `ee88d36`)
|
||
|
||
| Jalon | Commit (session) | Nature | Opposabilité au merge |
|
||
|---|---|---|---|
|
||
| **TEETH publiciste NBSP** | `39def91` (`20260811_095844`) | Ajout d'un test de parsing prix : l'**espace insécable** U+00A0 (inséré par Word/InDesign FR/ES comme séparateur de milliers dans les prix réels des `data_room`) doit être capté par la char-class Unicode-whitespace de `lib/parser.py`. Le test **mord** si la capture est réduite à de l'ASCII pur (seul le 1er chiffre survivrait : `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 ` ` (0 octet invisible). | **Opposable** : +1 test verrou ; régression **628/611 → 629/612** (voir §État courant). 0 artefact reconstruit hors les artefacts régression/audit re-générés du même coup. |
|
||
| **RÉFÉRENCE design (Michel)** | `031b5e7` | Ajout par Michel du PNG `DASHBOARD_LUXURY_MODELE_REFERENCE_20260811` (design canonique OTO CONTRACTOR, dark+doré · #4). **Hors production repo** (asset de référence root-owned mode 600). | **Non opposable** (asset de référence · 0 code · 0 artefact). |
|
||
| **CLEANUP #5 orphelin `out_fresh/`** | `ee88d36` (`20260812_040034`) | Suppression de `frontend/portails/out_fresh/` (`workspace.json` + `MANIFEST.json`) : scratch-dir **byte-identique** à `out/`, commité une seule fois par accident (`f954cc1`, 2026-08-02), **produit par rien** (le générateur n'écrit que dans `out/`) et **référencé nulle part** (`git grep out_fresh` = 0). Il **échappait à TOUS les gates** (`check_artifacts` découvre par `find -type d -name out` = match exact) → bombe à retardement de staleness. Fix = `git rm -r` (réversible via historique, non créé par le worker, copie autoritaire `out/` intacte + byte-repro vérifié). Occurrence isolée → **pas de nouveau gate** (#5). | **Opposable** : `run_ci` inchangé **33/0/0** ; **0 artefact autoritaire** modifié (seul un doublon orphelin retiré). |
|
||
|
||
## Jalons du jour depuis l'émission initiale (`ee88d36` → `37c68ac`)
|
||
|
||
Trois commits worker **du même jour** ont suivi l'émission initiale de ce rapport. Tous
|
||
sont des travaux de **vérification / durcissement** : **0 code moteur V18** (bloqué D-06),
|
||
**artefacts byte-identiques** (matrice **stable** à `629/612/17` — confirmé par
|
||
`check_artifacts` ∈ `run_ci` vert).
|
||
|
||
| Jalon | Commit (session) | Nature | Opposabilité au merge |
|
||
|---|---|---|---|
|
||
| **Déterminisme · ordre d'exécution des suites** | `a17d86a` (`20260812_050034`) | 4ᵉ axe de déterminisme (frères : hash-seed · locale/TZ · forward-compat) : ré-exécution de la matrice avec l'ordre des 24 suites **inversé** → totaux **byte-identiques**, 24/24 suites identiques. Fermé *by design* (chaque suite tourne dans son propre subprocess `cwd=abs_path`, agrégation somme-indépendante-de-l'ordre). Balayage **replayable**, pas un gate (#5). | **Non opposable** (lecture seule `/tmp`, 0 artefact touché). |
|
||
| **Vérif i18n SEO · asymétrie `fr=87·en=87·es=84`** | `1513e69` (`20260812_053034`) | Angle i18n frais : l'écart per-langue **prouvé NON-DÉFAUT** au byte-level (`country[es]` = « Republica Dominicana » coïncide avec la `localisation` générique de 5 projets → 3 collisions global↔projet dédupliquées en plus qu'en fr/en ; chaque chaîne unique existe exactement une fois). Chiffre déjà gaté par `check_readme_claims`. Livrable = **note explicative** au point de dedup (`keywords.py:106`), anti re-flag ; 0 logique/fixture/artefact touché. | **Opposable** : commentaire pur, `seo/out/*.json` re-build **byte-identique**. |
|
||
| **Hardening correctness · `criteria.py`** | `37c68ac` (`20260812_060044`) | 3ᵉ détecteur regex `_ADD_PARSER_RE` durci `add_parser\(` → `add_parser\s*\(` (tolère l'espace avant `(`, Python valide) — dernier non durci de la famille « détecter la **forme**, pas une **graphie** » (frères `ac595d0`/`fd99362`/`35de616`). Fix **latent** : aucun module n'utilise l'espace aujourd'hui (`grep` = 0) → `quality_report.json` re-build **byte-identique**. Occurrence one-shot → pas de gate (#5). | **Opposable** : `run_ci` inchangé **33/0/0** ; **0 artefact autoritaire** modifié. |
|
||
|
||
## Jalons du jour · 2ᵉ vague (`37c68ac` → `e7cc3c4`) — correctness à impact matrice
|
||
|
||
Contrairement à la 1ʳᵉ vague (vérif/hardening à artefacts byte-identiques), ces trois
|
||
commits corrigent des **bugs latents réels** de correctness de sortie sur des **entrées
|
||
financières / francophones réalistes RD**. Chacun ajoute un **test de régression à dents**
|
||
(prouvé qu'il échoue sans le fix), ce qui fait **croître la matrice** `629 → 633`. Tous :
|
||
**0 code moteur V18** (bloqué D-06), leçon commune « **le contexte de sortie dicte
|
||
l'encodeur, pas la donnée courante** ».
|
||
|
||
| Jalon | Commit (session) | Nature | Opposabilité au merge |
|
||
|---|---|---|---|
|
||
| **Fix · rendu publiciste : URL hero percent-encodée** | `aeb30b8` (`20260812_070054`) | `_hero_media` composait `url('/static/projets/{code}/{fichier}')` en CSS mais échappait le nom de fichier via `html.escape` — **mauvais encodeur pour un contexte CSS** : un rendu réel `Vue d'ensemble.png` (FR) devient `Vue d'ensemble.png`, HTML-décodé par le navigateur en `Vue d'ensemble.png` → l'apostrophe **referme la chaîne `url('…')`** → hero **invisible silencieusement**. Fix = `urllib.parse.quote(fichier)` (`'`→`%27`, espace→`%20`) — valide en URL/HTML/CSS. `_esc` conservé pour l'attribut HTML. Test à dents `test_hero_media_url_percent_encode`. Byte-repro intact (ASCII simple inchangé). | **Opposable** : bug de rendu réel corrigé ; suite publiciste **24→25**, matrice **629/612 → 630/613** ; 4 artefacts régénérés (regression×3 + quality_report) + 3 fiches à compteurs = **pure propagation**. |
|
||
| **Hardening · segment `code` de la même `url('…')`** | `5af86e3` (`20260812_073055`) | Le fix `070054` avait percent-encodé `fichier` mais laissé **le second segment dynamique `code`** brut dans la MÊME `url()` — dernier segment non-encodé (frère exact de `criteria.py` : durcir le SEUL non-durci d'une famille). **Non déclenchable aujourd'hui** (codes `P01..P09`, jamais d'apostrophe → byte-repro inchangé) mais durcissement d'uniformité. Fix = `quote(code)`. Test à dents `test_hero_media_code_segment_percent_encoded`. | **Opposable** : uniformité de construction ; suite publiciste **25→26**, matrice **630/613 → 631/614** ; artefacts = pure propagation de compteur. |
|
||
| **Fix · commissions : formule `base×taux` cassait sur montants réels** | `e7cc3c4` (`20260812_080104`) | `compute_line` composait le libellé de base via `f"{base:g}"` — casse **deux fois** sur des montants immobiliers RD (unité ≈ **18 000 000 DOP**) : (1) **exponentiel dès 1e6** (`18000000`→`1.8e+07`, non-auditable) ; (2) **arrondi silencieux à 6 chiffres sig.** (`123456.78`→`123457`) = **base fabriquée**, l'invention même interdite #6 dans le module dont la docstring proclame l'anti-invention. Fix = helper `_amount_label` (`f"{x:f}"` + strip zéros), fidèle et identique à l'ancien pour tout montant simple. Code **runtime** (jamais appelé par `commissions_gen.py`) → **0 régénération de l'artefact du module**. 2 tests à dents. | **Opposable** : bug de sortie financière corrigé ; suite commissions **25→27**, matrice **631/614 → 633/616** ; artefacts régression/audit régénérés = pure propagation. |
|
||
|
||
## Jalon du jour · 3ᵉ vague (`e7cc3c4` → `85cd625`) — correctness gate financement
|
||
|
||
Un 4ᵉ fix worker de correctness a suivi la 2ᵉ vague, dans la même veine (bug **latent
|
||
réel** sur entrée réaliste, byte-repro-aveugle, test à dents) : **0 code moteur V18**
|
||
(bloqué D-06).
|
||
|
||
| Jalon | Commit (session) | Nature | Opposabilité au merge |
|
||
|---|---|---|---|
|
||
| **Fix · `financement_bancaire` : barre pleine ✓ mais dossier BLOQUÉ** | `85cd625` (`20260812_093114`) | `gate.py:97` `_cond_apport` : `pct = _round1(min(100.0, paid/required*100))` arrondit à 1 décimale, tandis que `ok = paid + 1e-9 >= required` est **exact**. Un versement dans la bande **[99.95 %, 100 %[** (p. ex. **19 999 / 20 000 USD** = 99.995 %) remonte `percent: 100.0` (barre frontend « 100 % ✓ ») **tout en bloquant** la soumission (403 · `remaining: 1.0 USD`) — raison de blocage auto-contradictoire. Seul `_cond_apport` est atteignable (les 2 autres conditions = ratios entiers sur petites listes, `percent==100 ⟺ ok` structurel). Fix = garde `if not ok and pct >= 100.0: pct = 99.9` → invariant d'affichage **`percent == 100.0 ⟺ ok`** rétabli. `dossier_exemple` commité à 67.8 % (hors bande) → `gate_status_example.json` **byte-identique**. Test à dents `test_apport_quasi_complet_ninclut_pas_100pct`. | **Opposable** : bug d'affichage user-facing corrigé ; suite financement **35→36**, matrice **633/616 → 634/617** ; artefacts régression/audit régénérés = pure propagation. |
|
||
|
||
## Jalon du jour · 4ᵉ vague (`85cd625` → HEAD courant) — même bug, un niveau au-dessus
|
||
|
||
Un **5ᵉ fix worker de correctness** prolonge exactement le 4ᵉ : la 3ᵉ vague avait rétabli
|
||
l'invariant **`percent == 100.0 ⟺ ok`** *au niveau de chaque condition* (`_cond_apport`),
|
||
mais l'**agrégat** `overall_percent` (la **barre GLOBALE**) le violait toujours — même
|
||
classe de bug, un cran plus haut, que le fix précédent avait manqué.
|
||
|
||
| Jalon | Commit (session) | Nature | Opposabilité au merge |
|
||
|---|---|---|---|
|
||
| **Fix · `financement_bancaire` : barre GLOBALE 100 % mais dossier BLOQUÉ** | `20260812_110124` | `gate.py` `gate_status` : `overall = _round1(Σ percents / 4)`. Cas limite = apport plafonné à **99.9** (non ok, cf. fix 3ᵉ vague) **+** les 3 autres conditions à **100.0** (ok) → moyenne `(99.9 + 300)/4 = 99.975` → `round1` = **100.0**. La barre **globale** afficherait « 100 % » tout en refusant la soumission (403) — même auto-contradiction que le fix `_cond_apport`, mais à l'agrégat. Fix = garde `if not can_submit and overall >= 100.0: overall = 99.9` → invariant d'affichage **`overall_percent == 100.0 ⟺ can_submit`**. `gate_status_example.json` commité à `overall_percent: 39.1` (hors bande) → **byte-identique**. Test à dents `test_overall_percent_agrege_ninclut_pas_100pct` (mord `100.0 not less than 100.0` sans la garde). | **Opposable** : bug d'affichage user-facing corrigé ; suite financement **36→37**, matrice **634/617 → 635/618** ; artefacts régénérés = pure propagation. |
|
||
|
||
## Jalons de vérification depuis la 4ᵉ vague (`1992ee6` → HEAD courant `fb2d3e1`)
|
||
|
||
Après le 5ᵉ fix (`1992ee6`), **quatre commits worker** ont suivi le même jour. **Aucun**
|
||
n'est un fix de code : ce sont des **vérifications / durcissements anti-récurrence**
|
||
(commentaires purs) + une **currency de registre**. La matrice est donc **stable à
|
||
635/618/17** (`check_artifacts` ∈ `run_ci` vert · rebuild **byte-identique** de tous les
|
||
artefacts) — chiffres re-dérivés de l'artefact commité, jamais figés (#6).
|
||
|
||
| Jalon | Commit (session) | Nature | Opposabilité au merge |
|
||
|---|---|---|---|
|
||
| **Classe « percent==100 ⟺ ok » FERMÉE (4 conditions)** | `3849375` (`20260812_113134`) | Preuve que `financement_bancaire` est le **seul module à champ `percent`** ; les 2 conditions à domaine borné (documents ≤ 13 · autorisations = 4 ≪ seuil 2000) durcies par note anti-récurrence. Commentaires purs. | **Non opposable** (aucun fix · rebuild byte-identique). |
|
||
| **Classe « affichage arrondi ⟺ gate booléen » FERMÉE repo-wide** | `ea8458d` (`20260812_120139`) | Preuve d'**immunité structurelle** de `audit_4big` (score-au-seuil 95 = quantité UNIQUE affichage+verdict, ≠ financement à 2 quantités divergentes) + note in-situ `scoring.py`. Commentaire pur. | **Non opposable** (aucun fix · rebuild byte-identique). |
|
||
| **CURRENCY · réalignement de 2 citations `OPEN_DECISIONS_REGISTER.md`** | `4eb615b` (`20260812_123144`) | D-02 `gate.py:142-145 → :164-167` (les gardes des fixes du jour ont décalé `_cond_validation_wag`) · D-01 confotur `README:8-17 → :32-33` (bannière V18 préfixée) ; sweep complet = autres citations résolvent. Document éditorial. | **Non opposable** (0 code · 0 artefact). |
|
||
| **Chasse au défaut axe FRAIS date/time + parsing money/percent** | `fb2d3e1` (`20260812_130149`) | 3 candidats **RÉFUTÉS** domaine-borné (`signature_date="0"` corrompu · `banclib._pct` constante canonique · `rate()` séparateur-milliers inatteignable, taux borné 0-100) + note anti-récurrence in-situ sur `rate()` (un Explore l'avait mal-classé CONFIRMED). Commentaire pur. | **Non opposable** (aucun fix · rebuild byte-identique). |
|
||
|
||
## Chemin critique bloqué — séquence moteur V18 (inchangé)
|
||
|
||
La directive V18 (`DIRECTIVE_V18_MASTER_FEASIBILITY_ENGINE_20260810.md`) impose une
|
||
séquence *audit → validation Michel → Phase 1 → validation → Phases 2-15*. L'audit
|
||
préalable obligatoire (`OTO_V18_MIGRATION_ARCHITECTURE_AUDIT_20260810.md`) est **produit**
|
||
mais **en attente de validation** ; rien côté moteur n'est légitime avant l'approbation
|
||
D-06 (`OPEN_DECISIONS_REGISTER.md`). Les arbitrages ouverts restent :
|
||
|
||
| Décision | Objet | Statut |
|
||
|---|---|---|
|
||
| **D-06** 🔴 | Approbation de l'audit V18 (gate d'entrée Phase 1) | En attente Michel |
|
||
| **D-07** 🔴 | Formules financières canoniques (Master Data Model) | En attente Michel |
|
||
| **D-01** 🟠 | Périmètre juridique Section 13 (CONFOTUR seul, ou aussi Promesa/Fideicomiso/HOA) | Arbitrage de périmètre (aucun code ne génère ces contrats aujourd'hui) |
|
||
|
||
> **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 courant)
|
||
|
||
| 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** exécutées / **24** gatées régression | jobs `*-tests` de `gate.needs` (`.gitea/workflows/ci.yml`) ; la régression s'auto-exclut de son propre recensement |
|
||
| Matrice de régression | **635 exécutés · 618 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: true`, 0 manquant) | `quality_report.json` (`coverage`) |
|
||
|
||
Les **17 skips** sont l'oracle `jsonschema` OPTIONNEL neutralisé par `python -S` (par
|
||
design ; lecture stakeholder = **618 passés + 17 skippés**, **pas** 635 — voir baseline
|
||
régression). Trajectoire de la matrice depuis le rapport précédent (`628/611` à
|
||
`35de616`) : **+1** au `39def91` (test verrou NBSP publiciste, 628→**629**) ; stable à
|
||
`629/612` sur la 1ʳᵉ vague de vérif/hardening (`a17d86a`/`1513e69`/`37c68ac`, artefacts
|
||
byte-identiques) ; puis **2ᵉ vague de correctness** — **+1** au `aeb30b8` (630/613), **+1**
|
||
au `5af86e3` (631/614), **+2** au `e7cc3c4` (633/616) ; puis **3ᵉ vague** — **+1** au
|
||
`85cd625` (fix gate financement per-condition, **634/617**) ; puis **4ᵉ vague** — **+1**
|
||
au `1992ee6` (fix gate financement **agrégat** `overall_percent`, **635/618**) ; puis **4
|
||
commits de vérification** (`3849375`/`ea8458d`/`4eb615b`/`fb2d3e1`) **sans impact matrice**
|
||
(commentaires purs + currency, rebuild byte-identique) portant l'arbre au HEAD courant
|
||
`fb2d3e1`. Chaque incrément = un **test de
|
||
régression à dents** ajouté par un fix ; **aucun nouveau gate** (une divergence de compte
|
||
serait déjà structurellement rougie par `check_readme_claims`, ∈ `run_ci`). Les commits
|
||
non-test (`031b5e7` PNG · `ee88d36` cleanup orphelin · `cb8069b` notes `:g` pures) **ne
|
||
touchent aucun test**. Matrice courante **635/618/17** au HEAD courant.
|
||
|
||
## Portée / anti-churn (session `20260812_100114` · re-réconcilie `083114` au HEAD `85cd625`)
|
||
|
||
- **0 commande VPS** (#8) · **0 API externe payante** · **0 code moteur V18** (séquence
|
||
suspendue à Michel · #6).
|
||
- **0 fichier de production édité** cette session, **0 artefact reconstruit**, **0 gate
|
||
ajouté** (#5) : le livrable est la **re-réconciliation de ce rapport stakeholder** au
|
||
HEAD courant (`85cd625`) — currency du canal + remontée du **4ᵉ fix de correctness**
|
||
(`633→634`, gate `financement_bancaire`, commité après la réconciliation `083114`) +
|
||
chemin critique bloqué inchangé — + le journal `05_activity_log/`. Le commit intercalaire
|
||
`cb8069b` (notes `:g` pures · session `090114`) est sans impact matrice.
|
||
- Tous les chiffres ci-dessus dérivent d'artefacts **commités**, jamais figés (#6).
|
||
|
||
**Gate au dépôt** : `./run_ci.sh` → **33 PASS · 0 FAIL · 0 SKIP**.
|