Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
20 KiB
Daily Report · 2026-08-12 · Claude Code DTP Worker
Session : 20260812_143156 (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 à fb2d3e1 en 20260812_133154 · portée au HEAD courant 4a13557 cette
session — §« Jalons de vérification » convertie en table roulante pour cesser de re-figer
le HEAD à chaque commit worker)
HEAD attesté : 4a13557 (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
des commits de vérification / currency byte-identiques ont porté l'arbre à 4a13557,
matrice stable 635/618/17 ; voir §« Jalons de vérification depuis la 4ᵉ vague »)
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 4a13557)
Table roulante. Après le 5ᵉ (et dernier) fix à impact matrice (
1992ee6), tout commit worker du jour est non opposable par construction — vérification / durcissement anti-récurrence (commentaire pur), currency de canal, ou sweep en lecture seule. Aucun n'est un fix de code produit. La matrice reste donc stable à 635/618/17 quel que soit le nombre de lignes ci-dessous ; elle ne bougera qu'au prochain fix de correctness. Cette section liste ces jalons au fil de l'eau (six à ce jour) sans re-figer le HEAD ailleurs — chiffres re-dérivés de l'artefact commité, jamais figés (#6) ;check_artifacts∈run_civert · rebuild byte-identique de tous les artefacts.
| 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). |
| CURRENCY · remontée des 4 jalons post-4ᵉ-vague dans ce rapport | e15129b (20260812_133154) |
Le canal s'arrêtait à 1992ee6 tout en s'affirmant « au HEAD courant » (grep-count 0 des 4 hashes) → §« Jalons de vérification » créée + en-tête HEAD attesté réaligné. Document éditorial. |
Non opposable (0 code · 0 artefact). |
| Nouvel axe FRAIS · mode d'arrondi (banquier / round-half-to-even) | 4a13557 (20260812_140156) |
Balayage repo-wide des 8 sites round() de production → CLEAN teeth-prouvé, 0 défaut : scorer.py:57 verdict-immune (complete ⟹ filled==total ⟹ pts==20 exact) · :81 immune par inclusion champs_manquants · gate.py montants au cent + percents déjà gardés (85cd625/1992ee6) · parser.py domaine entier · audit_4big immune (ea8458d). Sweep en lecture seule (journal only, aucun mis-flag → pas de note in-situ). |
Non opposable (aucun fix · aucun artefact touché). |
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 six
commits de vérification / currency (3849375/ea8458d/4eb615b/fb2d3e1/e15129b/4a13557)
sans impact matrice (commentaires purs + currency, rebuild byte-identique) portant l'arbre
au HEAD courant 4a13557. 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, gatefinancement_bancaire, commité après la réconciliation083114) + chemin critique bloqué inchangé — + le journal05_activity_log/. Le commit intercalairecb8069b(notes:gpures · session090114) 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.