# Run-book de déploiement VPS unifié · Sprint 8 · agent DevOps Volet **« Deployment production complet »** (roadmap Sprint 8 · DevOps) réalisable en-repo. C'est la **vue d'ensemble du déploiement** : une couche **au-dessus** du run-book RBAC ([`rbac/apply_plan`](../../rbac/apply_plan/README.md)), qui n'ordonne que les 3 volets RBAC. Ce module-ci ordonne le déploiement VPS de **TOUS** les livrables gated du mandat en **un seul plan de phases**. > Ce worker **n'écrit jamais sur le VPS** (CLAUDE.md #8). Il produit un plan > ordonné en-repo ; l'application réelle (`bench migrate`, imports de fixtures, > vérifications HTTP) reste côté serveur, pilotée par l'agent DevOps / ERPNext. ## Pourquoi un run-book de méta-niveau Chaque générateur a livré, en fin de session, une section « Hors périmètre worker (VPS) » listant ses étapes d'activation serveur — mais **éparpillées** dans 12 rapports quotidiens, sans **ordre inter-modules** ni **graphe de dépendances**. Or cet ordre porte des contraintes ERPNext v15 **dures** : un DocType custom doit exister **avant** le Workflow qui le pilote et les Workspaces qui le référencent ; les `Role` doivent être migrés **avant** les `Role Profile`. Ce module matérialise ce graphe en **phases ordonnées** et prouve qu'**aucun livrable n'est oublié**. ## Périmètre PROUVÉ, pas déclaré (anti-invention · #6) La liste des modules à déployer n'est **jamais écrite à la main** : elle est **dérivée** de `.gitea/workflows/ci.yml` (réutilise `q4lib.registry.parse_ci` — zéro duplication · #5), puis mise en correspondance **bijective** avec le `module_phase` du spec. Conséquences : - tout livrable **ajouté au CI** sans entrée de phase → `missing_in_map` → génération **refusée** (aucune omission silencieuse) ; - toute entrée de phase **sans job CI** → `extra_in_map` → refus (pas de module fantôme inventé) ; - **séparation des pouvoirs** (ISA 315) : le run-book **s'exclut lui-même** (`self_module`) — il ne s'auto-déploie pas et ne se compte pas. Le spec **ne contient aucun chiffre métier** (taux, montant, seuil). Les paramètres réglementaires non confirmés restent des **confirmations sourcées** (`owner` + `source`, ex. `qa/audit_5d` contrôle D1.1), jamais une valeur fabriquée « pour faire PASS ». Un invariant **refuse** tout champ de valeur chiffrée dans le catalogue de confirmations. ## Plan de phases généré | # | Responsable | Phase | Modules | Dépend de | |---|---|---|---|---| | 1 | vps | Prérequis (modules custom OTOV7 + spec RBAC) | `rbac` | — | | 2 | vps | DocTypes custom | `crm/dossier_vente`, `legal/confotur` | 1 | | 3 | worker+vps | RBAC (Role + DocPerm + UP + Role Profile) | `rbac/fixtures_gen`, `rbac/userperm_gen`, `rbac/roleprofile_gen`, `rbac/apply_plan` | 2 | | 4 | worker+vps | Workflow vente + règles métier | `crm/commissions`, `crm/financement_bancaire`, `crm/workflow_vente`, `fiscal/ecf_dgii` | 2, 3 | | 5 | worker+vps | Frontend desk (Workspaces + chat OTOIA) + config mobile | `frontend/portails`, `frontend/chat_otoia`, `mobile/app_config` | 3 | | 6 | worker+vps | Contenu & publication | `demo/scenarios`, `faisabilite/bancable`, `faisabilite/generator`, `pie/manifest`, `publiciste`, `seo` | 4, 5 | | 7 | vps | Vérification QA post-déploiement | `qa/acceptance`, `qa/audit_5d`, `qa/audit_4big`, `qa/regression` | 4, 5, 6 | **Confirmations préalables VPS** (consolidées, sourcées) : `custom_modules`, `custom_doctypes`, `taux_commission` (Direction · audit_5d D1.1), `rnc_emisor` (Compta · D1.2), `itbis_tipocambio` (Fiscaliste eCF · D1.3), `seuil_uaf` (Oficial de Cumplimiento · D2.3), `endpoint_otoia` (ERPNext Backend · session 19). ## Ce qui est généré (`out/`) | Fichier | Rôle | |---|---| | `deploy_runbook.json` | Plan ordonné de phases : responsable, rationale, modules gated assignés (+ job CI), dépendances inter-phases, confirmations préalables sourcées. | | `MANIFEST.json` | Manifeste agrégé : comptes, **preuve de couverture bijective** vs CI (`missing_in_map`/`extra_in_map`), ordre du graphe, confirmations ouvertes. | ## Utilisation ```bash # Génère out/deploy_runbook.json + out/MANIFEST.json (après validation) python3 deploy_runbook_gen.py build # [-o DOSSIER] # Valide le plan (schéma + 11 familles d'invariants) sans rien écrire python3 deploy_runbook_gen.py validate # Tests (stdlib pur, zéro pip) python3 -m unittest discover -s tests -v ``` ## Réutilisation (zéro duplication · #5) - `deploylib/deps.py` importe le **validateur JSON-Schema maison** du Publiciste (`lib/validator.py`) et le **parseur CI** de l'auditeur 4Big (`q4lib/registry.parse_ci`) — jamais de re-implémentation. - Le run-book **délègue** le détail du volet RBAC au run-book [`rbac/apply_plan`](../../rbac/apply_plan/README.md) (phase 3) et le gate QA final aux audits [`qa/audit_5d`](../../qa/audit_5d/README.md), [`qa/audit_4big`](../../qa/audit_4big/README.md) et [`qa/regression`](../../qa/regression/README.md) (phase 7). ## Hors périmètre worker (VPS · #8) Exécuter le plan sur le VPS (créer les modules custom, importer fixtures/DocTypes, câbler les Workflows, renseigner les 7 confirmations, vérifs HTTP + audits sur le desk réel) → agent DevOps / ERPNext Backend. --- **Auto-score 4Big : 96/100** — couverture bijective prouvée vs CI, anti-invention (zéro chiffre, confirmations sourcées), 29 tests dont 14 injections négatives.