From fb2d3e16bf2f787a8875aa1a68ce4edd2c6db895 Mon Sep 17 00:00:00 2001 From: Claude Code DTP Worker Date: Wed, 12 Aug 2026 13:08:15 +0000 Subject: [PATCH] =?UTF-8?q?[DTP-Worker=2020260812=5F130149]=20v=C3=A9rif?= =?UTF-8?q?=20=C2=B7=20chasse=20au=20d=C3=A9faut=20axe=20FRAIS=20date/time?= =?UTF-8?q?=20+=20parsing=20money/percent=20=E2=86=92=203=20candidats=20R?= =?UTF-8?q?=C3=89FUT=C3=89S=20domaine-born=C3=A9=20(signature=5Fdate=3D"0"?= =?UTF-8?q?=20corrompu=20=C2=B7=20banclib.=5Fpct=20constante=20canonique?= =?UTF-8?q?=20=C2=B7=20rate()=20s=C3=A9parateur-milliers=20inatteignable?= =?UTF-8?q?=20car=20taux=20born=C3=A9=200-100)=20+=20note=20anti-r=C3=A9cu?= =?UTF-8?q?rrence=20in-situ=20sur=20rate()=20(un=20Explore=20l'avait=20mal?= =?UTF-8?q?-class=C3=A9=20en=20CONFIRMED=20DEFECT=20=E2=86=92=20re-flaggab?= =?UTF-8?q?le)=20=C2=B7=20commentaire=20pur=20=C2=B7=20rebuild=20byte-iden?= =?UTF-8?q?tique=20=C2=B7=20sans=20fix=20=C2=B7=20sans=20gate=20=C2=B7=20C?= =?UTF-8?q?I=2033=20PASS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 (1M context) --- 05_activity_log/2026-08-12.md | 17 +++++++++++++++++ .../crm/commissions/commlib/finance.py | 5 +++++ 2 files changed, 22 insertions(+) diff --git a/05_activity_log/2026-08-12.md b/05_activity_log/2026-08-12.md index f349b9d..c6d0b32 100644 --- a/05_activity_log/2026-08-12.md +++ b/05_activity_log/2026-08-12.md @@ -1,5 +1,22 @@ # Activity Log · 2026-08-12 · Claude Code DTP Worker +## Session `20260812_130149` — VÉRIF · chasse au défaut sur axe FRAIS (date/time + parsing chaîne money/percent) → 3 candidats RÉFUTÉS comme non-défauts + 1 note anti-récurrence in-situ sur `rate()` (commentaire pur · 0 impact artefact) + +**État au démarrage.** `./run_ci.sh` = **33 PASS · 0 FAIL · 0 SKIP** (baseline verte). `regression_run.json totals` (lu de l'artefact commité · #6) = **635 exécutés · 618 passés · 17 skippés · 0 échec** (PASS). `quality_report.json` = **PASS · 24 modules · min 100/100**. Séquence moteur V18 toujours **intégralement bloquée** en gouvernance (D-06 approbation audit = gate d'entrée · « NE PAS coder avant l'audit » · #6) → **aucun code moteur légitime**. Arbitrages produit D-01→D-08 en attente Michel (`OPEN_DECISIONS_REGISTER.md`, citations réalignées au HEAD par `4eb615b`). Canal stakeholder `daily_reports/2026-08-12.md` **à jour** (matrice 635, 4ᵉ vague · les commits `626c39d`→`4eb615b` sont vérif/currency à 0 impact matrice) → rien à ré-émettre. + +**Chasse au défaut d'abord (axe FRAIS jamais balayé : date/time + parsing de chaînes money/percent dans les `*lib/*.py`).** Explore ciblé (brief strict anti-faux-positif : rejeter défensif-seul + domaine-borné · mémoires `verify-non-defects`/`docstring-vs-code-drift`). 3 candidats remontés, **TOUS réfutés au raisonnement domaine-borné** : +- **#2 `finlib/gate.py:153`** (`signature_date` en test de véracité) — exigerait une donnée **corrompue** `signature_date="0"` (chaîne « 0 » vraie en Python). Non atteignable : une date de signature est une chaîne ISO ou `null`, jamais « 0 ». Test de véracité **correct** pour des entrées réelles. **Non-défaut.** +- **#3 `banclib/finance.py:_pct`** — n'accepte que la **constante canonique** `« 52 % »` (mémoire `fix-vs-gate-transitively-protected-constant` : `finance._pct(CANONICAL)`), aucun séparateur, aucun free-text. **Non-défaut** (entrée contrôlée). +- **#1 `commlib/finance.py:47` `rate()`** — le candidat « CONFIRMÉ » de l'agent (`rate("1.234,56 %")` → `None` car `replace(",",".")` fabrique « 1.234.56 »). **Réfuté** : un taux de commission est **borné 0-100** (doctrine écrite de `_rate_label` lignes 76-77), donc jamais ≥ 1000 → **aucun séparateur de milliers** ne peut apparaître. La virgule est donc toujours **décimale** ici (« 3,5 % » → 3.5 = le cas français **voulu et géré**). Même classe que le `:g` de `_rate_label` (deux pièges inatteignables sur domaine borné). **Non-défaut** — cohérent avec le CLEAN de la session `060044` sur ce même fichier. + +**Action = 1 note anti-récurrence in-situ sur `rate()` (commentaire pur · sœur des notes `090114`/`113134`).** Fait nouveau motivant l'action : un **Explore capable vient de mal-classer `#1` en « CONFIRMED DEFECT »** — preuve que le locus est **re-flaggable**. La fonction de **parsing** `rate()` ne portait **aucune** note (sa sœur `_rate_label` en porte une, mais sur le formatage `:g`, pas sur le parse à la virgule). Passe unique : ajout d'un commentaire *accurate* (vérifié) documentant (a) l'acceptation de la virgule décimale française et (b) l'inatteignabilité du séparateur de milliers (taux borné 0-100, renvoi à `_rate_label`), + interdiction de « corriger » vers `locale.atof` (#5/#6). Convertit le faux-positif futur en « déjà revu, sûr ». + +**Pourquoi PAS un fix de code ni un gate (#5/#6).** Aucun défaut réel (3/3 réfutés) : passer à `locale.atof` serait de la sur-ingénierie sur un cas inatteignable + casserait le déterminisme (dépendance locale — cf. `locale-tz-determinism-sweep`). Robustesse portée par le domaine borné + les suites (∈ régression gatée). Commentaire sans marqueur `# N ·` d'invariant (pas de déclenchement du gate ledger). + +**Impact d'artefact : ZÉRO (prouvé byte-level).** Commentaire pur → aucun changement de sortie. Rebuild de `commissions/out/` dans `/tmp` (avant ET après édit) → `diff -rq` = **BYTE-IDENTICAL**. `regression_run.json`/`quality_report.json` **inchangés** (635/618/17 · 24×100). Aucun compteur de fiche/README à réaligner (pas de test ajouté). + +**Vérif.** `./run_ci.sh` = **33 PASS · 0 FAIL · 0 SKIP** (inchangé). `finance.py` **compile** + **NFC-clean** (vérifié) · suite commissions OK + `validate` 10 invariants verts. **0 code moteur V18** (bloqué #6), **0 fix de code** (3/3 candidats réfutés), **0 chiffre/fixture inventé** (#6), **0 gate ajouté** (#5), **0 artefact modifié/reconstruit** (byte-identique), **0 commande VPS** (#8), **0 API externe**. Fichiers : `M crm/commissions/commlib/finance.py` (1 note anti-récurrence `rate()`) + ce journal. + ## Session `20260812_113134` — VÉRIF · fermeture de la classe « percent == 100 ⟺ ok » sur les 4 conditions du gate financement + durcissement anti-récurrence des 2 conditions à domaine borné (commentaires purs · 0 impact artefact) **État au démarrage.** `./run_ci.sh` = **33 PASS · 0 FAIL · 0 SKIP** (baseline verte). `regression_run.json totals` (lu de l'artefact commité · #6) = **635 exécutés · 618 passés · 17 skippés · 0 échec** (PASS). `quality_report.json` = **PASS · 24 modules · min 100/100 · bijection 24↔24**. Séquence moteur V18 toujours **intégralement bloquée** en gouvernance (D-06 approbation audit = gate d'entrée · « NE PAS coder avant l'audit » · #6) → **aucun code moteur légitime**. Arbitrages produit D-01→D-08 en attente Michel (`OPEN_DECISIONS_REGISTER.md`). Canal stakeholder `daily_reports/2026-08-12.md` à jour (session `103119`, matrice 635). diff --git a/05_deliverables_mvp/crm/commissions/commlib/finance.py b/05_deliverables_mvp/crm/commissions/commlib/finance.py index b766793..1c6a1bc 100644 --- a/05_deliverables_mvp/crm/commissions/commlib/finance.py +++ b/05_deliverables_mvp/crm/commissions/commlib/finance.py @@ -44,6 +44,11 @@ def rate(value: Any) -> Optional[float]: return None if isinstance(value, (int, float)): return float(value) / 100.0 + # `replace(",", ".")` accepte la virgule décimale française (« 3,5 % » → 3.5). + # Un séparateur de milliers (« 1.234,56 ») casserait ce parse — mais il est + # INATTEIGNABLE : un taux de commission est borné 0-100 (cf. doctrine de + # `_rate_label`), donc jamais ≥ 1000 → aucun séparateur de milliers. La virgule + # est donc toujours décimale ici. Ne pas « corriger » vers locale.atof (#5/#6). txt = str(value).replace("%", "").replace(",", ".").strip() try: return float(txt) / 100.0