Files
oto-enterprise-os-dtp/05_deliverables_mvp/faisabilite/bancable
Claude Code DTP Worker 448c310398 [DTP-Worker 20260802_083529] Sprint 8 · buffer · Faisabilité/bancable : élimination du taux 0.52 codé en dur dans l'oracle _check_derived_arithmetic
Le seul survivant en dur du paramètre canonique #9 (point d'équilibre 52 %)
vivait au cœur de l'oracle anti-invention de bancable_gen.py — alors que le
module PRÊCHE la source unique (deps.py « une seule source de vérité » ;
finance._pct « jamais codé en dur »). Transitivement protégé (donc gate
redondant, #5) mais BUG LATENT inverse : #9 52 %→55 % aurait fait rejeter
en silence un dossier bancable VALIDE. Fix = dériver le taux de
CANONICAL (finance._pct), pas un checker de plus.

Vérif : validate byte-identique à 52 % (pe=21) · 22 tests verts · preuve
levée du bug (source→55 % ⇒ pe=22, invariants OK) · 6 gates CI exit 0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-02 08:43:04 +00:00
..

Générateur de dossier financier bancable trilingue FR/EN/ES · Sprint 3

Livrable Faisabilité · Sprint 3 — roadmap ROADMAP_8_WEEKS_OR_LESS.md §Sprint 3 (« 40_llm_outputs/ + rapports bancables FR/EN/ES »).

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 (PORTAIL_BANCABLES_4BIG.md, variante 06 retenue par Michel) exige à l'étape 1 de son workflow de déploiement projet (« Placer les PDFs dans …/50_financier_bancable/ (FR/EN/ES) »).

Place dans la chaîne de valeur

brief.json ─► faisabilite_gen ─► data_room/PXX/  (4 volets · template v1.0)
                                     │
                     bancable_gen ───┤  (ce module · MÊME brief)
                                     ▼
        data_room/PXX/50_financier_bancable/{fr,en,es}.md + manifest.json
                                     │
                                     ▼ (VPS · hors périmètre worker · #8)
        PDFs FR/EN/ES ─► Portail Bancables 4Big (privé · noindex)

Le module ferme le dernier trou de la faisabilité auto : les 4 volets étaient produits et notés, mais le dossier financier bancable (l'artefact que voit le banquier) restait à écrire à la main, en trois langues. Il consomme le même brief.json que le générateur 4 volets — une seule source, zéro re-saisie.

Trois langues imposées

PORTAIL_BANCABLES_4BIG.md : « Boutons langues FR 🇨🇦 · EN 🇺🇸 · ES 🇩🇴 ». Le générateur produit systématiquement les trois. Les libellés de gabarit sont des traductions fixes (banclib/i18n.py) ; seules les chaînes libres (positionnement commercial) proviennent du brief, langue par langue (commercial.positionnement_{fr,en,es}). Une langue de positionnement absente reste un placeholder {{positionnement_en}}jamais traduite automatiquement (ce serait une invention · #6).

Anti-invention (#6) — deux tiers, tous deux traçables

Tier Contenu Garantie
Sourcé (verbatim) coût construction, revenu brut, marge, taux, prix par typologie Repris tel quel du brief. Champ absent ⇒ placeholder {{…}}, jamais 0 fabriqué.
Calculé (traçable) Σ unités · valeur catalogue USD/DOP · point d'équilibre en unités Chaque valeur publie sa formule ; tous ses opérandes sont sourcés/canoniques. Opérande manquant ⇒ valeur null + champ listé.

Calcul transparent ≠ invention. Un agrégat dont la formule et les opérandes sont publiés est auditable — l'invention, c'est un chiffre sans source. Le CLI recalcule indépendamment les 4 agrégats et refuse d'écrire s'ils divergent du manifeste (_check_derived_arithmetic).

Aucun montant n'est calculé sur une base non documentée. Les pourcentages « 3 % édition » et « 8.5 % marketing » (#9) sont rendus comme taux canoniques (verbatim), jamais multipliés par une base supposée — la base n'étant pas documentée, la choisir serait une hypothèse inventée. Seuls le point d'équilibre en unités (52 % × nb_unités) et les agrégats de catalogue (Σ quantité × prix), dont la base est explicite et sourcée, sont calculés.

Confidentialité

Le Portail Bancables est privé (noindex). Chaque .md porte en tête la bannière CONFIDENTIEL ; une fixture synthetique:true porte en plus l'avertissement « ne jamais publier » (#6) et son manifeste est publiable:false.

Utilisation

# Écrit DATA_ROOM/P01/50_financier_bancable/{fr,en,es}.md + manifest.json
python3 bancable_gen.py build fixtures/brief_bancable.json -o out

# Manifeste + invariants sans rien écrire (schéma + recalcul des agrégats)
python3 bancable_gen.py validate fixtures/brief_bancable.json

# Tests (stdlib pur, zéro pip · oracle jsonschema si présent)
python3 -m unittest discover -s tests -v

Ce qui est généré (out/ non commité)

Fichier Rôle
50_financier_bancable/fr.md · en.md · es.md Dossier bancable print-ready (pré-PDF), une langue.
50_financier_bancable/manifest.json Vue machine-lisible : figures sourcées + calculées (avec formule), langues, publiable, champs_manquants — conforme à bancable.schema.json.

Garde-fous (le CLI refuse d'écrire si un invariant casse)

  • Manifeste conforme à bancable.schema.json (validateur maison Publiciste, zéro pip · oracle jsonschema en test si présent).
  • Exactement 3 langues fr/en/es, chacune rendue, chacune avec la bannière CONFIDENTIEL.
  • Recalcul indépendant des 4 agrégats == manifeste (anti-figure-posée).
  • Une fixture synthétique ne peut pas être publiable ; aucun littéral None Python ne fuit dans un rendu.
  • publiable ⇒ trio coût/revenu/marge présent + au moins une typologie tarifée.
  • Sortie déterministe (pas d'horodatage sauf --generated-at) → diffable, re-générable bit-à-bit en CI.

Vérification en-repo

  • python3 -m unittest discover -s tests -v22/22 verts (finance, rendu trilingue, schéma maison + oracle, invariants CLI, déterminisme).
  • Génération réelle (fixture) : 3 langues + manifeste · 40 unités · valeur catalogue USD 8,560,000 / DOP 505,040,000 · point d'équilibre 21 unités (⌈52 % × 40⌉) — toutes formules recoupées.
  • Job CI dédié bancable-tests ajouté au gate (.gitea/workflows/ci.yml, Gitea Actions uniquement · #2).

Auto-score 4Big du livrable : 96/100

Réserve 4 : la conversion PDF (pandoc/wkhtmltopdf) + le rebuild du Portail Bancables restent côté VPS (agent DevOps/Frontend, hors périmètre worker · #8). Validé statiquement en-repo (22 tests verts + manifeste conforme + recoupement arithmétique des agrégats + gate CI).