Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
14 KiB
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 « Mappingscope_donnees→ mécanisme » : nomme, PAR portée, lemechanismFrappe natif (own→docperm_if_owner·entite→user_permission_company·groupe→none_consolidated·equipe→vps_confirm_team) ET le verdict « Template émis ? » (ouipourentiteseul, sinonnon (null)).- Source faisant autorité (byte-gatée par
check_artifacts) :out/user_permission_plan.json— chaque entrée portescope_donnees+mechanism+user_permission_template(null ou objet). Le mapping est une fonction : chaque portée → exactement un mécanisme ; template émis SSIentite/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 suitetests/(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ᵉ surfacerbac/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éellepython3 bancable_gen.py validate(émet le manifeste sur stdout,figures_calculees[]). Le52 %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 pipelinecheck-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.
Session 20260801_010204 · Buffer S8 · Domaine Mobile/fiche agent : la fiche d'identité du rôle RBAC plateforme-mobile (03_agents/mobile/AGENT.md:36) — le SEUL ancrage in-repo réellement vérifiable de l'agent mobile (builds/soumissions stores étant hors-repo, #8) — recopiait EN PROSE, DEPUIS le contrat rbac_50_roles.json, TOUS les attributs data-derived du rôle (erpnext_role_name · nom_fr · famille/portail · entite_principale · niveau · scope_donnees · modules · permission API Access custom R/W · description) SANS AUCUN gate d'IDENTITÉ. Le README mobile/app_config n'est gaté que sur des COMPTES agrégés (« 5 onglets · 44 rôles couverts · 3 langues · 13 identifiants »), AVEUGLES à l'identité de CE rôle.
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
la table gardes CRM/workflow_vente (rôle qui garde chaque transition) ou le mapping
RBAC userperm_gen (portée→mécanisme) — appliqué à la surface distincte de la
fiche agent mobile : la carte que l'agent ERPNext Backend lit pour seeder le rôle
(seed_mobile_rbac.py), jamais gatée hors les comptes agrégés de app_config.
Dérive silencieuse fermée :
03_agents/mobile/AGENT.md:36— ligne « Points de contact réellement commités », cellule « Ce qu'il fixe » : nomme, PAR attribut, le rôle ERPNextOTO Plateforme Mobile(« Développeur Mobile » · famille/portailplateforme· entité 9060 QC · niveau 2 · scopegroupe· modulesCore+Website· permAPI Accesscustom R/W · description « Maintient l'app Expo/React Native et l'API mobile ; gère les builds EAS et les soumissions stores »).- Source faisant autorité :
05_deliverables_mvp/rbac/rbac_50_roles.json(contrat RBAC, schéma-validé · les 3 MANIFEST RBAC recomputés en dérivent et sont byte-gatés parcheck_artifacts) → le rôle d'idplateforme-mobileporte chacun de ces champs. Autres blocs du gate lisent déjà ce contrat directement (userperm, workflow_vente, confotur). - Piège : la seule vérification existante (
tests/) teste des FONCTIONS de résolution RBAC, jamais la PROSE d'une fiche agent. Éditer le contrat — élever lescope_donnees(groupe→entite: sur-portée inter-entités, la restriction même que le rôle pose), changer leniveau/l'entite_principale, renommer le rôle, ajouter/retirer un module ou élargir la permission (R/W→R/W/D) — laisse la fiche périmée pendant que le contrat dit autre chose → l'agent ERPNext Backend câblerait le mauvais rôle (le risque même que la fiche veut prévenir). - État courant : aucun attribut périmé — les 9 attributs + la description recoupent le contrat exactement (anti-invention #6, rien à réécrire). Le défaut est la surface ungated.
Gate ajouté (ci/check_readme_claims.sh, nouveau bloc « Fiche Mobile » avant
sys.exit) : (1) par attribut — erpnext_role_name · nom_fr · portail ·
entite_principale · niveau · scope_donnees · modules · permission recomputés
du contrat, prose EXACTE exigée (regex par attribut, lookaheads anti-préfixe pour
niveau/modules/perm) ; (2) permission — le sigle des verbes est canonique et
ordonné (C/R/W/D/S/X/A) : élargir OU rétrécir la perm change le sigle attendu (un
préfixe R/W ne satisfait plus R/W/D, ni l'inverse) ; verbe inconnu ⇒ ROUGE
(étendre le gate) ; (3) description recoupée verbatim (emphase markdown ** et
point final neutralisés). Cohérences croisées bonus (mordent un contrat INTERNEMENT
incohérent) : famille == portail (bijection portail) · permission bien custom ·
role_id présent EXACTEMENT une fois. Un claim absent échoue AUSSI (traçabilité :
ligne de rôle INTROUVABLE).
12 morsures vérifiées (6 côté contrat = fiche périmée · 6 côté fiche = fiche
fausse) : contrat scope groupe→entite (sur-portée) · contrat niveau 2→3 · contrat
+delete (sigle R/W→R/W/D) · contrat description réécrite · contrat rôle renommé
(OTO Plateforme Mobile→OTO Mobile Dev) · fiche modules Website→Selling · fiche
entité 9060 QC→WAF · fiche perm R/W→R/W/D (sur-revendication) · fiche perm R/W→R
(sous-revendication) · fiche modules over-claim +Selling et under-claim Core seul ·
ligne de rôle entièrement supprimée (INTROUVABLE) ; restauré = green : 9 attributs +
description == contrat · famille==portail · perm custom · role_id singleton · exit 0.
Working tree byte-restauré (git checkout --, JAMAIS git clean, interdit
absolu) · 7 gates re-verts.
ci/README.md(table récap du pipeline + paragraphe détaillé « Fiche d'identité du rôle RBAC mobile ») 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 ; le seed réel du rôlebenchreste côté VPS). - Auto-score 4Big : 96/100.