[DTP-Worker 20260806_031432] FIX générateur — crm/financement_bancaire MANIFEST.roles_rbac_utilises répétait ventes-conseiller (dup ungaté, liste per-slot vs ensemble distinct)
Défaut réel/reproductible (pas stale, byte-repro vert) : finlib/builder.py:89
faisait [roles_resolved[k] for k in sorted(roles_resolved)], itérant les 4 SLOTS
logiques de spec["roles"] — 2 slots (conseiller_wag ET validation_dossier) pointent
le même rôle ventes-conseiller → 4 entrées pour 3 rôles distincts. Preuve bug (pas
per-slot voulu) : la sortie drope la clé de slot (cle), donc le doublon ne porte
aucune info distinctive ; sémantique documentée README.md:54 « rôles RBAC utilisés »
+ ci/README.md:1100 « ensemble distinct » ; les 3 modules frères produisent tous un
ensemble distinct (confotur 3/3, commissions 4/4, workflow_vente 7/7) — financement
seul outlier 4/3.
Fix (aligné idiome commissions) : ensemble distinct trié par role_id via
sorted({rr["role_id"] for rr in roles_resolved.values()}). Artefact régénéré → 3/3
distinct. 0 gate ajouté (#5 — champ lu par AUCUN gate financement ni consommateur
externe ; convention distinctness déjà tenue par les frères). 0 chiffre inventé (#6).
run_ci 33 PASS · 0 FAIL · 0 SKIP (byte-repro vert avec nouvel artefact, 35 tests verts).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,50 @@
|
|||||||
# Activity Log · 2026-08-06 · Claude Code DTP Worker
|
# Activity Log · 2026-08-06 · Claude Code DTP Worker
|
||||||
|
|
||||||
|
## Session `20260806_031432` — FIX générateur (NOUVELLE sous-classe : liste per-slot vs ensemble distinct) · `crm/financement_bancaire` : `MANIFEST.roles_rbac_utilises` répétait `ventes-conseiller` (dup ungaté)
|
||||||
|
|
||||||
|
**Choix de tâche.** `./run_ci.sh` au démarrage = **33 PASS · 0 FAIL · 0 SKIP**, arbre propre,
|
||||||
|
roadmap intégralement livrée/gatée. Les 5 derniers commits étant FIX-help / currency / vérif-only,
|
||||||
|
chasse **adversariale à un vrai défaut ungaté** sur un **axe frais** (anti-churn) : la
|
||||||
|
**cohérence sémantique interne des artefacts commités** (un champ « ensemble » contenant un
|
||||||
|
doublon) — axe non balayé par les 7 axes de `024430`.
|
||||||
|
|
||||||
|
**Défaut trouvé (réel, haute confiance).**
|
||||||
|
`05_deliverables_mvp/crm/financement_bancaire/out/MANIFEST.json` · `roles_rbac_utilises` portait
|
||||||
|
**4 entrées pour 3 rôles distincts** : `ventes-conseiller` / `OTO Ventes Conseiller` **répété**
|
||||||
|
(positions 1 et 4). Reproductible depuis le générateur (donc **pas** un artefact stale — byte-repro
|
||||||
|
vert) : `finlib/builder.py:89` faisait `[roles_resolved[k] for k in sorted(roles_resolved)]`,
|
||||||
|
itérant les **4 slots logiques** de `spec["roles"]` — or **deux** slots (`conseiller_wag` ET
|
||||||
|
`validation_dossier`) pointent le même rôle `ventes-conseiller` → doublon.
|
||||||
|
|
||||||
|
**Preuve que c'est un bug et non un per-slot voulu.**
|
||||||
|
1. La sortie **drope la clé de slot** (`cle`) : chaque entrée ne porte que `role_id` +
|
||||||
|
`erpnext_role_name`. Un doublon ne transporte donc **aucune** information distinctive — si le
|
||||||
|
per-slot était voulu, la clé de slot serait sérialisée. Smoking gun.
|
||||||
|
2. Sémantique documentée : README `MANIFEST.json → … rôles RBAC **utilisés** » (README.md:54) +
|
||||||
|
`ci/README.md:1100` « l'**ensemble distinct** `(role_id, nom)` réellement payé ».
|
||||||
|
3. **Convention codebase** : les 3 modules frères produisent tous un ensemble **distinct**
|
||||||
|
(`confotur` 3/3 · `commissions` 4/4 · `workflow_vente` 7/7, `n == distinct`). `financement`
|
||||||
|
était **le seul outlier** (4/3).
|
||||||
|
|
||||||
|
**Fix (`finlib/builder.py:89`, aligné idiome `commissions`).** Ensemble **distinct** trié par
|
||||||
|
`role_id` : `[{"role_id": rid, "erpnext_role_name": resolver.erpnext_name(rid)} for rid in
|
||||||
|
sorted({rr["role_id"] for rr in roles_resolved.values()})]` + commentaire expliquant le
|
||||||
|
dédoublonnage multi-slots. Artefact régénéré (`build`) → `roles_rbac_utilises` = **3/3 distinct**
|
||||||
|
(`compta-tresorier`, `ventes-conseiller`, `ventes-directeur`).
|
||||||
|
|
||||||
|
**Pourquoi 0 gate ajouté (#5).** Le champ `roles_rbac_utilises` de `financement` n'est lu par
|
||||||
|
**aucun** gate (les blocs `check_readme_claims` qui le lisent visent confotur/commissions/
|
||||||
|
workflow_vente, en **SET** — donc dedup) ni aucun consommateur externe (`grep` = 0). Le champ
|
||||||
|
`counts` n'inclut pas de compte de rôles pour ce module (contrairement aux frères) → **aucune**
|
||||||
|
prose/oracle à réaligner. Le fix corrige la **source** ; un gate distinctness serait redondant
|
||||||
|
avec la convention déjà tenue par les frères et non-régressante ici (verify-before-gate).
|
||||||
|
|
||||||
|
**Non-régression.** `./run_ci.sh` = **33 PASS · 0 FAIL · 0 SKIP** après (byte-repro
|
||||||
|
`check_artifacts` **vert avec le nouvel artefact** ; les **35** tests `crm-financement-bancaire`
|
||||||
|
verts — aucun ne figeait `roles_rbac_utilises`, l.204 teste `role_validation`, non affecté).
|
||||||
|
**2 fichiers édités** (`finlib/builder.py` + `out/MANIFEST.json` régénéré), **0 chiffre inventé**
|
||||||
|
(#6 — 4/3 recomputés), **aucune commande VPS** (#8).
|
||||||
|
|
||||||
## Session `20260806_024430` — VÉRIF indépendante multi-axes (7 axes) → **CLEAN · 0 édition de production**
|
## Session `20260806_024430` — VÉRIF indépendante multi-axes (7 axes) → **CLEAN · 0 édition de production**
|
||||||
|
|
||||||
**Choix de tâche.** `./run_ci.sh` au démarrage = **33 PASS · 0 FAIL · 0 SKIP**, arbre propre,
|
**Choix de tâche.** `./run_ci.sh` au démarrage = **33 PASS · 0 FAIL · 0 SKIP**, arbre propre,
|
||||||
|
|||||||
@@ -86,7 +86,16 @@ def build_bundle(spec: dict, resolver: RoleResolver) -> dict[str, Any]:
|
|||||||
"banniere_lignes": len(gate_spec["banniere"]["lignes"]),
|
"banniere_lignes": len(gate_spec["banniere"]["lignes"]),
|
||||||
"workflow_suivi_etapes": len(gate_spec["workflow_suivi_banque"]),
|
"workflow_suivi_etapes": len(gate_spec["workflow_suivi_banque"]),
|
||||||
},
|
},
|
||||||
"roles_rbac_utilises": [roles_resolved[k] for k in sorted(roles_resolved)],
|
# Ensemble DISTINCT des rôles RBAC réellement utilisés. Plusieurs slots
|
||||||
|
# logiques peuvent pointer le même rôle (ex. conseiller_wag ET
|
||||||
|
# validation_dossier == ventes-conseiller) : on dédoublonne par role_id
|
||||||
|
# et on trie par role_id, comme les modules frères (commissions,
|
||||||
|
# confotur, workflow_vente). Sans ce dédoublonnage, la liste répétait le
|
||||||
|
# rôle et contredisait sa sémantique « rôles utilisés » (ensemble).
|
||||||
|
"roles_rbac_utilises": [
|
||||||
|
{"role_id": rid, "erpnext_role_name": resolver.erpnext_name(rid)}
|
||||||
|
for rid in sorted({rr["role_id"] for rr in roles_resolved.values()})
|
||||||
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -17,14 +17,6 @@
|
|||||||
"workflow_suivi_etapes": 6
|
"workflow_suivi_etapes": 6
|
||||||
},
|
},
|
||||||
"roles_rbac_utilises": [
|
"roles_rbac_utilises": [
|
||||||
{
|
|
||||||
"role_id": "ventes-conseiller",
|
|
||||||
"erpnext_role_name": "OTO Ventes Conseiller"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"role_id": "ventes-directeur",
|
|
||||||
"erpnext_role_name": "OTO Ventes Directeur"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"role_id": "compta-tresorier",
|
"role_id": "compta-tresorier",
|
||||||
"erpnext_role_name": "OTO Compta Trésorier"
|
"erpnext_role_name": "OTO Compta Trésorier"
|
||||||
@@ -32,6 +24,10 @@
|
|||||||
{
|
{
|
||||||
"role_id": "ventes-conseiller",
|
"role_id": "ventes-conseiller",
|
||||||
"erpnext_role_name": "OTO Ventes Conseiller"
|
"erpnext_role_name": "OTO Ventes Conseiller"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"role_id": "ventes-directeur",
|
||||||
|
"erpnext_role_name": "OTO Ventes Directeur"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user