[DTP-Worker] Sprint 8 · buffer · Domaine RBAC/roleprofile_gen (2e surface) : le CLASSEMENT métier/technique des 6 Role Profile (colonne « Type » de la table « Profils générés » + prose « 6 profils (5 métier + 1 technique) ») était NON GATÉ. Le bloc RBAC existant ne gatait que le COMPTE Nb rôles par ligne + total bijectif 50 — sa colonne « Type » était un WILDCARD ([^|]*), et le split métier/technique en prose n'était gaté nulle part. Preuve reproduite : classer le portail technique plateforme en « métier » dans le README → check_readme_claims EXIT 0 (le gate ne voyait que 6==6). Ce classement est DATA-DERIVED : le flag booléen metier par profil de MANIFEST.profiles + le split = counts.portails_metier(5)/portails_techniques(1)/role_profiles(6), MANIFEST recomputé du contrat rbac_50_roles.json à chaque build (byte-gaté par check_artifacts). Un « métier vs technique » faux détournerait le Sprint 4 (« 5 portails rôle » = les 5 métier · plateforme = console technique). PIÈGE : check_artifacts ne prouve QUE MANIFEST==build (byte-for-byte) et la boucle Nb rôles existante n'itère que MANIFEST→README (capte le MANQUANT) — donc RENVERSER un flag dans la prose · MENTIR sur le split · AJOUTER une ligne fantôme d'un profil inventé restait « vert trompeur » qu'aucune suite tests/ (qui teste des FONCTIONS de builder, pas la prose du README) n'attrape → gate étendu (bloc roleprofile de ci/check_readme_claims.sh) : (1) colonne « Type » recomputée du flag metier, exigée EXACTE par profil (fin du wildcard) ; (2) prose « N profils (X métier + Y technique) » == comptes MANIFEST ; (3) identité d'ensemble — nombre de lignes de profil de la table == |profiles| (aucune ligne FANTÔME absente du contrat ; complète le sens MANIFEST→README) ; (4) cohérences croisées mordant un MANIFEST INTERNEMENT incohérent : portails_metier + portails_techniques == role_profiles == |profiles| ET ces comptes recomptent les flags metier réels. 5 morsures vérifiées : README classe plateforme métier (technique→métier) · README classe ventes technique (métier→technique) · prose split 5→4 métier (6/4/1 MAIS 6/5/1) · ligne FANTÔME OTO Portail Fantome (7≠6) · MANIFEST portails_metier 5→6 sans toucher aux flags (incohérence interne, flags réels=5) ; restauré = green : 6 Types == MANIFEST · split 6/5/1 · 6 lignes · comptes cohérents · exit 0. État courant : aucun classement périmé (anti-invention #6, rien à réécrire) — le défaut est la surface ungated. ci/README.md (table + détail « 2e surface roleprofile_gen ») mis à jour · 7 gates re-verts.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+13
-2
@@ -20,7 +20,7 @@ et manuellement (`workflow_dispatch`). Jobs statiques (+ une suite `unittest` pa
|
||||
| `check-artifacts` | `ci/check_artifacts.sh` | Reproductibilité : chaque `out/*.json` versionné == build frais | ✅ oui |
|
||||
| `check-regression` | `ci/check_regression.sh` | Fraîcheur : `qa/regression/out/regression_run.json` (`run`) == run frais + verdict PASS | ✅ oui |
|
||||
| `check-ci-integrity` | `ci/check_ci_integrity.sh` | Intégrité du câblage : `gate.needs` == tous les jobs non-manuels · chaque `ci/*.sh` câblé au gate | ✅ oui |
|
||||
| `check-readme-claims` | `ci/check_readme_claims.sh` | Intégrité des chiffres des docs d'entrée : chaque nombre de `README.md` « État courant », de la fiche QA « Verdict agrégé » **et** de la colonne « Tests » par suite des tables de fiches **et** des agrégats en prose (Total CRM / RBAC / e-CF) **et** des comptes par workspace des portails (cartes/liens/rôles, ×2 docs) **et** des comptes RBAC des 3 volets (table Nb rôles/profil, ligne agrégée apply_plan, ventilation userperm) **et** des comptes de mots-clés SEO (total + fr/en/es, ×2 docs) **et** du pipeline vente CRM (états/transitions, ×2 docs + énumération des transitions à séparation des pouvoirs `{action | allow_self_approval=0}` recomputée de `workflow.json`) **et** de l'app mobile Expo (onglets/rôles/langues/identifiants a_confirmer + énumération ordonnée des onglets recomputée de `role_navigation`, bijection onglet⇔portail) **et** du DocType CONFOTUR (champs/données/sections/rôles/évènements de dépôt, ×2 docs) **et** de l'audit 5D (contrôles/dimensions ×2 docs + ventilation verdict pass/fail/à-confirmer + énumération des open items `control→dimension→propriétaire` recomputée de `audit_report.open_items`) **et** du run-book de déploiement VPS (phases ×2 dans la fiche devops + confirmations préalables count & énumération dans le README) **et** du run-sheet de démo (nombre de modules cités dans le diagramme du README) **et** du montage Chat OTOIA par portail (`Custom Block`/configs runtime/portails, tous = 5 aujourd'hui, ×2 docs) **et** du module de recette `qa/acceptance` (couple livrables de sprint + métriques succès MVP, ×2 docs de module au-delà du README d'entrée) **et** du barème de l'auditeur 4Big (nombre de critères en prose + poids par critère de la table + « generator (N critères) », recomputés de `quality_report.criteria`) **et** de la carte de renormalisation par archétype de l'auditeur 4Big (critères EXCLUS de `data_room`/`parser`/`contract`, recomputés des `checks` par archétype de `quality_report.modules`) **et** du contrat de format de l'e-NCF fiscal (`E + tipoeCF(2) + secuencia(10) = 13` : préfixe/longueurs des segments/longueur totale, ×3 README + fiche `erpnext_backend`, recomputés du bloc `e_ncf` d'`ecf_plan.json` + cohérences croisées `1+tipo+seq==longueur` & `|regex digits|==tipo+seq`) **et** de la cross-cohérence du barème de commissions `crm/commissions` (états brouillon exclus recomputés de `{doc_status=0}` de `workflow.json` + champs de base recomputés de `{base_field}` de `commission_plan.json` + invariant 3 « commissionne seulement des états soumis ») **et** du catalogue RBAC `rbac/fixtures_gen` (DocTypes `custom` à créer énumérés == `MANIFEST.custom_doctypes_a_confirmer` + séparation des pouvoirs : le rôle unique porteur de `set_user_permissions` == `custom_docperm.json`) **et** de la composition du graphe schema.org SEO (les `@type` du `@graph` — `Organization` racine + une `Residence` par projet — recomputés de `seo_schema_org.json` + bijection listing⇔projet & absence d'`offers`) **et** de la carte hreflang SEO (les langues de contenu `alternate` `FR/EN/ES` + `x-default` recomputées de `seo_hreflang.json` + cohérences croisées : carte uniforme sur toutes les pages · `x-default` présent partout · langue par défaut ∈ langues de contenu · `x-default`.href == `canonical` == href de la langue par défaut) **et** du catalogue de projets du DocType `crm/dossier_vente` (le Select `projet` — les 9 projets `P01..P09` avec libellés — **ancré sur** la section « ## Projets » de `CLAUDE.md`, recomputé de CLAUDE.md : ensemble + ordre == options du DocType byte-gaté, plage `P01..P09` + mot d'ancrage dans le README, catalogue contigu/sans-doublon en bonus) **et** du catalogue des DocTypes `custom` à créer du portail `frontend/portails` (2e surface : le §hand-off VPS énumère `CONFOTUR Application`/`Faisabilité`/`Publiciste Log` == `MANIFEST.doctypes_custom_a_creer` recomputé, set-diff normalisé + cohérences croisées : catalogue trié/sans-doublon/non-vide · égal à l'UNION des `doctypes_custom` par workspace) == artefact cité (#6) | ✅ oui |
|
||||
| `check-readme-claims` | `ci/check_readme_claims.sh` | Intégrité des chiffres des docs d'entrée : chaque nombre de `README.md` « État courant », de la fiche QA « Verdict agrégé » **et** de la colonne « Tests » par suite des tables de fiches **et** des agrégats en prose (Total CRM / RBAC / e-CF) **et** des comptes par workspace des portails (cartes/liens/rôles, ×2 docs) **et** des comptes RBAC des 3 volets (table Nb rôles/profil, ligne agrégée apply_plan, ventilation userperm) **et** des comptes de mots-clés SEO (total + fr/en/es, ×2 docs) **et** du pipeline vente CRM (états/transitions, ×2 docs + énumération des transitions à séparation des pouvoirs `{action | allow_self_approval=0}` recomputée de `workflow.json`) **et** de l'app mobile Expo (onglets/rôles/langues/identifiants a_confirmer + énumération ordonnée des onglets recomputée de `role_navigation`, bijection onglet⇔portail) **et** du DocType CONFOTUR (champs/données/sections/rôles/évènements de dépôt, ×2 docs) **et** de l'audit 5D (contrôles/dimensions ×2 docs + ventilation verdict pass/fail/à-confirmer + énumération des open items `control→dimension→propriétaire` recomputée de `audit_report.open_items`) **et** du run-book de déploiement VPS (phases ×2 dans la fiche devops + confirmations préalables count & énumération dans le README) **et** du run-sheet de démo (nombre de modules cités dans le diagramme du README) **et** du montage Chat OTOIA par portail (`Custom Block`/configs runtime/portails, tous = 5 aujourd'hui, ×2 docs) **et** du module de recette `qa/acceptance` (couple livrables de sprint + métriques succès MVP, ×2 docs de module au-delà du README d'entrée) **et** du barème de l'auditeur 4Big (nombre de critères en prose + poids par critère de la table + « generator (N critères) », recomputés de `quality_report.criteria`) **et** de la carte de renormalisation par archétype de l'auditeur 4Big (critères EXCLUS de `data_room`/`parser`/`contract`, recomputés des `checks` par archétype de `quality_report.modules`) **et** du contrat de format de l'e-NCF fiscal (`E + tipoeCF(2) + secuencia(10) = 13` : préfixe/longueurs des segments/longueur totale, ×3 README + fiche `erpnext_backend`, recomputés du bloc `e_ncf` d'`ecf_plan.json` + cohérences croisées `1+tipo+seq==longueur` & `|regex digits|==tipo+seq`) **et** de la cross-cohérence du barème de commissions `crm/commissions` (états brouillon exclus recomputés de `{doc_status=0}` de `workflow.json` + champs de base recomputés de `{base_field}` de `commission_plan.json` + invariant 3 « commissionne seulement des états soumis ») **et** du catalogue RBAC `rbac/fixtures_gen` (DocTypes `custom` à créer énumérés == `MANIFEST.custom_doctypes_a_confirmer` + séparation des pouvoirs : le rôle unique porteur de `set_user_permissions` == `custom_docperm.json`) **et** de la composition du graphe schema.org SEO (les `@type` du `@graph` — `Organization` racine + une `Residence` par projet — recomputés de `seo_schema_org.json` + bijection listing⇔projet & absence d'`offers`) **et** de la carte hreflang SEO (les langues de contenu `alternate` `FR/EN/ES` + `x-default` recomputées de `seo_hreflang.json` + cohérences croisées : carte uniforme sur toutes les pages · `x-default` présent partout · langue par défaut ∈ langues de contenu · `x-default`.href == `canonical` == href de la langue par défaut) **et** du catalogue de projets du DocType `crm/dossier_vente` (le Select `projet` — les 9 projets `P01..P09` avec libellés — **ancré sur** la section « ## Projets » de `CLAUDE.md`, recomputé de CLAUDE.md : ensemble + ordre == options du DocType byte-gaté, plage `P01..P09` + mot d'ancrage dans le README, catalogue contigu/sans-doublon en bonus) **et** du catalogue des DocTypes `custom` à créer du portail `frontend/portails` (2e surface : le §hand-off VPS énumère `CONFOTUR Application`/`Faisabilité`/`Publiciste Log` == `MANIFEST.doctypes_custom_a_creer` recomputé, set-diff normalisé + cohérences croisées : catalogue trié/sans-doublon/non-vide · égal à l'UNION des `doctypes_custom` par workspace) **et** du classement métier/technique des `Role Profile` de `rbac/roleprofile_gen` (2e surface : la colonne « Type » de la table — auparavant un WILDCARD — recompute le flag `metier` par profil de `MANIFEST.profiles` + prose « N profils (X métier + Y technique) » == `counts.role_profiles/portails_metier/portails_techniques` + identité d'ensemble : lignes de profil de la table == `|profiles|` (aucun profil fantôme) + cohérences croisées : `portails_metier + portails_techniques == role_profiles` et recomptent les flags réels) == artefact cité (#6) | ✅ oui |
|
||||
| `gate` | — | Agrégat vert = gate qualité 4Big franchi | ✅ oui |
|
||||
|
||||
Aucune dépendance réseau/marketplace hors `actions/checkout`. Tout tourne avec
|
||||
@@ -172,7 +172,18 @@ tous les volets en une phrase) et la ventilation « 28 `entite` · 16 `groupe`
|
||||
`own` · 4 `equipe` ». Chaque nombre est recomputé depuis le `out/MANIFEST.json`
|
||||
du volet (recalculé du contrat `rbac_50_roles.json` à chaque build, byte-gaté par
|
||||
`check_artifacts`) : ajouter un rôle/DocType ferait dériver **les trois** READMEs
|
||||
en silence sinon.
|
||||
en silence sinon. **2ᵉ surface `rbac/roleprofile_gen`** : la table « Profils
|
||||
générés » ne gatait que le **compte** `Nb rôles` par ligne — sa colonne « Type »
|
||||
(`métier`/`technique`) était un **wildcard** (`[^|]*`), donc un portail technique
|
||||
classé « métier » (ou l'inverse) passait **vert**. On recompute le classement
|
||||
depuis le flag booléen `metier` de `MANIFEST.profiles` et on exige la colonne
|
||||
« Type » **exacte** par profil, on gate la prose « **6 profils** (5 métier + 1
|
||||
technique) » contre `counts.role_profiles/portails_metier/portails_techniques`, on
|
||||
exige que le **nombre de lignes de profil** de la table == `|profiles|` (aucune
|
||||
ligne fantôme d'un profil inventé absent du contrat), et en bonus deux
|
||||
cohérences croisées qui mordent un MANIFEST **internement** incohérent :
|
||||
`portails_metier + portails_techniques == role_profiles` **et** ces comptes
|
||||
recomptent les flags `metier` réels des profils.
|
||||
|
||||
Même classe enfin côté **SEO** : le total et la ventilation par langue des
|
||||
mots-clés (« **258** mots-clés (fr=87 · en=87 · es=84) ») étaient transcrits **à
|
||||
|
||||
Reference in New Issue
Block a user