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>
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.
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.
OTO Enterprise OS · Digital Twin Platform (DTP)
Mandat de refactoring 8 semaines ou moins : unifier BIM (Blender/Bonsai/IFC/Speckle),
ERPNext v15 natif, la Console Helios (luxury dark+doré) et les faisabilités 4 volets
niveau 4Big, pilotés par l'agent orchestrateur OTOIA. Vision et contraintes
NON-NÉGOCIABLES : CLAUDE.md.
Point d'entrée de ce dépôt de mandat. Il indexe les artefacts et rapporte l'état courant. Chaque chiffre ci-dessous est sourcé vers un artefact commité (anti-invention
CLAUDE.md#6) ; ce README n'introduit aucune donnée nouvelle.
Navigation
| Zone | Contenu |
|---|---|
CLAUDE.md |
Vision · 10 contraintes NON-NÉGOCIABLES · entités · projets · VPS |
04_roadmap/ROADMAP_8_WEEKS_OR_LESS.md |
Plan 8 sprints · gains d'accélération (~47%) · métriques succès MVP |
AGENTS_EXISTING_ASSETS.md |
Modules OTOV7 réutilisés par agent (source des refactorings) |
PORTAIL_BANCABLES_4BIG.md |
Cadre de bancabilité 4Big |
02_master_prompt/ |
Prompt maître du mandat |
03_agents/ |
Fiches des 13 agents (rôle · livrables · coordination) |
05_deliverables_mvp/ |
Livrables (générateurs déterministes + hand-off out/) |
05_deliverables_mvp/GAP_ANALYSIS_SPRINT1.md |
Audit d'assets + gap analysis (Sprint 1) |
05_activity_log/ |
Journal de session horodaté |
.gitea/workflows/ci.yml · ci/ |
Gate CI Gitea Actions + guards locaux |
tests/ |
Baseline E2E Playwright |
Les 13 agents
Faisabilité & 3D : bim · ifc_speckle ·
rendu · faisabilite ·
publiciste
Plateforme : erpnext_backend ·
frontend_console · crm ·
onapi_legal · seo ·
mobile
Transverses : devops · qa
État courant (sourcé)
- Qualité 4Big : 22/22 modules gated à 100/100 (seuil 95 ·
CLAUDE.md#5), verdictPASS— sourceqa/audit_4big/out/quality_report.json. - Régression : 22 suites gated couvertes bijectivement vs CI ; le compte de tests
agrégé faisant autorité est produit par
qa/regression run(non commité par design) — planqa/regression/out/regression_plan.json. - Recette roadmap : 15 promesses (8 livrables sprint + 7 métriques MVP), 15
in_repoprouvées (chacune traçant ses items hors-périmètre worker · #8 · ex. M5 « app publiée 2 stores »), verdicttrue— sourceqa/acceptance/out/acceptance_matrix.json. - Guards :
ci/guard_constraints.sh+ci/check_docs.shverts.
Périmètre worker (in-repo) vs VPS
Ce dépôt produit des générateurs déterministes et leurs hand-off out/, gatés en CI.
Le déploiement réel (bench migrate, import fixtures, câblage nginx/systemd, builds stores,
indexation, voix Amélie) s'exécute sur le VPS 153.75.250.214 et reste hors périmètre
worker (CLAUDE.md #8). Le plan d'activation ordonné est le run-book
devops/deploy_runbook.
Git — Gitea uniquement
Dépôt de mandat : michel/oto-enterprise-os-dtp sur Gitea (153.75.250.214:3015).
JAMAIS GitHub / GitLab / Bitbucket (CLAUDE.md #2, garde ci/guard_constraints.sh).