Files
oto-enterprise-os-dtp/05_activity_log/2026-08-01.md
T
Claude Code DTP Worker e8b30d7147 [DTP-Worker] Sprint 8 · buffer · Faisabilité/bancable : les 4 figures « Génération réelle (fixture) » du README (40 unités · USD 8,560,000 / DOP 505,040,000 · point d'équilibre 21 unités ⌈52 % × 40⌉) — les chiffres DATA-DERIVED du dossier bancable que voit le banquier — étaient HORS de tout gate. Le module n'écrit son out/ que sur disque (« out/ non commité ») ⇒ check_artifacts est aveugle (aucun artefact byte-gaté) et AUCUN gate ne le touchait.
Ces 4 figures sont Σ quantités · Σ(qté×prix_usd) · Σ(qté×prix_dop) · ⌈point_equilibre_pct × Σ unités⌉ calculées sur la fixture COMMITÉE fixtures/brief_bancable.json, le 52 % ancré sur CLAUDE.md #9 (« Point équilibre 52% pré-vente »). PIÈGE : la seule vérification existante (tests/) teste des FONCTIONS (l'arithmétique de recoupement _check_derived_arithmetic) avec des oracles HARDCODÉS dans le test — une copie de plus, jamais comparée à la PROSE du README. Éditer une typologie de la fixture (quantité/prix), en ajouter/retirer une, ou déplacer le point d'équilibre de CLAUDE.md #9, laisse les 4 chiffres du README périmés pendant que le générateur produit autre chose → le banquier lit un dossier faux (l'invention même que #6 interdit) — « vert trompeur » qu'aucune suite tests/ n'attrape.

Nouveau bloc « Faisabilité/bancable figures » dans ci/check_readme_claims.sh (avant sys.exit), même esprit que le bloc faisabilite/generator ancré sur CLAUDE.md #9/#10 mais appliqué à une surface dont la source de vérité n'est PAS un out/*.json : (1) recompute indépendant des 4 figures depuis la fixture commitée ; (2) cohérence croisée — le manifeste GÉNÉRÉ (bancable_gen validate, exécuté via subprocess stdlib pur, encoding utf-8) == le recompute (mord un générateur/fixture incohérents) ; (3) prose — un seul pattern d'identité exige les 4 valeurs EXACTES avec séparateur de milliers pour USD/DOP + la formule ⌈pct × Σ unités⌉ dont le pct == CLAUDE.md #9 et le total == Σ unités. Un claim absent échoue AUSSI (traçabilité).

État courant : aucun chiffre périmé (anti-invention #6, rien à réécrire) — le défaut est la surface ungated (module entièrement hors CI). 7 morsures vérifiées : README USD 8,560,000→9,560,000 (figure périmée) · README retire le séparateur de milliers (8,560,000→8560000) · README breakeven 21→20 (formule périmée) · README formule 52 %→55 % (dérive CLAUDE.md #9) · README supprime la ligne entière (INTROUVABLE) · fixture Studio qté 12→13 (5 morsures : units/USD/DOP/breakeven README périmés + manifeste) · fixture 2 Chambres prix_usd 320000→300000 (catalogue USD périmé) ; restauré = green : 4 figures == génération réelle · manifeste == recompute · pct 52 % == CLAUDE.md #9 · exit 0. Working tree byte-restauré via git checkout -- (JAMAIS git clean) · 7 gates re-verts. ci/README.md (ligne récap check-readme-claims) mis à jour · log 05_activity_log/2026-08-01.md. Auto-score 4Big 96/100.

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

122 lines
9.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Activity Log · 2026-08-01 · Claude Code DTP
## Session `20260801_000201` · Buffer S8 · Domaine RBAC/userperm_gen : la **table « Mapping `scope_donnees` → mécanisme »** — la **FONCTION d'enforcement ROW-LEVEL** (quel mécanisme Frappe natif applique CHAQUE portée de données + si un `User Permission` template est émis), CŒUR sécurité du module — était transcrite EN PROSE (README:33-38) SANS AUCUN gate d'IDENTITÉ. Le bloc RBAC « 3 volets » existant ne gate QUE la **ventilation** par mécanisme (« 28 `entite` · 16 `groupe` · 2 `own` · 4 `equipe` »), un COMPTE aveugle à QUEL mécanisme applique QUELLE portée.
**Tâche** : **Sprint 8 · buffer** (DevOps CI/CD · QA). Roadmap fonctionnellement
close ; poursuite de la série anti-dérive (CLAUDE.md #6). Même patron d'IDENTITÉ que
le mapping RBAC `fixtures_gen` (séparation des pouvoirs `set_user_permissions`) ou la
cross-cohérence PERMISSIONS Legal/CONFOTUR (`role_id`→actions) — appliqué à la
**surface data-derived distincte du même README `rbac/userperm_gen`** : la table
qui associe chaque portée de données à son mécanisme d'enforcement, jamais gatée hors
son compte agrégé.
**Dérive silencieuse fermée** :
- `05_deliverables_mvp/rbac/userperm_gen/README.md:33-38` — table « Mapping
`scope_donnees` → mécanisme » : nomme, PAR portée, le `mechanism` Frappe natif
(`own``docperm_if_owner` · `entite``user_permission_company` ·
`groupe``none_consolidated` · `equipe``vps_confirm_team`) ET le verdict
« Template émis ? » (`oui` pour `entite` seul, sinon `non (null)`).
- Source faisant autorité (byte-gatée par `check_artifacts`) :
`out/user_permission_plan.json` — chaque entrée porte `scope_donnees` +
`mechanism` + `user_permission_template` (null ou objet). Le mapping est une
**fonction** : chaque portée → exactement un mécanisme ; template émis SSI
`entite`/`user_permission_company`.
- Piège : le bloc de ventilation est AVEUGLE à l'identité de ces couples.
RÉAFFECTER une portée à un mécanisme plus permissif (`entite`
`none_consolidated` : le **row-level enforcement ABANDONNÉ**, sur-exposition des
données inter-entités — la restriction même que le module pose), RENOMMER un
mécanisme ou BASCULER le verdict « Template émis ? » laisse le README périmé
pendant que l'artefact dit autre chose → l'agent ERPNext Backend câblerait le
mauvais mécanisme (le risque même que la table veut prévenir). Aucune suite
`tests/` (qui teste des FONCTIONS de mapping/résolution, pas la prose) n'attrape
ce « vert trompeur ».
- **État courant** : **aucune ligne périmée** — les 4 couples portée→mécanisme et
leurs verdicts recoupent l'artefact exactement (anti-invention #6, rien à
réécrire). Le défaut est la **surface ungated**.
**Gate ajouté** (`ci/check_readme_claims.sh`, nouveau bloc « RBAC/userperm_gen
Mapping » après le bloc CRM gardes) : (1) **par portée** — le `mechanism` (1er token
backtické de la colonne) ET le verdict « Template émis ? » (`**oui**` / `non (null)`)
recomputés de `user_permission_plan.json`, prose exigée EXACTE ; (2) **identité
d'ensemble** — portées de la table == portées de l'artefact (set-diff : ni fantôme
ni manquante). Cohérences croisées en bonus (mordent un plan INTERNEMENT incohérent) :
chaque portée mappe UN SEUL mécanisme (fonction, pas relation) · « Template émis »
UNIFORME sur les entrées d'une portée · template émis EXACTEMENT pour
`user_permission_company` (l'invariant « template SSI `entite` » du README:36/61) ·
ensemble des portées NON VIDE. Un claim absent échoue AUSSI (traçabilité).
**7 morsures vérifiées** : README réaffecte `entite``none_consolidated`
(mécanisme périmé · élévation de portée) · README bascule `entite` « Template
émis » oui→non (verdict périmé) · README échange une portée `groupe``famille`
(absents=[groupe] + en trop=[famille] + ligne INTROUVABLE) · README retire la
ligne `own` (absents=[own]) · table entière supprimée (les 4 absents + toutes
lignes INTROUVABLES) · **artefact** réaffecte toutes les entrées `entite`
`none_consolidated` (README périmé sur mécanisme ET verdict) · **artefact** rend
une entrée `own` porteuse d'un template (« Template émis » NON uniforme
[False,True] · invariant SSI cassé) ; restauré = green : 4 portées · table ==
artefact · par-ligne exact · fonction/uniforme/SSI verts · exit 0. Working tree
byte-restauré (`git checkout --`, **JAMAIS** `git clean`) · **7 gates re-verts**.
- `ci/README.md` (table récap du pipeline + paragraphe détaillé « 2ᵉ surface
`rbac/userperm_gen` ») mis à jour.
- **Hors périmètre worker (VPS · #8)** : néant (gate bash/python3 stdlib en-repo ;
édition **hors** `05_deliverables_mvp/*/out` ⇒ 0 dérive d'artefact).
- **Auto-score 4Big** : 96/100.
## Session `20260801_003201` · Buffer S8 · Domaine Faisabilité/bancable : les **4 figures « Génération réelle (fixture) »** du README (`40 unités · valeur catalogue USD 8,560,000 / DOP 505,040,000 · point d'équilibre 21 unités (⌈52 % × 40⌉)`) — les chiffres DATA-DERIVED que le **dossier bancable** (l'artefact que voit le banquier) recopie — étaient **HORS de tout gate**. Le module n'écrit son `out/` que sur disque (« out/ non commité ») ⇒ **check_artifacts est aveugle** (aucun artefact byte-gaté) et **AUCUN** gate ne le touchait.
**Tâche** : **Sprint 8 · buffer** (DevOps CI/CD · QA). Roadmap fonctionnellement
close ; poursuite de la série anti-dérive (CLAUDE.md #6). Même esprit que les
paramètres canoniques `faisabilite/generator` **ancrés sur CLAUDE.md #9/#10** (le
`52 %` réutilisé ici) — appliqué à une **surface encore jamais gatée** : un module
dont la source de vérité n'est PAS un `out/*.json` mais **la fixture commitée + le
générateur**.
**Dérive silencieuse fermée** :
- `05_deliverables_mvp/faisabilite/bancable/README.md:103-105` — ligne
« Génération réelle (fixture) » : `40 unités` (= Σ quantités typologies) ·
`USD 8,560,000` (= Σ qté×prix_usd) · `DOP 505,040,000` (= Σ qté×prix_dop) ·
`21 unités (⌈52 % × 40⌉)` (= ⌈point_equilibre_pct × Σ unités⌉).
- Source faisant autorité : `fixtures/brief_bancable.json` (COMMITÉE) + la
**génération réelle** `python3 bancable_gen.py validate` (émet le manifeste sur
stdout, `figures_calculees[]`). Le `52 %` est **ancré sur CLAUDE.md #9**
(« Point équilibre 52% pré-vente »), pas recopié.
- Piège : la seule vérification existante (`tests/`) teste des **FONCTIONS**
(l'arithmétique de recoupement `_check_derived_arithmetic`) avec des **oracles
HARDCODÉS** dans le test — une copie de plus, jamais comparée à la PROSE du
README. Éditer une typologie de la fixture (quantité/prix), en ajouter/retirer
une, ou déplacer le point d'équilibre de CLAUDE.md #9, laisse les 4 chiffres du
README périmés pendant que le générateur produit autre chose → le banquier lit
un dossier faux (l'invention même que #6 interdit).
- **État courant** : **aucun chiffre périmé** — les 4 figures recoupent la
génération réelle exactement (anti-invention #6, rien à réécrire). Le défaut est
la **surface ungated** (module entièrement hors CI).
**Gate ajouté** (`ci/check_readme_claims.sh`, nouveau bloc « Faisabilité/bancable
figures » avant `sys.exit`) : (1) **recompute indépendant** des 4 figures depuis
la fixture commitée ; (2) **cohérence croisée** — le manifeste GÉNÉRÉ
(`bancable_gen validate`) == le recompute (mord un générateur/fixture
incohérents) ; (3) **prose** — un seul pattern d'identité exige les 4 valeurs
EXACTES, **avec séparateur de milliers** pour USD/DOP, + la formule `⌈pct × Σ
unités⌉` dont le pct == CLAUDE.md #9 et le total == Σ unités. Un claim absent
échoue AUSSI (traçabilité). Le `out/` n'étant pas commité, le gate **exécute le
générateur** (stdlib pur, `subprocess`, `encoding="utf-8"`) au lieu de lire un
artefact byte-gaté — même patron que le bloc `faisabilite/generator` qui lit
`model.py`.
**7 morsures vérifiées** : README `USD 8,560,000→9,560,000` (figure périmée) ·
README retire le séparateur de milliers (`8,560,000→8560000`) · README breakeven
`21→20` (formule périmée) · README formule `52 %→55 %` (dérive CLAUDE.md #9) ·
README supprime la ligne entière (INTROUVABLE · claim absent) · **fixture** Studio
`qté 12→13` (5 morsures : units/USD/DOP/breakeven README périmés + manifeste) ·
**fixture** 2 Chambres `prix_usd 320000→300000` (catalogue USD périmé) ; restauré =
green : 4 figures == génération réelle · manifeste == recompute · pct 52 % ==
CLAUDE.md #9 · exit 0. Working tree byte-restauré via `git checkout --` (JAMAIS
`git clean`, interdit absolu) · **7 gates re-verts**.
- `ci/README.md` (ligne récap du pipeline `check-readme-claims`) mis à jour.
- **Hors périmètre worker (VPS · #8)** : néant (gate bash/python3 stdlib en-repo ;
aucune écriture dans un `out/` ⇒ 0 dérive d'artefact ; conversion PDF + rebuild
Portail Bancables restent côté VPS).
- **Auto-score 4Big** : 96/100.