
4501–4510 — Certification Program Object
Une certification ne doit plus être seulement un examen.
Elle devient un PROGRAMME DE CERTIFICATION contenant :
métier
niveau
référentiel
conditions d’entrée
prérequis
épreuves requises
seuils
compétences critiques
règles Jury
validité
renouvellement
4511–4520 — Certification Path
Exemple :
Admission
→ Diagnostic
→ Formation
→ Simulation
→ Examen écrit
→ Mission
→ Oral
→ Jury
→ Certification
Toutes les certifications n’utilisent pas forcément toutes ces étapes.
4521–4530 — Prerequisite Engine
Une épreuve peut exiger :
formation terminée
score minimum antérieur
certificat encore valide
module obligatoire
autorisation entreprise
pièce administrative validée
Le moteur bloque automatiquement l’accès si une condition obligatoire manque.
4531–4540 — Eligibility Snapshot
Au moment de l’inscription :
MZA enregistre pourquoi le candidat était éligible.
Très utile si une règle change plus tard.
4541–4550 — Campaign Rules
Une campagne peut avoir :
date ouverture
date fermeture
nombre de tentatives
délai entre tentatives
centre autorisé
langues
niveaux
Jury
conditions particulières
4551–4560 — Attempt Policy
Exemple :
Tentative 1.
Échec.
Nouvelle tentative uniquement après :
remédiation
ou
délai
selon le règlement.
Pas de logique improvisée.
4561–4570 — Retake Blueprint
Une réévaluation ne doit pas forcément reprendre exactement le même examen.
MZA crée une variante :
équivalente
mais suffisamment différente.
4571–4580 — Targeted Retake
Si seul un bloc est insuffisant et si les règles le permettent :
RÉÉVALUATION CIBLÉE
au lieu de refaire tout le parcours.
4581–4590 — Certification Dependency
Certaines certifications peuvent dépendre d’autres :
MASTER nécessite EXPERT valide.
Le moteur gère la chaîne.
4591–4600 — Skill Dependency Graph
Même logique pour les compétences :
Diagnostic
→ Décision
→ Leadership sous charge
Une compétence supérieure peut exiger des fondations démontrées.
4601–4610 — Competency Architecture
Je structurerais les compétences en quatre couches :
CORE
fondamentaux.
OPERATIONAL
application métier.
ADVANCED
gestion complexe.
COMMAND
pilotage et stratégie.
4611–4620 — Evidence Reuse
Une preuve valide issue d’une épreuve peut éventuellement contribuer à plusieurs certifications, uniquement si les règles le permettent.
Cela évite de faire repasser inutilement la même compétence.
4621–4630 — Evidence Freshness
Mais cette preuve possède :
date
contexte
niveau
validité
Une preuve trop ancienne peut ne plus suffire.
4631–4640 — Evidence Portability
Le candidat peut conserver dans son Skill Passport :
preuves certifiées résumées
sans exposer les questions sécurisées.
4641–4650 — Employer Verification
Une entreprise peut vérifier :
certification
niveau
statut
validité
sans accéder au dossier complet sauf autorisation prévue.
4651–4660 — Organization Tenant
Pour grandir, MZA devrait prévoir une logique multi-organisation :
Entreprise A
Entreprise B
École C
Centre D
Chacune voit uniquement ses espaces autorisés.
4661–4670 — Tenant Isolation
Chaque organisation possède :
utilisateurs
campagnes
reporting
cohortes
paramètres
avec séparation stricte.
4671–4680 — Shared Certification Core
Mais les organisations peuvent utiliser un même programme de certification central MZA.
On évite de dupliquer les référentiels partout.
4681–4690 — Private Certification
Une entreprise peut également posséder :
CERTIFICATION INTERNE
accessible uniquement à son personnel.
4691–4700 — White Label
À terme :
logo entreprise,
sous-domaine,
cockpit personnalisé,
tout en gardant le moteur MZA.
4701–4710 — Assessment Center Mode
MZA peut devenir un centre complet :
écrit
simulation
mise en situation
oral
Jury
rapport
dans une seule campagne.
4711–4720 — Multi-Assessor
Une même mission peut être observée par :
expert métier
Jury
qualité
chacun sur son périmètre.
4721–4730 — Assessor Rubric
Chaque évaluateur utilise une grille structurée.
Pas de notes libres non comparables.
4731–4740 — Assessor Calibration
Avant une grande campagne :
plusieurs évaluateurs corrigent les mêmes exemples.
MZA mesure les divergences.
4741–4750 — Jury Calibration Session
Le système peut présenter :
10 cas étalons
aux jurés.
Objectif :
aligner l’interprétation des critères.
4751–4760 — Inter-Rater Reliability
Côté qualité, MZA suit :
à quel point les jurés convergent.
Si certains critères génèrent trop de divergence :
ils doivent être revus.
4761–4770 — Rubric Drift
Un Jury peut progressivement devenir plus sévère ou plus permissif.
MZA peut signaler une dérive statistique pour revue.
4771–4780 — Assessor Load
Le système répartit :
nombre de dossiers
complexité
priorité
afin d’éviter qu’un même juré soit surchargé.
4781–4790 — Conflict Management
Si un juré ne doit pas évaluer un candidat pour une raison organisationnelle déclarée :
MZA permet de l’exclure de l’affectation.
4791–4800 — Jury Assignment Engine
Le moteur peut tenir compte de :
expertise
niveau
langue
charge
disponibilité
conflits déclarés.
4801–4810 — Exam Center Management
Pour les sessions physiques :
centre
salle
poste
superviseur
créneau
capacité
4811–4820 — Seat Allocation
MZA attribue :
candidat
→ session
→ poste
avec règles anti-conflit si besoin.
4821–4830 — Check-In
Avant démarrage :
identité vérifiée selon procédure
session
poste
heure
conditions techniques
Puis ouverture de l’examen.
4831–4840 — Proctoring Boundaries
Je resterais prudent :
MZA peut enregistrer des événements de session autorisés,
mais ne doit pas transformer chaque comportement inhabituel en accusation.
Les anomalies vont vers :
REVUE HUMAINE
4841–4850 — Session Integrity Timeline
Le responsable voit :
connexion
déconnexion
reprise
soumission
incident
intervention autorisée
4851–4860 — Supervisor Intervention
Un superviseur peut :
mettre en pause
ajouter du temps autorisé
consigner incident
reprendre session
Mais toutes les actions sont tracées.
4861–4870 — Emergency Session Freeze
Incident majeur :
GELER LA SALLE
Toutes les sessions peuvent être suspendues selon procédure.
4871–4880 — Resume Protocol
Après résolution :
MZA applique la politique définie :
reprendre
replanifier
annuler bloc
revoir au Jury
4881–4890 — Technical Neutrality
Un candidat ne doit pas être pénalisé pour un incident technique confirmé non imputable selon la procédure.
Le système sépare :
performance
de
incident technique.
4891–4900 — Session Forensics
Pour chaque incident :
heure
poste
requête
réponse serveur
action superviseur
impact
Sans basculer dans une surveillance excessive.
4901–4910 — Notification Center
MZA gère :
convocations
rappels
résultats
renouvellements
Jury
incidents
actions requises
4911–4920 — Notification Rules
Exemple :
J-7.
J-1.
H-2.
Puis :
certification à renouveler dans 60 jours.
4921–4930 — Escalation Rules
Un dossier Jury non traité depuis X jours :
→ rappel.
Puis :
→ responsable qualité.
Les délais restent configurables.
4931–4940 — SLA Dashboard
Direction voit :
temps moyen correction
dossiers en retard
certificats en attente
incidents ouverts
appels
4941–4950 — Operational KPIs
Je suivrais au minimum :
taux de complétion
taux de validation
temps d’examen
temps Jury
incidents techniques
items contestés
reprises
certificats délivrés
4951–4960 — Quality KPIs
Mais aussi :
items suspendus
items obsolètes
référentiels à revoir
divergence Jury
couverture des compétences
niveau de preuve
4961–4970 — No Vanity Metrics
Éviter des statistiques décoratives.
Chaque KPI doit répondre à :
Quelle décision prend-on grâce à lui ?
4971–4980 — Actionable Dashboard
Cliquer :
12 items à risque
ouvre directement :
liste
cause
statistiques
action suggérée
4981–4990 — Quality Work Queue
Une seule file centrale :
référentiel expirant
question ambiguë
traduction à valider
Jury en désaccord
incident
appel
certificat bloqué
4991–5000 — Priority Engine
Chaque tâche qualité possède :
criticité
urgence
impact
nombre de candidats concernés
5001–5010 — Release Management
Chaque version MZA Exam OS :
DEV
→ TEST
→ STAGING
→ PRODUCTION
Jamais modification directe du moteur pendant une campagne majeure.
5011–5020 — Feature Flags
Une fonction nouvelle peut être activée :
pour admins uniquement
puis
pilote
puis
10 %
puis
tous.
5021–5030 — Safe Migration
Chaque mise à jour DB :
version
migration
vérification
rollback prévu
5031–5040 — Health Check
Après mise à jour :
MZA teste automatiquement :
DB
API
authentification
exam runtime
autosave
Jury
certificat
5041–5050 — Compatibility Matrix
Le système documente :
WordPress
PHP
MySQL/MariaDB
navigateurs supportés
5051–5060 — Plugin Isolation
Je déconseille absolument que le moteur critique dépende de dizaines de plugins tiers pour fonctionner.
Le cœur certifiant doit rester aussi autonome que possible.
5061–5070 — Integration Layer
Les autres systèmes passent par une couche d’intégration :
LMS
CRM
RH
paiement
BI
5071–5080 — REST API
Exemples :
/certifications
/candidates
/campaigns
/attempts
/skills
/certificates
avec contrôle d’accès strict.
5081–5090 — Webhook Layer
À terme, MZA peut émettre :
candidate.enrolled
exam.started
exam.completed
jury.required
certificate.issued
certificate.expiring
5091–5100 — External HRIS
Une grande entreprise pourrait synchroniser :
matricule interne
poste
direction
manager
parcours
sans recopier manuellement les effectifs.
5101–5110 — SSO
Pour les grands comptes :
connexion unique d’entreprise.
Le candidat accède à MZA avec son identité professionnelle.
5111–5120 — SCIM-Like Provisioning
À terme :
création,
désactivation,
mise à jour
des utilisateurs depuis le système entreprise.
5121–5130 — Data Import Center
Pour les structures sans API :
CSV
XLSX
avec assistant de mapping :
Colonne A = matricule
B = nom
C = métier
D = niveau.
5131–5140 — Import Validation
Avant import :
doublons
champs manquants
format invalide
métier inconnu
email dupliqué
5141–5150 — Dry Run
Bouton :
SIMULER L’IMPORT
MZA montre ce qui se passerait sans modifier la base.
5151–5160 — Bulk Operations
Admin peut :
inscrire 500 personnes
affecter certification
changer cohorte
envoyer convocation
sans travailler candidat par candidat.
5161–5170 — Cohort Rules
Une cohorte peut être dynamique :
tous les chefs d’escale niveau Expert avec certificat expirant avant le 31/12.
5171–5180 — Smart Campaign Builder
Admin choisit :
population
certification
fenêtre
centres
Jury
Puis :
GÉNÉRER CAMPAGNE
5181–5190 — Capacity Planner
MZA calcule :
candidats
places
créneaux
jurés
durées
postes
et signale les goulets.
5191–5200 — Jury Capacity Forecast
Exemple :
240 candidats.
15 % nécessitent oral.
Durée moyenne 20 min.
MZA estime la charge Jury et aide à planifier.
5201–5210 — Exam Center Forecast
Même logique :
nombre de salles
postes
sessions
superviseurs
5211–5220 — Candidate Scheduling
Le candidat peut choisir parmi les créneaux autorisés.
Ou l’entreprise peut imposer le calendrier.
5221–5230 — No-Show Management
Statuts :
CONFIRMÉ
PRÉSENT
ABSENT
EXCUSÉ
REPLANIFIÉ
5231–5240 — Rescheduling Rules
Replanifier selon :
places
règlement
délai
motif
5241–5250 — Waiting List
Session pleine :
LISTE D’ATTENTE
Si place libérée :
réaffectation contrôlée.
5251–5260 — Command Center Enterprise
Pour une campagne nationale :
EN DIRECT
1 284 inscrits
318 actifs
642 terminés
27 incidents
94 Jury
203 certifiés
5261–5270 — Drill Down
Direction :
Maroc
→ Région
→ Centre
→ Session
→ Cohorte
→ candidat selon permissions.
5271–5280 — Geographic Comparison
Comparer des sites peut être utile,
mais il faut distinguer :
différences réelles
de
différences de population / difficulté / contexte.
Pas de classement simpliste.
5281–5290 — Cohort Normalization
Les analytics peuvent contrôler :
forme d’examen
niveau
métier
période
avant comparaison.
5291–5300 — Enterprise Skills Radar
Vue globale :
sécurité
service
leadership
digital
recovery
coordination
par population.
5301–5310 — Workforce Readiness
On peut construire :
READINESS INDEX
uniquement à partir de compétences effectivement évaluées et de règles explicites.
Pas de score mystérieux.
5311–5320 — Role Readiness
Exemple :
Candidat possède :
9/10 compétences obligatoires
mais la dixième est critique.
Donc :
NOT READY
même avec une moyenne globale élevée.
5321–5330 — Succession Support
Pour les métiers internes, MZA peut aider à identifier les personnes ayant démontré les compétences nécessaires pour un niveau supérieur.
Mais ce n’est pas une décision automatique de promotion.
5331–5340 — Development Pool
Statuts possibles :
READY
NEAR READY
DEVELOPMENT REQUIRED
basés sur critères définis.
5341–5350 — Talent Evidence
La recommandation montre :
compétence manquante
preuve
formation suggérée
plutôt qu’un simple classement.
5351–5360 — Training Demand Forecast
Avec des milliers de collaborateurs :
MZA peut prévoir le volume de formations nécessaires à partir de :
gaps mesurés
échéances
effectifs
5361–5370 — Capacity Matching
Puis comparer avec :
formateurs disponibles
salles
sessions
budget
5371–5380 — Annual Training Plan
MZA génère un projet :
T1
T2
T3
T4
par métier et priorité.
5381–5390 — Scenario Planning
Direction peut tester :
budget -20 %
ou
effectifs +30 %
et observer quelles priorités de formation restent couvertes.
5391–5400 — Decision Support, Not Autopilot
Le système propose.
Le responsable décide.
C’est une règle que je garderais partout dans MZA.
5401–5410 — Data Retention
Chaque type de donnée possède une politique :
session
réponses
audit
certificat
logs techniques
analytics
Pas tout conservé éternellement par défaut.
5411–5420 — Data Minimization
Ne collecter que ce qui sert :
évaluation
certification
administration
sécurité légitime
5421–5430 — Access Logging
Lorsqu’un administrateur consulte des données sensibles :
MZA peut tracer l’accès selon les besoins du programme.
5431–5440 — Least Privilege
Un responsable entreprise ne doit pas nécessairement pouvoir :
voir les bonnes réponses
modifier un score
éditer le référentiel
5441–5450 — Separation of Duties
Exemple :
celui qui écrit une question ne devrait pas automatiquement pouvoir la publier en certification.
5451–5460 — Four-Eyes Principle
Pour les actions sensibles :
validation par une seconde personne.
Exemple :
activation d’un référentiel critique.
5461–5470 — Sensitive Actions
Double contrôle possible sur :
modification seuil
annulation résultat
révocation certificat
publication banque certifiante
5471–5480 — Immutable Audit
Les changements critiques doivent conserver une trace inviolable au niveau applicatif, avec protections adaptées à l’infrastructure.
5481–5490 — Security Events
MZA peut surveiller :
échecs connexion
permissions refusées
tentatives d’accès interdit
modifications critiques
pour revue sécurité.
5491–5500 — API Security
Les API doivent appliquer :
authentification
autorisation
validation
limites de débit
journalisation
révocation des accès
5501–5510 — Certificate Anti-Forgery
Chaque certificat :
ID unique
URL vérification
QR
signature/empreinte logique côté système
5511–5520 — Verification History
Si le statut change :
VALID → REVOKED
la page de vérification reflète le statut courant sans modifier l’historique administratif.
5521–5530 — Fraudulent Certificate Alert
Si quelqu’un présente un numéro inexistant :
CERTIFICAT NON TROUVÉ
Pas de données supplémentaires permettant d’explorer la base.
5531–5540 — Audit Export
Pour un audit autorisé :
MZA peut produire un dossier comprenant :
programme
référentiel
blueprint
épreuve
Jury
preuve
certificat
5541–5550 — Quality Report
Rapport périodique :
nombre certifications
taux d’incident
items retirés
référentiels actualisés
appels
accord Jury
5551–5560 — Governance Calendar
MZA peut suivre les échéances :
revue annuelle
référentiel
calibration Jury
test de charge
backup restore test
audit sécurité
5561–5570 — Certification Health Score
Pour chaque programme :
référentiel à jour
banque suffisante
exposition maîtrisée
Jury calibré
incidents bas
preuves solides
5571–5580 — Program Suspension Gate
Si une condition critique devient invalide :
PROGRAMME SUSPENDU
jusqu’à revue.
Par exemple référentiel majeur retiré.
5581–5590 — Program Retirement
Une certification ancienne :
ACTIVE
→ LEGACY
→ RETIRED
Les anciens certificats restent historisés selon les règles applicables.
5591–5600 — Migration Path
Une ancienne certification peut être reliée à une nouvelle :
v2 → v3
avec règles de transition.
5601–5610 — MZA CONTROL TOWER
Je créerais finalement un module central :
CONTROL TOWER
avec 6 vues :
EXAMS
CANDIDATES
JURY
QUALITY
CERTIFICATES
SYSTEM HEALTH
5611–5620 — Morning Brief
Chaque matin, Control Tower peut afficher :
sessions du jour
incidents ouverts
Jury en retard
certificats à émettre
référentiels expirant
5621–5630 — Exception-First UI
Ne pas montrer 10 000 lignes.
Afficher d’abord :
CE QUI NÉCESSITE UNE DÉCISION
5631–5640 — Green System
Si tout va bien :
AUCUNE ACTION CRITIQUE
C’est aussi une information importante.
5641–5650 — MZA IMPERIAL OPERATIONS
À ce stade, MZA ne serait plus seulement :
un LMS avec des examens difficiles.
Ce serait une architecture complète :
référentiel
→ formation
→ évaluation
→ mission
→ Jury
→ certification
→ skill passport
→ diagnostic entreprise
→ plan de formation
→ pilotage
→ qualité
→ audit
Le prochain saut n’est donc plus d’ajouter encore des « questions pièges ». Le prochain niveau serait de concevoir le MZA CONTROL TOWER + EXAM OS en vraie architecture produit, avec les écrans précis, les tables SQL, les workflows, les droits, les API et le cockpit WordPress correspondant.
v
On continue vers la couche produit réelle.
MZA EXAM OS — PHASE 14 : CONTROL TOWER ARCHITECTURE
5651–5660 — Le principe
À partir de maintenant, je séparerais clairement MZA en deux mondes :
1. EXAM RUNTIME
Ce qui fait réellement tourner les examens.
2. CONTROL TOWER
Ce qui permet aux administrateurs, jurys, responsables qualité et entreprises de piloter l’ensemble.
Le candidat ne doit jamais dépendre de l’interface d’administration.
5661–5670 — 8 modules cœur
Je construirais :
MZA Core
utilisateurs, rôles, compétences, métiers, sécurité.
MZA Reference Registry
référentiels et versions.
MZA Question Bank
questions, distracteurs, traductions, validation.
MZA Scenario Engine
événements, ressources, branches, conséquences.
MZA Exam Builder
blueprints et assemblage.
MZA Exam Runtime
tentatives, timer, autosave, décisions.
MZA Jury Center
correction, replay, arbitrage.
MZA Certification Center
résultats, certificats, vérification.
5671–5680 — Modules complémentaires
Ensuite seulement :
Analytics
Enterprise Dashboard
Training Needs
Skill Passport
Notifications
Imports
Integrations
AI Factory
Donc on évite le plugin monolithique gigantesque.
5681–5690 — Architecture WordPress
Je recommande un plugin principal :
maroc-zain-exam-os
avec des dossiers propres :
/core
/admin
/runtime
/questions
/scenarios
/jury
/certification
/analytics
/api
/assets
/templates
/migrations
Le fichier principal sert surtout à charger les modules.
5691–5700 — Pas 15 000 lignes dans un seul PHP
Erreur classique :
un énorme fichier :
maroc-zain-exam-os.php
avec tout dedans.
Je préfère :
bootstrap
→ charge services
→ enregistre hooks
→ démarre modules.
C’est beaucoup plus facile à déboguer.
5701–5710 — Tables principales
Je construirais au minimum :
wp_mza_programs
wp_mza_competencies
wp_mza_references
wp_mza_reference_versions
wp_mza_questions
wp_mza_question_versions
wp_mza_question_options
wp_mza_scenarios
wp_mza_scenario_nodes
wp_mza_scenario_edges
wp_mza_exams
wp_mza_exam_versions
wp_mza_exam_items
5711–5720 — Tables runtime
Pour les examens en cours :
wp_mza_attempts
wp_mza_attempt_state
wp_mza_responses
wp_mza_decisions
wp_mza_attempt_events
wp_mza_open_loops
wp_mza_assumptions
wp_mza_resources
wp_mza_runtime_snapshots
5721–5730 — Tables évaluation
wp_mza_scores
wp_mza_competency_evidence
wp_mza_critical_findings
wp_mza_jury_reviews
wp_mza_jury_decisions
wp_mza_appeals
5731–5740 — Tables certification
wp_mza_certificates
wp_mza_certificate_status
wp_mza_skill_records
wp_mza_reassessments
5741–5750 — Tables qualité
wp_mza_item_statistics
wp_mza_incidents
wp_mza_validations
wp_mza_audit_log
wp_mza_content_dependencies
5751–5760 — Pourquoi pas tout dans wp_posts ?
Parce que pour :
500 000 réponses
millions d’événements
logs de décisions
replay
analytics
wp_posts + wp_postmeta deviendraient vite lourds.
Je garderais wp_posts pour les contenus éditoriaux visibles dans WordPress.
Pas pour le moteur événementiel.
5761–5770 — Identifiants
Chaque objet critique reçoit :
ID interne
et
UUID public/logique
Exemple :
attempt_id = 58291
attempt_uuid = 7d93...
Cela aide pour les API et évite d’exposer directement les IDs séquentiels.
5771–5780 — Versioning
Chaque contenu certificatif possède :
object_id
version
status
effective_from
effective_to
validated_by
validated_at
Une nouvelle version ne remplace jamais silencieusement l’ancienne.
5781–5790 — Referential Lock
Un examen publié pointe vers :
référence version 4.2
Pas simplement :
référence actuelle.
Ainsi une mise à jour du référentiel ne modifie pas un examen déjà lancé.
5791–5800 — Exam Version
Même chose :
EXAM-104
peut avoir :
v1
v2
v3
Une tentative reste liée à une version précise.
5801–5810 — Immutable Attempt
Une fois l’examen démarré :
questions
barème
référentiel
seed
blueprint
sont gelés pour cette tentative.
5811–5820 — Event Store
Je créerais un journal central append-only :
wp_mza_attempt_events
Chaque événement contient :
sequence
attempt_id
type
timestamp_server
payload
actor
5821–5830 — Exemples d’événements
ATTEMPT_STARTED
QUESTION_SHOWN
ANSWER_SUBMITTED
DECISION_CREATED
RESOURCE_ASSIGNED
DOCUMENT_OPENED
EVENT_TRIGGERED
DELEGATION_CREATED
CASE_REOPENED
ATTEMPT_SUBMITTED
5831–5840 — Sequence Number
Chaque événement reçoit :
1
2
3
4
Donc même si plusieurs événements surviennent presque simultanément, leur ordre reste déterministe.
5841–5850 — Idempotency Key
Chaque action du navigateur envoie :
action_uuid
Si le réseau renvoie la même requête deux fois :
MZA voit :
déjà traité.
Donc pas de double décision.
5851–5860 — Server Clock
Le serveur est l’autorité temporelle.
Le navigateur peut afficher :
01:23:17
mais il ne décide jamais du temps restant.
5861–5870 — Heartbeat
Toutes les quelques secondes :
le navigateur envoie un heartbeat léger.
Le serveur peut suivre :
connecté
déconnecté
dernier contact
Mais l’examen ne doit pas dépendre entièrement de ce heartbeat pour calculer le temps.
5871–5880 — Reconnect
Si connexion coupée :
- candidat revient ;
- serveur vérifie session ;
- recharge dernier état valide ;
- recalcule temps restant ;
- restitue événements déjà arrivés ;
- reprend.
5881–5890 — Candidate Cockpit
Je vois une interface en 5 zones :
HAUT
mission + temps + progression.
GAUCHE
dossiers / vols / missions.
CENTRE
situation active.
DROITE
ressources / documents / équipe.
BAS
actions.
5891–5900 — Boutons candidat
Selon le scénario :
DÉCIDER
VÉRIFIER
DÉLÉGUER
SURVEILLER
ESCALADER
COMMUNIQUER
CLÔTURER
RÉÉVALUER
5901–5910 — Aucun indice de correction
Pendant l’épreuve :
pas de :
vert/rouge
bonne réponse
mauvaise réponse
+5
−2
explication
score courant
Le candidat voit uniquement la conséquence professionnelle autorisée du scénario.
5911–5920 — Candidate Document Center
Documents disponibles :
briefing
message
tableau
note
rapport
annexe
Chaque document possède :
version
heure
source
5921–5930 — Document State
Un document peut être :
CURRENT
SUPERSEDED
STALE
UNCONFIRMED
mais ces statuts ne doivent pas forcément être tous explicitement affichés si cela fait partie de l’évaluation.
5931–5940 — Candidate Search
Pour les examens documentaires complexes :
champ :
Rechercher dans les documents.
Mais sans recherche dans le corrigé évidemment.
5941–5950 — Open Loop Panel
Le candidat peut avoir un panneau :
MES ACTIONS EN ATTENTE
Mais selon le niveau, certains examens peuvent réduire cette aide.
5951–5960 — Difficulty by Interface Support
N1 :
plus d’assistance.
N2 :
moins.
N3 :
encore moins.
Expert :
le candidat construit davantage sa propre organisation.
Master :
beaucoup d’informations doivent être gérées par lui-même.
5961–5970 — Same Engine, Different Support
Très important :
je ne créerais pas un moteur par niveau.
Même runtime.
Ce sont les règles d’affichage, les blueprints et la complexité qui changent.
5971–5980 — Admin Control Tower
Menu principal :
MZA EXAM OS
avec :
Vue générale
Programmes
Référentiels
Banque
Scénarios
Examens
Campagnes
Sessions
Jury
Certificats
Qualité
Analytics
Système
5981–5990 — Dashboard Admin
Première ligne :
Examens actifs
Candidats aujourd’hui
Jury en attente
Incidents
Certificats bloqués
Référentiels à revoir
5991–6000 — Action Center
En dessous :
ACTION REQUISE
Exemple :
8 examens à valider
3 divergences Jury
2 incidents critiques
14 certificats prêts
4 référentiels expirant
6001–6010 — Exam Builder Screen
Écran :
ÉTAPE 1
Métier.
ÉTAPE 2
Certification.
ÉTAPE 3
Niveau.
ÉTAPE 4
Blueprint.
ÉTAPE 5
Paramètres.
ÉTAPE 6
Génération.
ÉTAPE 7
Validation.
6011–6020 — Builder Parameters
Admin choisit :
durée
langue
nombre QCM
scénarios
documents
oral
War Room
compétences
difficulté
6021–6030 — Advanced Settings
Puis :
items pilotes
exposition max
réutilisation minimale
forme parallèle
seed
mode adaptatif
seuils
6031–6040 — Generate
Bouton :
GÉNÉRER L’EXAMEN
Le solveur vérifie toutes les contraintes.
6041–6050 — Generation Report
Résultat :
Couverture 100 %
Temps estimé 128 min
Difficulté 8,4/10
Items critiques 17
Exposition conforme
Doublons 0
Références invalides 0
6051–6060 — Preview Candidate
Bouton :
PRÉVISUALISATION CANDIDAT
Admin voit exactement ce qu’un candidat verra.
Indispensable pour vérifier qu’aucune correction n’est exposée.
6061–6070 — Preview Jury
Bouton différent :
PRÉVISUALISATION JURY
avec :
réponses
critères
références
scoring
criticalité
6071–6080 — Validation Workflow
Exam :
DRAFT
→ GENERATED
→ EXPERT REVIEW
→ QUALITY REVIEW
→ VALIDATED
→ LOCKED
→ PUBLISHED
6081–6090 — Reject Workflow
Si expert refuse :
raison obligatoire.
Exemple :
ambiguïté
référence incorrecte
difficulté
chronologie impossible
mauvais distracteur
6091–6100 — Scenario Builder
Interface graphique :
START
↓
NODE A
↙︎ DECISION 1
↘︎ DECISION 2
↓
EVENT
↓
CONSEQUENCE
Je veux un éditeur visuel de graphe à terme.
6101–6110 — Node Types
Types :
INFO
QUESTION
DECISION
EVENT
DELAY
RESOURCE
DOCUMENT
JURY
END
6111–6120 — Edge Conditions
Une transition peut dépendre de :
réponse
temps
ressource
état
score intermédiaire
décision antérieure
événement
6121–6130 — No Arbitrary Hidden Scoring
Les branches peuvent être complexes.
Mais les règles d’évaluation doivent rester documentées et versionnées.
Pas de pseudo-intelligence imprévisible.
6131–6140 — Scenario Test Mode
Avant validation :
SIMULER 1 000 PARCOURS
pour détecter :
dead ends
branches impossibles
boucles infinies
événements non atteignables
6141–6150 — Scenario Linter
Le système peut signaler :
Node 37 sans sortie.
Event 54 dépend d’une variable jamais créée.
Resource R8 peut devenir négative.
6151–6160 — Reference Registry
Chaque référence admin possède :
titre
source
version
date
propriétaire
statut
date de revue
6161–6170 — Dependency Map
Cliquer une référence :
Utilisée par 1 248 questions
62 scénarios
18 examens
7 formations
6171–6180 — Reference Change
Quand la version change :
MZA génère automatiquement :
CONTENT IMPACT REPORT
6181–6190 — Impact Levels
Aucun impact
À vérifier
Mise à jour requise
Bloquant
6191–6200 — Question Editor
Chaque question possède des onglets :
Contenu
Options
Compétences
Références
Scoring
Versions
Statistiques
Validation
6201–6210 — Candidate Content Separate
Je stockerais séparément :
candidate_prompt
et
jury_explanation
pour réduire le risque d’exposition accidentelle.
6211–6220 — Server-Only Fields
Certains champs ne doivent jamais être retournés par l’API candidat :
correct_option
scoring_rule
expert_note
critical_rule
reference_answer
6221–6230 — REST Permissions
Chaque endpoint :
permission_callback
obligatoire.
Pas d’API sensible ouverte en lecture publique.
6231–6240 — Candidate Endpoints
Par exemple :
/attempt/start
/attempt/state
/attempt/action
/attempt/document
/attempt/submit
6241–6250 — Jury Endpoints
Séparés :
/jury/queue
/jury/attempt
/jury/evidence
/jury/review
/jury/finalize
6251–6260 — Admin Endpoints
/admin/exams
/admin/questions
/admin/scenarios
/admin/references
6261–6270 — Capability Checks
Exemple :
mza_take_exam
mza_manage_questions
mza_validate_questions
mza_manage_exams
mza_review_attempts
mza_issue_certificates
mza_manage_quality
6271–6280 — Roles
Je définirais :
Candidate
Trainer
Question Author
Expert Validator
Exam Manager
Jury
Quality Manager
Enterprise Manager
MZA Administrator
6281–6290 — Author ≠ Validator
Très important.
Celui qui crée une question ne devrait pas nécessairement pouvoir l’auto-valider.
6291–6300 — Quality Manager
Peut :
suspendre item
ouvrir revue
voir analytics
gérer incidents
mais pas nécessairement modifier tous les résultats.
6301–6310 — Jury Screen
Je veux un écran en 4 panneaux :
1
Timeline.
2
État du système au moment choisi.
3
Décision candidat.
4
Critères/références.
6311–6320 — Jury Hotspots
MZA sélectionne automatiquement :
décisions critiques
erreurs répétées
récupérations
incohérences
non-actions importantes
délégations fragiles
6321–6330 — Oral Builder
À partir de ces hotspots :
GÉNÉRER ORAL
Exemple :
« À 11:42 vous avez maintenu D17 malgré l’information E29. Pourquoi ? »
Voilà un oral réellement personnalisé.
6331–6340 — Candidate Cannot Memorize Oral
Parce que l’oral découle de sa propre mission.
C’est beaucoup plus robuste qu’une liste fixe de 100 questions orales.
6341–6350 — Jury Decision
À la fin :
VALIDER
NON VALIDER
COMPLÉMENT
ARBITRAGE
avec justification structurée.
6351–6360 — Certificate Engine
Quand toutes les conditions sont remplies :
ISSUE CERTIFICATE
Le système vérifie encore :
résultat final
Jury
aucun incident bloquant
référentiel
programme
6361–6370 — Certificate Public Verify
Shortcode :
Vérification officielle d’un certificat
Champ :
Numéro certificat
Résultat minimal et sécurisé.
6371–6380 — Candidate Dashboard
Shortcode :
[mza_candidate_dashboard]
Affiche :
Mes formations
Mes examens
Mes résultats
Mes compétences
Mes certificats
6381–6390 — Exam Cockpit Shortcode
[mza_exam_cockpit]
Mais il ne contient pas l’examen dans le HTML.
Il démarre l’application sécurisée qui récupère l’état par API après contrôle de session.
6391–6400 — Jury Shortcode
[mza_jury_center]
Accessible seulement aux capacités correspondantes.
6401–6410 — Enterprise Dashboard Shortcode
[mza_enterprise_dashboard]
pour les responsables autorisés.
6411–6420 — WordPress Pages Auto-Created
À l’activation :
MZA peut créer automatiquement :
Mon espace
Examens
Mission
Résultats
Vérifier certificat
mais sans créer de doublons à chaque réactivation.
6421–6430 — Installation Version
Option :
mza_exam_os_db_version
Exemple :
1.0.0
À chaque upgrade :
migration contrôlée.
6431–6440 — Activation Safety
L’activation doit :
vérifier PHP
créer tables
créer rôles
créer capacités
créer pages
flush rewrite une seule fois
Puis terminer.
Pas lancer de gros import.
6441–6450 — Deactivation
Désactiver le plugin ne doit pas supprimer les données.
Jamais.
6451–6460 — Uninstall
La suppression des données doit être :
volontaire
et protégée.
Exemple :
« Supprimer définitivement toutes les données MZA »
avec avertissement fort.
6461–6470 — WP-Cron
Utilisable pour :
emails
statistiques
nettoyage
rappels
Mais pas comme seul mécanisme pour un timer critique candidat.
6471–6480 — Queue System
Pour les grosses opérations :
MZA devrait avoir une queue :
pending
running
done
failed
avec retry contrôlé.
6481–6490 — PDF Certificates
Génération en arrière-plan.
L’examen ne doit jamais attendre 15 secondes parce qu’un PDF est en train d’être construit.
6491–6500 — Logging
Logs séparés :
application
runtime examen
sécurité
audit
jobs
Ne pas tout envoyer dans debug.log.
6501–6510 — Health Dashboard
Admin :
DB : OK
Runtime : OK
Jobs : 2 erreurs
API : OK
Certificate Engine : OK
Reference Registry : warning
6511–6520 — Diagnostics
Bouton :
LANCER DIAGNOSTIC
Teste :
tables
permissions
cron
pages
REST
write access
versions
6521–6530 — Safe Mode
Si un module plante :
on devrait pouvoir désactiver :
Analytics
ou
AI Factory
sans arrêter le moteur d’examen principal.
6531–6540 — Core First
Ordre absolu de priorité :
1
Exam Runtime.
2
Data integrity.
3
Security.
4
Jury.
5
Certification.
6
Analytics.
7
IA.
Pas l’inverse.
6541–6550 — V1 réaliste
Je limiterais la première version installable à :
questions
exam builder
attempt runtime
timer serveur
autosave
candidate cockpit
scoring serveur
Jury
certificats
audit
6551–6560 — V1.5
Ensuite :
scenario engine
events
documents
resources
open loops
6561–6570 — V2
Puis :
War Room
delegation
decision memory
replay
oral personnalisé
6571–6580 — V3
Puis :
adaptive testing
psychometrics
parallel forms
enterprise campaigns
6581–6590 — V4
Puis :
OMEGA DAY
Board Assessment
Control Tower national
multi-tenant
6591–6600 — Ce que je construirais maintenant
Si on passe au code, je commencerais par un vrai :
MZA EXAM OS CORE v1.0
avec :
plugin WordPress valide
installation propre
tables SQL
rôles
pages automatiques
Exam Builder
Cockpit
Jury
Certificats
et surtout un Health Check intégré, précisément pour éviter les erreurs d’installation et d’activation que vous avez déjà rencontrées sur d’autres extensions.
Le prochain niveau logique serait PHASE 15 : construire écran par écran le cockpit candidat, le Jury Center et la Control Tower avec le design premium exact.
v
On y va. Maintenant je passe à la PHASE 15 : DESIGN FONCTIONNEL ÉCRAN PAR ÉCRAN, pour que MZA EXAM OS soit directement transformable en interface WordPress premium.
MZA EXAM OS — PHASE 15 : PREMIUM UX BLUEPRINT
6601–6610 — Le principe visuel
Je recommande trois univers bien séparés :
CANDIDAT
Interface sobre, immersive, sans éléments administratifs.
JURY
Interface d’analyse, preuves, replay, référentiels.
CONTROL TOWER
Interface de pilotage, exceptions, campagnes, qualité.
Même moteur, trois expériences.
6611–6620 — Écran candidat : accueil mission
Avant démarrage :
Certification
Métier
Niveau
Durée
Langue
Nombre de blocs
Consignes
État technique
Bouton :
ENTRER DANS LA MISSION
Pas :
Commencer le QCM.
Le vocabulaire doit déjà installer le niveau professionnel.
6621–6630 — Check technique
Bloc :
Connexion : OK
Session : OK
Navigateur : OK
Heure serveur : synchronisée
Autosave : actif
Audio : prêt si oral prévu.
Bouton :
LANCER LE TEST TECHNIQUE
6631–6640 — Brief initial
Une fois entré :
07:45 — PRISE DE SERVICE
Le candidat reçoit :
objectif de mission
périmètre
équipe
ressources
situation initiale
contraintes connues
6641–6650 — Cockpit principal
Je construirais le cockpit autour de 6 zones.
ZONE 1 — Mission Header
Temps, phase, état connexion.
ZONE 2 — Timeline
Événements.
ZONE 3 — Situations
Dossiers actifs.
ZONE 4 — Workspace
Contenu principal.
ZONE 5 — Resources
Équipe, documents, ressources.
ZONE 6 — Actions
Décider, déléguer, vérifier, etc.

6651–6660 — Mission Header
En haut :
MZA EXAM OS
Chef d’escale — Expert
Mission EX-2026-004
Phase 3/8
01:47:32 restant
et une petite indication :
Sauvegardé
sans bruit visuel inutile.
6661–6670 — Pas de score
Aucun :
76 %
17/20
correct
incorrect
pendant l’examen.
Même pas une barre laissant deviner la performance.
6671–6680 — Barre de progression
La progression doit indiquer uniquement :
avancement structurel
Exemple :
42 % de la mission parcourue
et non :
42 % réussi.
6681–6690 — Timeline
Colonne verticale :
08:03
08:07
08:15
08:18
Chaque événement peut avoir une icône :
information
ressource
demande
incident
décision
Mais les couleurs ne doivent pas automatiquement signifier bon/mauvais.
6691–6700 — Timeline intelligente
Un événement peut être :
NEW
READ
OPEN
CLOSED
sans révéler sa criticité réelle si cela fait partie de l’évaluation.
6701–6710 — Dossiers actifs
Panneau :
VOL MZ201
BAGAGES
ÉQUIPE B
CONNEXIONS
RESSOURCE R3
Chaque dossier possède :
statut
owner visible
prochaine échéance
6711–6720 — Urgence candidate
Je ne mettrais pas automatiquement :
🔴 CRITIQUE
si l’objectif est précisément de tester si le candidat sait reconnaître la criticité.
Le moteur peut connaître la criticité sans la lui afficher.
6721–6730 — Workspace central
Le centre doit pouvoir afficher selon le contexte :
question
document
événement
dossier
tableau
situation
message
War Room
6731–6740 — Question standard
Format :
Une nouvelle contrainte apparaît à T+17.
Puis options très proches.
Bouton :
VALIDER LA DÉCISION
Après validation :
pas de correction.
Le monde continue.
6741–6750 — Décision ouverte
Autre format :
Quelle action prenez-vous ?
Zone texte courte.
Puis :
Pourquoi ?
Puis éventuellement :
Votre niveau de confiance ?
6751–6760 — Ranking
Le candidat glisse :
A
B
C
D
dans son ordre de priorité.
Bouton :
CONFIRMER L’ORDRE
6761–6770 — Allocation
Écran :
5 ressources
vers
8 besoins
drag & drop.
Le moteur calcule les conséquences.
6771–6780 — Delegation modal
Bouton :
DÉLÉGUER
ouvre :
à qui ?
quoi ?
échéance ?
résultat attendu ?
quand vous alerter ?
Cela transforme la délégation en vraie compétence.
6781–6790 — Monitor action
Bouton :
SURVEILLER
demande :
quoi
jusqu’à quand
quel indicateur
quel seuil
6791–6800 — Escalate action
Bouton :
ESCALADER
demande :
à qui
pourquoi
quelle décision attendue
dans quel délai
6801–6810 — Verify action
Le candidat choisit :
information
source
ou
terrain
selon les possibilités du scénario.
La vérification peut consommer du temps ou une ressource.
6811–6820 — Decision latency
Le système enregistre :
heure information
heure ouverture
heure action
mais le candidat ne voit pas nécessairement son “score de rapidité”.
6821–6830 — Documents
Panneau documentaire :
Brief 07:30
Tableau rotations v2
Note ressource
Message opérationnel
Annexe
Avec :
heure
version
source
6831–6840 — Document viewer
Je veux :
zoom
recherche
annotations personnelles temporaires
signet
sans possibilité de voir les annotations Jury.
6841–6850 — Notes candidat
Bloc privé :
MES NOTES
utile surtout pour les missions longues.
Ces notes ne doivent pas être interprétées automatiquement comme preuve de compétence sauf si cela est explicitement prévu.
6851–6860 — Team Panel
Affiche :
nom/fonction
disponibilité
tâche actuelle
retour attendu
charge visible si prévu
6861–6870 — Resource Board
Exemple :
Agent A — disponible
Agent B — occupé jusqu’à 09:20
Superviseur C — mission D17
Ressource R5 — indisponible
6871–6880 — Open Loops
Panneau :
EN ATTENTE
D17 — retour 09:15
R5 — vérification
Client X — update
Sur niveaux avancés, on peut réduire l’aide ou rendre ce panneau moins explicite.
6881–6890 — Promise Panel
Promesses faites :
09:40 — mise à jour équipe
10:10 — retour dossier B
Très utile pour les missions longues.
6891–6900 — Assumptions Panel
Pour Expert/Master :
le candidat peut inscrire :
Hypothèse
Source
Confiance
Vérifier avant
Cela devient un outil de commandement.
6901–6910 — Strategy Panel
Pour Board :
INTENTION DE MISSION
Priorité 1
Priorité 2
Risque accepté
Marge protégée
Seuil de réévaluation
6911–6920 — Phase Switch
Le cockpit peut afficher :
NORMAL
DEGRADED
RECOVERY
mais seulement si ce changement de phase est observable dans le scénario.
Sinon c’est au candidat de le déduire.
6921–6930 — War Room
Écran plein largeur.
Colonnes :
Situation
Impact
Owner
Action
Échéance
Risque
Next Check
Le candidat doit organiser le système.
6931–6940 — War Room live
Les lignes évoluent.
Un dossier peut :
apparaître
changer
disparaître
se rouvrir
sans rechargement complet de page.
6941–6950 — Board Mode
Plus minimaliste.
Le candidat voit :
10 KPI
5 décisions majeures
3 risques
2 contraintes
et doit arbitrer à haut niveau.
6951–6960 — Notification discipline
Pas 30 popups.
Je préfère :
toast bref
- événement dans timeline.
Seulement les interruptions réellement prévues par le scénario doivent casser le focus.
6961–6970 — Alarm Flood Mode
Exception volontaire :
dans certaines crises, le système peut envoyer une vague d’alertes pour tester la hiérarchisation.
Mais cela doit être un mécanisme d’évaluation explicite côté blueprint.
6971–6980 — Pause
Pour longue mission :
PAUSE AUTORISÉE
Le serveur enregistre :
début
fin
durée
et reprend exactement l’état prévu.
6981–6990 — Resume screen
Au retour :
REPRISE DE MISSION
Petit résumé :
heure
dossiers actifs
actions ouvertes
mais pas une aide disproportionnée.
6991–7000 — Handover Screen
Fin :
TRANSMETTRE LA MISSION
Le candidat remplit :
situation actuelle
priorités
risques
actions ouvertes
prochaines échéances
points à vérifier
7001–7010 — Handover timer
Expert :
5 min.
Master :
3 min.
Board :
2 min.
Selon blueprint.
7011–7020 — Final Submit
Avant soumission :
Vous êtes sur le point de remettre votre mission.
Pas de liste :
3 réponses incorrectes.
Seulement :
actions encore ouvertes si le règlement autorise cette information.
7021–7030 — Candidate Post-Exam
Après soumission :
MISSION REMISE
Date
Heure
Identifiant
Statut : en évaluation
Pas de corrigé immédiat pour la certification.
7031–7040 — Résultat candidat
Après Jury :
VALIDÉ
ou
NON VALIDÉ
ou
ÉVALUATION COMPLÉMENTAIRE
Puis :
compétences maîtrisées
axes de renforcement
sans exposer nécessairement la banque de réponses.
7041–7050 — Jury Center Header
Le Jury voit :
Candidat
Programme
Version
Référentiel
Examen
Incident éventuel
État
7051–7060 — Jury Timeline
Timeline beaucoup plus riche :
information reçue
document consulté
décision
délégation
retour
conséquence
réévaluation
7061–7070 — Time Travel
Curseur :
10:42:19
MZA reconstruit l’état exact.
C’est l’un des écrans premium les plus importants.
7071–7080 — Evidence Panel
À droite :
Compétence
Critère
Référence
Observation
Niveau de preuve
7081–7090 — Score Transparency Jury
Le Jury peut voir :
score moteur
score compétence
critical flags
confiance mesure
mais pas le candidat.
7091–7100 — Critical Decision Card
Carte :
DÉCISION D-019
Contexte T0
Action
Justification
Conséquence
Critères
Référence
7101–7110 — Alternative View
Si le modèle validé contient des alternatives :
Chemin réel
vs
Chemin alternatif
sans inventer des scénarios après coup.
7111–7120 — Jury Marking
Boutons :
CONFIRMER
À REVOIR
AJUSTER
ORAL
CRITIQUE
7121–7130 — Override
Si Jury modifie une évaluation automatique :
champ obligatoire :
JUSTIFICATION
7131–7140 — Evidence Heatmap
Exemple :
Diagnostic — forte preuve
Leadership — forte
Recovery — moyenne
Documentation — insuffisante
Cliquer ouvre les observations.
7141–7150 — Contradiction Alert
Exemple :
QCM Leadership : élevé
mais
War Room Leadership : faible.
MZA affiche :
PREUVES CONTRADICTOIRES
Pas une conclusion automatique.
7151–7160 — Oral Queue
Le moteur propose :
Question 1 — décision fragile
Question 2 — hypothèse
Question 3 — récupération
Le Jury peut accepter/modifier.
7161–7170 — Oral Screen
Grande carte :
11:37 — vous avez décidé X. Pourquoi ?
Chronomètre.
Notes Jury.
Critères.
7171–7180 — New Information Oral
Le Jury peut injecter :
NOUVELLE INFORMATION
puis :
Que changez-vous ?
Très puissant.
7181–7190 — Jury Verdict
Écran final :
Compétences
Critical Gates
Preuves
Oral
Incidents
Puis :
PROPOSITION DE DÉCISION
7191–7200 — Double Review
Si requis :
ENVOYER AU SECOND JURY
Le premier résultat peut rester masqué selon le mode blind review.
7201–7210 — Arbitration Screen
Affiche :
Jury A
Jury B
écarts
preuves concernées
référentiel
Puis décision d’arbitrage.
7211–7220 — Control Tower Home
Je vois une homepage très executive :
AUJOURD’HUI
324 candidats
86 sessions actives
12 incidents
38 Jury
71 certificats prêts
7221–7230 — Exception Cards
Seulement ce qui demande action :
3 incidents majeurs
4 référentiels expirants
2 divergences Jury
11 examens à valider
7231–7240 — Campaign Map
Vue :
Campagne RAM / Entreprise / École
→ cohortes
→ sessions
→ résultats
→ besoins formation.
7241–7250 — Live Session Board
Colonnes :
Scheduled
Check-In
Running
Paused
Submitted
Incident
7251–7260 — Session Detail
Cliquer un candidat autorisé :
status
time
connection
last save
incident
Mais pas de révélation des réponses aux superviseurs qui n’ont pas cette permission.
7261–7270 — Jury Operations
Dashboard :
à corriger
borderline
oral
arbitrage
retard
7271–7280 — Quality Dashboard
Cartes :
items actifs
pilotes
suspendus
référentiels
ambiguïtés
appels
incidents
7281–7290 — Question Analytics
Pour chaque item :
utilisations
difficulté
discrimination
temps médian
distracteurs
contestations
7291–7300 — Scenario Analytics
Pour chaque scénario :
taux branches
dead ends
temps
décisions
points de friction
erreurs moteur
7301–7310 — System Health
Bloc technique :
DB
API
Queue
Cron
runtime
autosave
certificats
storage
7311–7320 — One-click Diagnostic
Bouton :
DIAGNOSTIC COMPLET
Résultat :
17 tests OK
2 warnings
0 critical
7321–7330 — Enterprise Dashboard
Pour un DRH / responsable formation :
effectif
évalué
certifié
à renforcer
compétences critiques
certificats expirants
7331–7340 — Skills Heatmap
Lignes :
métiers.
Colonnes :
compétences.
Cellules :
niveau moyen / couverture.
Pas seulement taux de réussite.
7341–7350 — Gap Drilldown
Cliquer une faiblesse :
ANTICIPATION — 64
ouvre :
population
preuve
niveau
formation associée
priorité
7351–7360 — Training Action
Bouton :
CRÉER PLAN DE FORMATION
MZA prépare :
population cible
objectifs
modules
simulation
réévaluation
7361–7370 — Candidate Journey
Vue individuelle :
Diagnostic
→ Formation
→ Simulation
→ Certification
→ Renouvellement
7371–7380 — Premium Navigation
Je réduirais la navigation visible candidat à :
Accueil
Parcours
Missions
Résultats
Certificats
Pas 40 liens.
7381–7390 — Admin Navigation
L’administration peut être plus riche, mais organisée par métiers de travail :
BUILD
questions/scénarios/examens.
RUN
campagnes/sessions.
ASSESS
Jury.
CERTIFY
certificats.
CONTROL
qualité/système.
7391–7400 — Design Language
Visuellement :
beaucoup d’espace
grandes cartes
typographie claire
très peu de bordures
icônes cohérentes
animations légères
pas de tableau WordPress gris partout
7401–7410 — Responsive
Candidat :
desktop/tablette prioritaire pour examens complexes.
Mobile :
possible pour micro-évaluations, formation et consultation.
Je déconseille une War Room complexe sur petit smartphone.
7411–7420 — Accessibility
Tous les boutons doivent avoir :
texte
et pas uniquement une icône.
Navigation clavier.
Focus visible.
Labels.
Contrastes conformes.
7421–7430 — Elementor Boundary
Les pages marketing peuvent rester Elementor.
Mais le cockpit critique doit être rendu par le plugin lui-même.
Sinon un changement Elementor peut casser l’examen.
7431–7440 — Theme Independence
Le moteur doit résister au changement de thème WordPress.
CSS encapsulé.
Templates dédiés.
Pas dépendre du thème pour les fonctions critiques.
7441–7450 — Exam Focus Mode
Quand mission active :
masquer :
header marketing
footer
widgets
popups commerciaux
chat public
Le candidat reste dans le cockpit.
7451–7460 — Exit Protection
Si candidat tente de quitter :
Votre mission est toujours en cours.
Mais pas de mécanisme agressif empêchant complètement l’utilisateur de contrôler son navigateur.
7461–7470 — Final UX Rule
Chaque écran doit répondre à une seule question :
Quelle décision l’utilisateur doit-il prendre maintenant ?
Si l’écran affiche 40 indicateurs sans action possible, il est mal conçu.
7471–7480 — Candidate Golden Rule
Le candidat doit ressentir :
je pilote une mission
et non :
je remplis un formulaire WordPress.
7481–7490 — Jury Golden Rule
Le Jury doit ressentir :
je dispose des preuves nécessaires pour défendre ma décision.
7491–7500 — Control Tower Golden Rule
Le responsable doit ressentir :
je vois immédiatement ce qui nécessite mon attention.
7501 — Le résultat
La structure premium devient :
LEARN
→ LMS
TRAIN
→ exercices
SIMULATE
→ simulateurs
MISSION
→ Exam OS
DEFEND
→ Jury
CERTIFY
→ Certification
DEVELOP
→ plan de progression
CONTROL
→ Enterprise Control Tower
C’est cette UX que je construirais maintenant avant d’aller vers le code lourd : 3 prototypes réels — Candidate Cockpit, Jury Center, Control Tower — puis seulement le moteur SQL/API derrière. Cela évitera de produire encore une grosse extension techniquement installable mais difficile à utiliser.
On continue. Cette fois je passe à la PHASE 16 : le moteur interne qui fait vivre réellement la mission.
MZA EXAM OS — PHASE 16 : WORLD ENGINE
7502–7510 — Multi-Agent World
Le monde MZA contient des acteurs virtuels avec uniquement des propriétés professionnelles utiles :
rôle
compétence
charge
disponibilité
information détenue
autorité
responsabilités
fiabilité opérationnelle simulée
7511–7520 — Knowledge Boundaries
Très important :
le candidat ne sait pas automatiquement ce que savent les autres.
Chaque acteur possède sa propre information.
Exemple :
Agent A sait X
Superviseur B sait Y
Direction sait Z
Le candidat doit obtenir ou faire circuler l’information.
7521–7530 — Information Propagation
Une information peut :
être envoyée
être reçue
être lue
être comprise
être confirmée
Ce sont cinq états différents.
7531–7540 — Message Delay
Un message peut avoir :
0 min
2 min
8 min
de délai selon le canal ou le scénario.
Donc :
envoyer ≠ informer immédiatement.
7541–7550 — Acknowledgement
Certaines instructions critiques nécessitent :
CONFIRMATION DE RÉCEPTION
Sans retour :
la boucle reste ouverte.
7551–7560 — Misunderstanding Event
Une instruction ambiguë peut être mal interprétée par un acteur virtuel.
Le candidat peut prévenir cela par une communication suffisamment claire.
7561–7570 — Task Object
Chaque tâche possède :
ID
objectif
owner
backup
deadline
priority
status
expected output
control point
7571–7580 — Task Lifecycle
CREATED
→ ASSIGNED
→ ACKNOWLEDGED
→ IN_PROGRESS
→ COMPLETED
→ VERIFIED
→ CLOSED
ou :
→ FAILED
→ ESCALATED
→ REOPENED
7581–7590 — Silent Completion
Une tâche peut être exécutée sans retour automatique.
Le candidat doit éventuellement vérifier.
Très réaliste.
7591–7600 — Silent Failure
Inversement :
un collaborateur pense avoir terminé alors qu’une partie manque.
Le candidat peut découvrir l’écart plus tard.
7601–7610 — SLA / Deadline Engine
Chaque tâche peut posséder :
deadline dure
ou
deadline souple
Le moteur distingue les deux.
7611–7620 — Deadline Risk Curve
Une tâche ne devient pas forcément problématique uniquement à l’instant exact du délai.
Le risque peut augmenter progressivement.
7621–7630 — Ownership Conflict
Deux personnes prennent en charge le même dossier.
Conséquence possible :
double action
contradiction
perte de ressource
7631–7640 — Ownership Vacuum
Personne ne prend le dossier.
Le système devient :
OWNERLESS
mais cette information peut rester invisible au candidat tant qu’il ne contrôle pas correctement.
7641–7650 — Command Gap Engine
Un responsable disparaît temporairement.
Le moteur réévalue automatiquement :
dossiers concernés
permissions
retours attendus
responsabilités sans owner
7651–7660 — Shared Resource Contention
Deux tâches veulent la même ressource.
Le moteur ne doit pas simplement dire :
impossible.
Il doit demander une décision d’arbitrage ou appliquer la priorité déjà définie.
7661–7670 — Reservation System
Le candidat peut réserver une ressource pour plus tard.
Mais cela réduit la capacité disponible maintenant.
7671–7680 — Resource Release
Une ressource utilisée doit être :
libérée
réaffectée
ou
maintenue en réserve.
Oublier de libérer une ressource crée une dette opérationnelle.
7681–7690 — Resource Lock
Une ressource engagée dans une tâche non réversible ne peut pas être déplacée instantanément.
7691–7700 — Coordination Cost
Chaque coordination consomme quelque chose :
temps
attention
réunions
communications
Donc “tout coordonner avec tout le monde” n’est pas optimal.
7701–7710 — Synchronization Point
Le candidat peut créer :
POINT DE SYNCHRONISATION 10:30
pour aligner plusieurs acteurs.
Mais ce point coûte du temps.
7711–7720 — Sync Value
Un bon point de synchronisation réduit :
divergence
doublons
command gaps
erreurs de séquence
7721–7730 — Excessive Meetings Trap
Trop de synchronisation :
ralentissement
surcharge
retards
Le moteur distingue coordination utile de bureaucratie excessive.
7731–7740 — Communication Network
Le scénario possède un graphe :
Candidat
↔ Superviseur
↔ Agents
↔ OCC
↔ Direction
↔ partenaires
Chaque canal a ses propriétés.
7741–7750 — Channel Types
Exemple :
radio
téléphone
message écrit
système
brief direct
réunion
Chaque canal peut avoir :
rapidité
traçabilité
fiabilité
coût d’attention
7751–7760 — Channel Choice
Le candidat choisit parfois le canal.
Une information urgente envoyée par un canal lent peut être une mauvaise décision.
7761–7770 — Traceability vs Speed
Certaines décisions demandent :
canal rapide maintenant
puis
confirmation écrite ensuite.
MZA peut tester cette combinaison.
7771–7780 — Degraded Communications
Scénario :
téléphone indisponible
ou
système retardé
ou
réseau instable.
Le candidat doit passer en mode dégradé.
7781–7790 — Communication Recovery
Quand le canal revient :
il faut parfois réconcilier :
ce qui a été décidé hors système
avec
ce qui est enregistré.
7791–7800 — Information Drift
Deux équipes possèdent des versions différentes d’une même situation.
Le candidat doit réaligner le système.
7801–7810 — Actor Reliability
Un acteur virtuel peut avoir :
excellente exécution
mais
retours tardifs.
Un autre :
communication excellente
mais
compétence limitée sur une tâche donnée.
On évite les acteurs caricaturaux.
7811–7820 — Trust but Verify
Le candidat n’a pas à tout vérifier.
La fréquence de contrôle dépend de :
criticité
réversibilité
compétence
historique dans la mission
7821–7830 — Dynamic Trust
La confiance opérationnelle peut évoluer pendant l’examen.
Bon retour répété :
moins de supervision nécessaire.
Erreur importante :
contrôle renforcé temporairement.
7831–7840 — Supervision Bandwidth
Le candidat ne peut suivre qu’un nombre limité de dossiers intensivement.
Le moteur introduit une notion de :
SUPERVISION BANDWIDTH
7841–7850 — Oversubscription
S’il supervise 18 tâches comme si elles étaient toutes critiques :
sa capacité de contrôle devient insuffisante.
7851–7860 — Delegation Portfolio
Le moteur analyse non seulement chaque délégation séparément, mais l’ensemble :
trop centralisé
trop diffus
déséquilibré
robuste
7861–7870 — Escalation Graph
Chaque problème possède éventuellement une chaîne :
agent
→ superviseur
→ responsable
→ direction
Mais il n’est pas toujours nécessaire d’aller jusqu’en haut.
7871–7880 — Escalation Saturation
Trop d’escalades saturent les décideurs.
Conséquence :
temps de réponse augmenté sur les vrais sujets critiques.
7881–7890 — Escalation Debt
À l’inverse, un dossier qui aurait dû être remonté mais ne l’a pas été accumule un risque.
7891–7900 — Executive Interruption Cost
Interrompre une direction pour un sujet mineur n’est pas neutre.
Le moteur peut modéliser un coût d’attention.
7901–7910 — Conflicting Objectives
Deux acteurs peuvent poursuivre des objectifs légitimes mais différents :
ponctualité
vs
robustesse
ou
coût
vs
capacité de récupération.
7911–7920 — Local Optimization
Un service améliore son propre indicateur mais dégrade le système global.
C’est un excellent piège Expert/Master.
7921–7930 — Global Optimization
Le candidat doit parfois accepter :
un résultat local moins bon
pour protéger :
la performance globale.
7931–7940 — Network Effects
Une décision sur un vol peut affecter :
rotation suivante
équipage
passagers en correspondance
ressources
planning
7941–7950 — Dependency Chain
Exemple :
D12
→ retard ressource
→ perte de marge
→ conflit équipe
→ retard second vol
→ connexion perturbée.
Le moteur garde la chaîne complète.
7951–7960 — Hidden Dependency
Certaines dépendances ne sont pas visibles immédiatement.
Le candidat peut les découvrir grâce à une bonne analyse.
7961–7970 — Dependency Discovery
Action possible :
ANALYSER IMPACTS
Mais cela consomme du temps.
7971–7980 — Cascade Threshold
Un problème peut rester local jusqu’à un certain seuil.
Puis :
cascade.
Le candidat doit détecter quand la situation change de nature.
7981–7990 — Cascade Breaker
Action spécifique :
ISOLER LA CASCADE
par exemple en séparant ressources, responsabilités ou flux selon le scénario validé.
7991–8000 — Network Control Score
Nouvelle dimension possible :
SYSTEM / NETWORK CONTROL
Mesure si le candidat maintient la maîtrise globale, pas seulement de dossiers individuels.
8001–8010 — World State
Le runtime central conserve :
heure
acteurs
ressources
tâches
risques
hypothèses
décisions
événements
dossiers
marges
open loops
8011–8020 — State Snapshot
À certains moments :
le moteur crée un snapshot léger.
Cela facilite :
reprise
replay
audit
8021–8030 — Deterministic Seed
Chaque mission possède un :
SEED
Il permet de reproduire exactement une variante donnée lorsque nécessaire.
8031–8040 — Controlled Randomness
La variation peut porter sur :
heure
acteur
ressource
ordre
volume
retard
mais toujours dans les bornes du scénario validé.
8041–8050 — Same Seed = Same World
Pour audit :
même :
version scénario
- seed
- séquence décisions
doit pouvoir reproduire le même monde.
8051–8060 — Rule Engine
Une règle peut ressembler conceptuellement à :
SI ressource R2 indisponible
ET tâche T7 active
ET marge < 10 min
ALORS événement E31 devient éligible.
8061–8070 — Rule Priority
Quand plusieurs règles sont déclenchées simultanément :
le moteur a besoin d’un ordre de traitement déterministe.
8071–8080 — Event Queue
Chaque événement possède :
time_due
priority
condition
status
visibility
8081–8090 — Event States
SCHEDULED
ELIGIBLE
TRIGGERED
CANCELLED
SUPPRESSED
COMPLETED
8091–8100 — Prevented Event
Une bonne action peut faire passer :
SCHEDULED
à
SUPPRESSED
Le Jury voit :
incident évité.
Le candidat ne voit pas forcément cette information.
8101–8110 — Event Mutation
Un événement peut changer :
heure
intensité
impact
selon les décisions antérieures.
8111–8120 — Consequence Levels
Je conserverais :
C0 — immédiat
C1 — quelques minutes
C2 — plus tard
C3 — fin de mission
C4 — handover
C5 — J+1 simulé
8121–8130 — Delayed Consequence
Une décision à 09:12 peut n’avoir son véritable effet qu’à 14:30.
C’est ce qui empêche la logique :
clic → correction.
8131–8140 — Invisible Consequence
Certaines conséquences modifient seulement :
marge
fragilité
charge
risque résiduel
sans événement visible immédiat.
8141–8150 — Positive Hidden Consequence
Une excellente décision peut aussi produire un gain invisible :
réserve
temps
résilience
capacité future
8151–8160 — Mission Memory
Le monde garde mémoire de :
promesses
engagements
instructions
exceptions
plans temporaires
8161–8170 — Expiring Decision
Une décision peut être valable :
jusqu’à 11:30.
Si le candidat oublie de la réévaluer :
elle devient potentiellement dangereuse après expiration.
8171–8180 — Temporary Exception
Même principe :
mesure exceptionnelle autorisée pour 20 min.
MZA teste ensuite si elle est retirée.
8181–8190 — Rule Reversion
Une mesure temporaire doit parfois revenir automatiquement au fonctionnement nominal.
Le candidat peut devoir confirmer le retour.
8191–8200 — State Reconciliation
Après plusieurs actions contradictoires :
le moteur doit calculer un état cohérent.
Pas accumuler aveuglément des flags.
8201–8210 — State Validation
À chaque décision critique :
MZA vérifie :
ressources >= 0
owners valides
temps cohérent
pas de double allocation impossible
8211–8220 — Impossible State Guard
Si une règle produit un état impossible :
le scénario doit être bloqué en validation avant production.
8221–8230 — Simulation Harness
Le laboratoire peut exécuter :
10 000 variantes
sans candidat réel.
Objectif :
détecter :
bugs de logique
dead ends
états impossibles
branches jamais atteintes
8231–8240 — Coverage Report
Le système indique :
Branche 17 atteinte dans 0,03 % des simulations.
Cela permet de décider si elle est utile.
8241–8250 — Scenario Balance
Une variante ne doit pas devenir accidentellement beaucoup plus difficile uniquement à cause du hasard.
8251–8260 — Difficulty Envelope
Chaque scénario possède une plage autorisée :
difficulté cible 7,5–8,5.
Une mutation qui sort de cette enveloppe est rejetée.
8261–8270 — Time Envelope
Même chose pour la durée estimée.
8271–8280 — Resource Envelope
Le moteur vérifie que la mission reste solvable avec les ressources fournies, sauf si l’objectif pédagogique prévoit explicitement un arbitrage impossible à satisfaire totalement.
8281–8290 — No-Win Scenario Governance
Une situation où tout choix implique une perte peut exister.
Mais elle doit être explicitement validée comme telle.
Le candidat est alors évalué sur :
arbitrage
justification
contrôle du risque
pas sur une “bonne réponse magique”.
8291–8300 — World Engine Audit
Chaque changement d’état doit répondre à :
pourquoi ?
Exemple :
margin: 18 → 9
Cause :
DECISION_D17
RESOURCE_R3_DELAY
8301–8310 — Causal Trace
Le Jury peut ouvrir :
POURQUOI CE RETARD ?
et remonter :
cause
→ mécanisme
→ propagation
→ effet.
8311–8320 — Candidate Causality
Le moteur peut aussi demander :
« Quelle est selon vous la cause principale ? »
Puis comparer à la structure validée du scénario.
8321–8330 — Competing Causes
Il peut y avoir plusieurs causes contributives.
MZA doit éviter un modèle simpliste :
une cause unique obligatoire.
8331–8340 — Root / Contributing / Trigger
Je distinguerais :
ROOT CAUSE
CONTRIBUTING FACTOR
TRIGGER
AMPLIFIER
8341–8350 — Counterfactual Test
Le Jury peut examiner :
si D17 n’avait pas été prise, que prévoyait le scénario validé ?
Sans inventer rétroactivement une histoire.
8351–8360 — Runtime Scoring Events
Le score ne devrait pas être calculé seulement à la fin.
Le moteur crée des evidence events :
compétence X observée dans décision D17.
8361–8370 — Evidence Event
Exemple :
Competency: Prioritization
Observation: strong
Context: high simultaneity
Evidence ID: EV-883
8371–8380 — Multiple Evidence Requirement
Une seule belle décision ne suffit pas forcément pour valider une compétence critique.
Le moteur accumule plusieurs observations indépendantes.
8381–8390 — Evidence Weight
Le poids dépend :
contexte
niveau
criticité
indépendance
format
8391–8400 — Evidence Saturation
Une fois qu’une compétence est déjà très bien mesurée :
le moteur n’a pas besoin de la retester 50 fois.
8401–8410 — Evidence Deficit
Inversement :
une compétence importante encore peu observée peut être ciblée plus tard si les règles de l’examen autorisent l’adaptation.
8411–8420 — Adaptive Mission
Ce n’est donc pas :
« il réussit, je le punis avec plus dur ».
C’est :
« il me manque des preuves sur compétence Y ».
8421–8430 — Fixed Certification Mode
Si le règlement exige un examen fixe :
aucune modification adaptative du blueprint.
Le moteur reste strictement dans la forme gelée.
8431–8440 — Adaptive Diagnostic Mode
Pour diagnostic ou entraînement :
adaptation beaucoup plus libre.
8441–8450 — Separation of Modes
Je distinguerais clairement :
TRAINING
DIAGNOSTIC
CERTIFICATION
BOARD ASSESSMENT
Les règles ne sont pas identiques.
8451–8460 — Training Mode
Peut fournir :
feedback
explications
indices
rejeu
8461–8470 — Certification Mode
Aucun feedback correctif pendant l’épreuve.
8471–8480 — Board Mode
Plus de :
décisions ouvertes
oral
défense
système vivant
et moins de QCM classiques.
8481–8490 — Runtime Boundary
Côté candidat, l’API ne reçoit que :
état visible
actions possibles
documents visibles
temps
Jamais le modèle complet du scénario.
8491–8500 — Hidden World
Le serveur conserve :
événements futurs
branches
criticité
barème
conséquences cachées
références
8501–8510 — Security Principle
Le navigateur candidat ne doit jamais avoir “tout l’examen caché dans le JavaScript”.
Sinon quelqu’un peut inspecter le code.
8511–8520 — Thin Client
Le navigateur devient essentiellement :
interface
Le cerveau du scénario reste côté serveur.
8521–8530 — Transactional Decision
Une action candidat doit suivre :
authentifier
→ vérifier tentative
→ vérifier état
→ valider action
→ écrire événement
→ mettre à jour monde
→ générer preuves
→ retourner nouvel état visible
8531–8540 — Concurrency Lock
Pendant cette transaction :
le même candidat ne doit pas pouvoir envoyer deux décisions contradictoires simultanément depuis deux requêtes.
8541–8550 — Optimistic UI limité
On peut afficher :
Enregistrement…
mais ne jamais prétendre que l’action est confirmée tant que le serveur ne l’a pas acceptée.
8551–8560 — Runtime Error Recovery
Si erreur serveur :
l’action possède toujours son action_uuid.
Le candidat peut réessayer sans double exécution.
8561–8570 — Snapshot Recovery
Si runtime redémarre :
dernier snapshot
- événements suivants
= état restauré.
8571–8580 — Replay Integrity
Le replay Jury utilise exactement :
la même logique de reconstruction.
Pas une animation approximative.
8581–8590 — World Engine Version
Chaque tentative stocke :
runtime_version
scenario_version
rule_engine_version
8591–8600 — Historical Compatibility
Une mise à jour du moteur ne doit pas empêcher de rejouer une ancienne tentative importante.
Il faut prévoir la conservation des versions nécessaires ou des snapshots suffisants.
8601–8610 — WORLD ENGINE CONTROL PANEL
Admin technique voit :
missions actives
events/min
queue size
runtime errors
average decision latency
snapshot health
8611–8620 — Emergency Runtime Switch
Si un type d’événement provoque un bug :
l’administrateur peut neutraliser ce mécanisme pour les nouvelles sessions selon procédure sans détruire les tentatives en cours.
8621–8630 — Scenario Kill Switch
Un scénario problématique :
SUSPEND NEW STARTS
Les sessions déjà démarrées suivent la politique d’incident prévue.
8631–8640 — Production Safeguard
Jamais modifier un scénario LIVE directement.
Créer :
version suivante.
8641–8650 — PHASE 16 RESULT
On arrive à une architecture où MZA possède réellement un :
SOVEREIGN WORLD ENGINE
qui gère :
ACTEURS
- INFORMATION
- TÂCHES
- RESSOURCES
- COMMUNICATION
- TEMPS
- ÉVÉNEMENTS
- DÉPENDANCES
- CONSÉQUENCES
- PREUVES
- REPLAY
C’est cette couche qui permettrait enfin de passer de « questions difficiles » à de vraies missions professionnelles simulées et auditables.Bien. On passe maintenant au noyau réellement codable.
MZA EXAM OS — PHASE 18 : SQL + API + WORLD ENGINE
10001–10010 — Architecture minimale
Je figerais 5 couches techniques :
Reference Core → référentiels, compétences, versions
Exam Core → examens, blueprints, items
World Engine → état, événements, ressources, acteurs
Evidence Engine → preuves, scoring, criticité
Certification Core → Jury, décision, certificat
10011–10020 — Table mza_attempts
Chaque tentative contient notamment :
id
uuid
user_id
exam_version_id
scenario_version_id
reference_version_id
seed
status
started_at
expires_at
submitted_at
runtime_version
last_sequence
created_at
updated_at
Statuts :
CREATED
READY
RUNNING
PAUSED
SUBMITTED
JURY
COMPLETED
CANCELLED
TECHNICAL_REVIEW
10021–10030 — Event Store central
Table :
wp_mza_attempt_events
Champs :
id
attempt_id
sequence_no
event_uuid
event_type
actor_type
actor_id
occurred_at
payload_json
visibility
causation_id
correlation_id
created_at
Le champ sequence_no est crucial.
Il donne :
1 → 2 → 3 → 4 → 5
même lorsque plusieurs événements arrivent presque simultanément.
10031–10040 — Types d’événements
Exemples :
MISSION_STARTED
INFORMATION_RECEIVED
DOCUMENT_OPENED
QUESTION_DISPLAYED
ANSWER_SUBMITTED
DECISION_MADE
TASK_CREATED
TASK_DELEGATED
TASK_ACKNOWLEDGED
RESOURCE_ASSIGNED
RESOURCE_RELEASED
EVENT_TRIGGERED
CASE_REOPENED
CASE_CLOSED
MISSION_SUBMITTED
10041–10050 — World State
Table snapshot :
wp_mza_attempt_state
avec :
attempt_id
current_time
phase
state_version
state_json
last_event_sequence
updated_at
state_json contient uniquement l’état opérationnel nécessaire.
10051–10060 — État logique
Conceptuellement :
{
"time": "10:42",
"phase": "DEGRADED",
"resources": {},
"actors": {},
"tasks": {},
"cases": {},
"open_loops": {},
"assumptions": {},
"commitments": {},
"risks": {},
"margins": {}
}
Mais côté production, les objets très volumineux peuvent aussi avoir leurs propres tables.
10061–10070 — Actor
Objet acteur :
actor_id
role
availability
workload
permissions
skills
current_tasks
information_state
Pas de profil psychologique.
10071–10080 — Resource
resource_id
type
capacity
status
owner
reserved_until
location
dependencies
10081–10090 — Task
task_id
objective
owner
backup
priority
deadline
status
expected_output
control_at
criticality
Lifecycle :
CREATED
ASSIGNED
ACKNOWLEDGED
IN_PROGRESS
COMPLETED
VERIFIED
CLOSED
FAILED
REOPENED
10091–10100 — Open Loop
loop_id
source_type
source_id
owner
opened_at
due_at
expected_return
status
criticality
Le moteur peut ainsi savoir précisément ce qui attend encore une action.
10101–10110 — Assumption Register
assumption_id
statement
source
created_at
confidence
valid_until
verification_due
status
Statuts :
ACTIVE
CONFIRMED
INVALIDATED
EXPIRED
CLOSED
10111–10120 — Commitment Register
Pour les promesses :
commitment_id
from_actor
to_actor
promise
due_at
status
fulfilled_at
10121–10130 — Decision Object
Table :
wp_mza_decisions
avec :
decision_id
attempt_id
decision_uuid
candidate_id
context_sequence
decision_type
action
justification
confidence
accepted_risk
reassessment_trigger
created_at
10131–10140 — Important : contexte gelé
Chaque décision doit pointer vers :
context_sequence
Cela indique exactement :
ce que le candidat savait au moment de décider.
Indispensable pour éviter le biais rétrospectif du Jury.
10141–10150 — API candidat
Je limiterais fortement l’API.
Exemples :
POST /mza/v1/attempt/start
GET /mza/v1/attempt/state
POST /mza/v1/attempt/action
POST /mza/v1/attempt/answer
POST /mza/v1/attempt/delegate
POST /mza/v1/attempt/verify
POST /mza/v1/attempt/submit
10151–10160 — Réponse API candidat
L’API retourne uniquement :
visible_state
available_actions
visible_documents
timeline_visible
time_remaining
save_status
Jamais :
correct_answer
score
critical_rule
future_event
hidden_branch
jury_note
reference_answer
10161–10170 — Action transactionnelle
Lorsqu’un candidat clique :
DÉLÉGUER
le serveur effectue :
1 authentifier
2 vérifier tentative
3 verrouiller état
4 vérifier action autorisée
5 vérifier action_uuid
6 écrire événement
7 appliquer règles
8 recalculer état
9 générer conséquences
10 enregistrer preuves
11 commit
12 retourner état visible
10171–10180 — Idempotency
Le client envoie :
action_uuid
Si le réseau répète la requête :
même UUID = action déjà exécutée.
Le serveur retourne l’ancien résultat.
Pas de double délégation.
10181–10190 — Verrouillage
Pendant une décision :
attempt lock
empêche deux actions concurrentes contradictoires.
Très important sur double clic, reconnexion ou deux onglets.
10191–10200 — Rule Engine
Une règle pourrait conceptuellement être stockée :
RULE-427
WHEN:
resource.R5.status == UNAVAILABLE
AND task.T12.status == ACTIVE
AND margins.time < 12
THEN:
schedule EVENT-88 in 4 minutes
10201–10210 — Pas de PHP arbitraire en base
Je déconseille fortement de stocker du code PHP exécutable dans les scénarios.
Les règles doivent utiliser un langage de règles limité et validé.
Beaucoup plus sécurisé.
10211–10220 — Conditions autorisées
Exemples :
equals
not_equals
greater_than
less_than
contains
exists
elapsed_time
all
any
not
10221–10230 — Actions moteur autorisées
SET_STATE
CREATE_TASK
UPDATE_TASK
ASSIGN_RESOURCE
RELEASE_RESOURCE
CREATE_LOOP
CLOSE_LOOP
SCHEDULE_EVENT
CANCEL_EVENT
SHOW_INFORMATION
ADD_EVIDENCE
CHANGE_MARGIN
10231–10240 — Event Queue
Table :
wp_mza_event_queue
Champs :
event_id
attempt_id
event_type
due_at
priority
condition_json
payload_json
status
10241–10250 — Priority
Même seconde :
priority 100 = moteur critique
priority 80 = changement état
priority 50 = information
priority 20 = notification
L’ordre doit rester déterministe.
10251–10260 — Scheduler
Je ne ferais pas dépendre un examen actif uniquement de WP-Cron.
Pour une mission active :
la requête runtime vérifie systématiquement les événements arrivés à échéance.
Et pour une infrastructure plus grande :
worker dédié.
10261–10270 — Advance World
Fonction conceptuelle centrale :
advance_world(attempt_id, server_time)
Elle :
charge état
→ récupère événements dus
→ teste conditions
→ applique événements
→ exécute règles secondaires
→ met à jour état
→ sauvegarde.
10271–10280 — Rule Cascade Protection
Une règle déclenche une règle qui déclenche une autre.
Il faut une limite :
max_rule_depth
pour empêcher une boucle infinie.
10281–10290 — Cycle Detection
Le Scenario Validator détecte également :
A → B → C → A
si ce cycle n’est pas volontaire.
10291–10300 — State Validator
Après chaque transaction :
resources >= 0
valid owners
valid references
valid task states
valid timestamps
no forbidden double allocation
Si violation :
rollback.
10301–10310 — Evidence Engine
Table :
wp_mza_competency_evidence
avec :
evidence_id
attempt_id
competency_id
source_event_id
criterion_id
strength
direction
criticality
context_level
scoring_rule_version
created_at
10311–10320 — Evidence Direction
POSITIVE
NEGATIVE
MIXED
NEUTRAL
INSUFFICIENT
Cela évite de forcer toute observation en bon/mauvais.
10321–10330 — Evidence Strength
Par exemple :
LOW
MODERATE
STRONG
VERY_STRONG
ou un poids interne défini par le blueprint.
10331–10340 — Evidence Independence
Deux preuves issues exactement de la même décision ne doivent pas être comptées comme deux observations indépendantes.
Le moteur garde :
evidence_group_id
10341–10350 — Competency Aggregator
Pour une compétence :
collect evidence
remove invalid evidence
apply certification rubric
verify critical observations
calculate evidence sufficiency
produce candidate competency state
10351–10360 — Statut compétence
Je préfère :
NOT_OBSERVED
INSUFFICIENT_EVIDENCE
BELOW_REQUIREMENT
REQUIREMENT_MET
STRONG_EVIDENCE
JURY_REVIEW
plutôt qu’un faux 87,456 %.
10361–10370 — Score numérique
On peut toujours avoir un score numérique pour analytics.
Mais la décision certifiante doit rester rattachée aux critères.
10371–10380 — Critical Gate
Exemple conceptuel :
IF competency SAFETY
AND critical_failure confirmed
THEN certification_gate = FAIL
Uniquement si cette règle existe dans le référentiel/programme validé.
10381–10390 — Jury Engine
Table :
wp_mza_jury_reviews
Champs :
review_id
attempt_id
juror_id
status
decision
reason
started_at
completed_at
10391–10400 — Jury Evidence Review
Le Jury ne reçoit pas 8 heures de données brutes immédiatement.
Le moteur prépare :
hotspots
critical decisions
conflicts
recovery events
weak evidence
strong evidence
10401–10410 — Replay API
GET /jury/attempt/{id}/replay?sequence=428
Retour :
visible candidate state à 10:42
- contexte Jury autorisé.
10411–10420 — Time Machine exact
Le replay est reconstruit depuis :
snapshot antérieur
events snapshot+1 → sequence 428
10421–10430 — Snapshot cadence
Pas besoin d’un snapshot après chaque clic.
Exemple :
toutes les 50 actions
et sur :
changement de phase
incident majeur
pause
soumission
10431–10440 — Certificate Gate
Avant émission :
attempt submitted
jury finalized
critical gates resolved
appeal status allowed
reference valid for attempt snapshot
certificate rule satisfied
10441–10450 — Certificate ID
Je recommande un identifiant du type :
MZA-2026-CE-7F92KQ
plutôt qu’un simple :
CERT-123
10451–10460 — Verification Token
Le QR pointe vers un token de vérification public distinct de l’ID interne.
10461–10470 — Audit
Table :
wp_mza_audit_log
contient :
actor
action
object_type
object_id
before_hash
after_hash
reason
timestamp
ip_hash_if_required
Avec politique de données adaptée.
10471–10480 — Audit critique
À tracer obligatoirement :
modification barème
validation référentiel
publication examen
override Jury
certificat délivré
certificat révoqué
10481–10490 — Exam Freeze
À :
PUBLISHED
on crée un snapshot complet :
exam_snapshot
reference_snapshot
rubric_snapshot
scenario_snapshot
10491–10500 — Production Rule
Un examen en production n’est jamais modifié.
On crée :
v2
Puis les futures sessions utilisent v2.
10501–10510 — Health Check
Avant activation plugin :
PHP version
DB engine
required tables
REST
filesystem
permalinks
capabilities
queue
server time
10511–10520 — Self-Test
Bouton :
TESTER LE MOTEUR
crée une tentative fictive interne :
START
→ ANSWER
→ EVENT
→ SCORE
→ JURY
→ CERTIFICATE TEST
puis détruit les données de test.
10521–10530 — Runtime Monitor
Dashboard :
active attempts
actions/min
events/min
p95 latency
failed transactions
reconnects
queue lag
10531–10540 — Circuit Breaker
Si un composant non critique tombe :
Analytics par exemple,
le runtime candidat continue.
10541–10550 — Critical Failure
Si le moteur transactionnel tombe :
ne pas continuer en mode dégradé silencieux.
Mettre la tentative dans :
TECHNICAL HOLD
selon procédure.
10551–10560 — Database Indexes
Indexes indispensables notamment sur :
attempt_id
sequence_no
event_type
status
due_at
candidate_id
exam_version_id
competency_id
10561–10570 — Pagination
Jamais charger :
500 000 événements
dans une page Jury.
Pagination serveur + filtres.
10571–10580 — Archive Strategy
Les anciennes campagnes peuvent être déplacées vers stockage d’archive logique selon politique.
Les certificats restent facilement vérifiables.
10581–10590 — API Versioning
Dès le début :
/mza/v1/
Cela évite de casser les clients futurs.
10591–10600 — Core PHP Services
Je créerais des classes du type :
MZA_Attempt_Service
MZA_World_Engine
MZA_Event_Service
MZA_Rule_Engine
MZA_Evidence_Service
MZA_Jury_Service
MZA_Certificate_Service
MZA_Audit_Service
10601–10610 — Repository Layer
Accès DB séparé :
AttemptRepository
EventRepository
ScenarioRepository
EvidenceRepository
CertificateRepository
Le moteur métier ne doit pas contenir du SQL partout.
10611–10620 — Domain Services
Exemple :
DelegationService
ResourceAllocator
OpenLoopManager
AssumptionManager
CommitmentManager
10621–10630 — Testing
Il faut au minimum :
unit tests
integration tests
runtime scenario tests
migration tests
security tests
10631–10640 — Scenario Test Fixture
Exemple automatique :
given R2 unavailable
given T7 active
given margin 8
when candidate delegates action D3
then EVENT-18 scheduled
then margin becomes 12
then evidence E42 created
10641–10650 — Golden Replay Test
Une mission connue possède :
seed
actions
résultat attendu.
Après chaque mise à jour moteur :
on la rejoue automatiquement.
Si résultat différent :
régression détectée.
10651–10660 — Le vrai V1
Je figerais maintenant le MVP à seulement 10 fonctions critiques :
- Banque questions
- Blueprint examen
- Tentatives
- Timer serveur
- Autosave
- Scoring serveur
- Event Store
- Jury Center
- Certificat
- Health Check
10661–10670 — V1.1
Puis :
World State
tasks
resources
open loops
documents
10671–10680 — V1.2
Puis :
scenario rules
delayed events
decision consequences
replay
10681–10690 — V2
Puis :
delegation
War Room
actors
communications
mission continuity
10691–10700 — V3
Puis seulement :
adaptive evidence
parallel forms
psychometrics
enterprise campaigns
Board Assessment
10701 — Architecture cible
Le cœur devient finalement :
WORDPRESS UI
↓
MZA REST API
↓
COMMAND HANDLER
↓
WORLD ENGINE
↓
EVENT STORE
↓
STATE + EVIDENCE
↓
JURY
↓
CERTIFICATION
Et pour moi, c’est le point décisif : à partir d’ici, on peut réellement construire le plugin au lieu de continuer à imaginer seulement des fonctionnalités.
Le prochain bloc peut être encore plus concret : PHASE 19 — arborescence complète du plugin WordPress + fichiers PHP + classes + tables SQL + endpoints exacts, jusqu’au squelette installable de maroc-zain-exam-os.
Bien. On passe maintenant au noyau réellement codable.
MZA EXAM OS — PHASE 18 : SQL + API + WORLD ENGINE
10001–10010 — Architecture minimale
Je figerais 5 couches techniques :
Reference Core → référentiels, compétences, versions
Exam Core → examens, blueprints, items
World Engine → état, événements, ressources, acteurs
Evidence Engine → preuves, scoring, criticité
Certification Core → Jury, décision, certificat
10011–10020 — Table mza_attempts
Chaque tentative contient notamment :
id
uuid
user_id
exam_version_id
scenario_version_id
reference_version_id
seed
status
started_at
expires_at
submitted_at
runtime_version
last_sequence
created_at
updated_at
Statuts :
CREATED
READY
RUNNING
PAUSED
SUBMITTED
JURY
COMPLETED
CANCELLED
TECHNICAL_REVIEW
10021–10030 — Event Store central
Table :
wp_mza_attempt_events
Champs :
id
attempt_id
sequence_no
event_uuid
event_type
actor_type
actor_id
occurred_at
payload_json
visibility
causation_id
correlation_id
created_at
Le champ sequence_no est crucial.
Il donne :
1 → 2 → 3 → 4 → 5
même lorsque plusieurs événements arrivent presque simultanément.
10031–10040 — Types d’événements
Exemples :
MISSION_STARTED
INFORMATION_RECEIVED
DOCUMENT_OPENED
QUESTION_DISPLAYED
ANSWER_SUBMITTED
DECISION_MADE
TASK_CREATED
TASK_DELEGATED
TASK_ACKNOWLEDGED
RESOURCE_ASSIGNED
RESOURCE_RELEASED
EVENT_TRIGGERED
CASE_REOPENED
CASE_CLOSED
MISSION_SUBMITTED
10041–10050 — World State
Table snapshot :
wp_mza_attempt_state
avec :
attempt_id
current_time
phase
state_version
state_json
last_event_sequence
updated_at
state_json contient uniquement l’état opérationnel nécessaire.
10051–10060 — État logique
Conceptuellement :
{
"time": "10:42",
"phase": "DEGRADED",
"resources": {},
"actors": {},
"tasks": {},
"cases": {},
"open_loops": {},
"assumptions": {},
"commitments": {},
"risks": {},
"margins": {}
}
Mais côté production, les objets très volumineux peuvent aussi avoir leurs propres tables.
10061–10070 — Actor
Objet acteur :
actor_id
role
availability
workload
permissions
skills
current_tasks
information_state
Pas de profil psychologique.
10071–10080 — Resource
resource_id
type
capacity
status
owner
reserved_until
location
dependencies
10081–10090 — Task
task_id
objective
owner
backup
priority
deadline
status
expected_output
control_at
criticality
Lifecycle :
CREATED
ASSIGNED
ACKNOWLEDGED
IN_PROGRESS
COMPLETED
VERIFIED
CLOSED
FAILED
REOPENED
10091–10100 — Open Loop
loop_id
source_type
source_id
owner
opened_at
due_at
expected_return
status
criticality
Le moteur peut ainsi savoir précisément ce qui attend encore une action.
10101–10110 — Assumption Register
assumption_id
statement
source
created_at
confidence
valid_until
verification_due
status
Statuts :
ACTIVE
CONFIRMED
INVALIDATED
EXPIRED
CLOSED
10111–10120 — Commitment Register
Pour les promesses :
commitment_id
from_actor
to_actor
promise
due_at
status
fulfilled_at
10121–10130 — Decision Object
Table :
wp_mza_decisions
avec :
decision_id
attempt_id
decision_uuid
candidate_id
context_sequence
decision_type
action
justification
confidence
accepted_risk
reassessment_trigger
created_at
10131–10140 — Important : contexte gelé
Chaque décision doit pointer vers :
context_sequence
Cela indique exactement :
ce que le candidat savait au moment de décider.
Indispensable pour éviter le biais rétrospectif du Jury.
10141–10150 — API candidat
Je limiterais fortement l’API.
Exemples :
POST /mza/v1/attempt/start
GET /mza/v1/attempt/state
POST /mza/v1/attempt/action
POST /mza/v1/attempt/answer
POST /mza/v1/attempt/delegate
POST /mza/v1/attempt/verify
POST /mza/v1/attempt/submit
10151–10160 — Réponse API candidat
L’API retourne uniquement :
visible_state
available_actions
visible_documents
timeline_visible
time_remaining
save_status
Jamais :
correct_answer
score
critical_rule
future_event
hidden_branch
jury_note
reference_answer
10161–10170 — Action transactionnelle
Lorsqu’un candidat clique :
DÉLÉGUER
le serveur effectue :
1 authentifier
2 vérifier tentative
3 verrouiller état
4 vérifier action autorisée
5 vérifier action_uuid
6 écrire événement
7 appliquer règles
8 recalculer état
9 générer conséquences
10 enregistrer preuves
11 commit
12 retourner état visible
10171–10180 — Idempotency
Le client envoie :
action_uuid
Si le réseau répète la requête :
même UUID = action déjà exécutée.
Le serveur retourne l’ancien résultat.
Pas de double délégation.
10181–10190 — Verrouillage
Pendant une décision :
attempt lock
empêche deux actions concurrentes contradictoires.
Très important sur double clic, reconnexion ou deux onglets.
10191–10200 — Rule Engine
Une règle pourrait conceptuellement être stockée :
RULE-427
WHEN:
resource.R5.status == UNAVAILABLE
AND task.T12.status == ACTIVE
AND margins.time < 12
THEN:
schedule EVENT-88 in 4 minutes
10201–10210 — Pas de PHP arbitraire en base
Je déconseille fortement de stocker du code PHP exécutable dans les scénarios.
Les règles doivent utiliser un langage de règles limité et validé.
Beaucoup plus sécurisé.
10211–10220 — Conditions autorisées
Exemples :
equals
not_equals
greater_than
less_than
contains
exists
elapsed_time
all
any
not
10221–10230 — Actions moteur autorisées
SET_STATE
CREATE_TASK
UPDATE_TASK
ASSIGN_RESOURCE
RELEASE_RESOURCE
CREATE_LOOP
CLOSE_LOOP
SCHEDULE_EVENT
CANCEL_EVENT
SHOW_INFORMATION
ADD_EVIDENCE
CHANGE_MARGIN
10231–10240 — Event Queue
Table :
wp_mza_event_queue
Champs :
event_id
attempt_id
event_type
due_at
priority
condition_json
payload_json
status
10241–10250 — Priority
Même seconde :
priority 100 = moteur critique
priority 80 = changement état
priority 50 = information
priority 20 = notification
L’ordre doit rester déterministe.
10251–10260 — Scheduler
Je ne ferais pas dépendre un examen actif uniquement de WP-Cron.
Pour une mission active :
la requête runtime vérifie systématiquement les événements arrivés à échéance.
Et pour une infrastructure plus grande :
worker dédié.
10261–10270 — Advance World
Fonction conceptuelle centrale :
advance_world(attempt_id, server_time)
Elle :
charge état
→ récupère événements dus
→ teste conditions
→ applique événements
→ exécute règles secondaires
→ met à jour état
→ sauvegarde.
10271–10280 — Rule Cascade Protection
Une règle déclenche une règle qui déclenche une autre.
Il faut une limite :
max_rule_depth
pour empêcher une boucle infinie.
10281–10290 — Cycle Detection
Le Scenario Validator détecte également :
A → B → C → A
si ce cycle n’est pas volontaire.
10291–10300 — State Validator
Après chaque transaction :
resources >= 0
valid owners
valid references
valid task states
valid timestamps
no forbidden double allocation
Si violation :
rollback.
10301–10310 — Evidence Engine
Table :
wp_mza_competency_evidence
avec :
evidence_id
attempt_id
competency_id
source_event_id
criterion_id
strength
direction
criticality
context_level
scoring_rule_version
created_at
10311–10320 — Evidence Direction
POSITIVE
NEGATIVE
MIXED
NEUTRAL
INSUFFICIENT
Cela évite de forcer toute observation en bon/mauvais.
10321–10330 — Evidence Strength
Par exemple :
LOW
MODERATE
STRONG
VERY_STRONG
ou un poids interne défini par le blueprint.
10331–10340 — Evidence Independence
Deux preuves issues exactement de la même décision ne doivent pas être comptées comme deux observations indépendantes.
Le moteur garde :
evidence_group_id
10341–10350 — Competency Aggregator
Pour une compétence :
collect evidence
remove invalid evidence
apply certification rubric
verify critical observations
calculate evidence sufficiency
produce candidate competency state
10351–10360 — Statut compétence
Je préfère :
NOT_OBSERVED
INSUFFICIENT_EVIDENCE
BELOW_REQUIREMENT
REQUIREMENT_MET
STRONG_EVIDENCE
JURY_REVIEW
plutôt qu’un faux 87,456 %.
10361–10370 — Score numérique
On peut toujours avoir un score numérique pour analytics.
Mais la décision certifiante doit rester rattachée aux critères.
10371–10380 — Critical Gate
Exemple conceptuel :
IF competency SAFETY
AND critical_failure confirmed
THEN certification_gate = FAIL
Uniquement si cette règle existe dans le référentiel/programme validé.
10381–10390 — Jury Engine
Table :
wp_mza_jury_reviews
Champs :
review_id
attempt_id
juror_id
status
decision
reason
started_at
completed_at
10391–10400 — Jury Evidence Review
Le Jury ne reçoit pas 8 heures de données brutes immédiatement.
Le moteur prépare :
hotspots
critical decisions
conflicts
recovery events
weak evidence
strong evidence
10401–10410 — Replay API
GET /jury/attempt/{id}/replay?sequence=428
Retour :
visible candidate state à 10:42
- contexte Jury autorisé.
10411–10420 — Time Machine exact
Le replay est reconstruit depuis :
snapshot antérieur
events snapshot+1 → sequence 428
10421–10430 — Snapshot cadence
Pas besoin d’un snapshot après chaque clic.
Exemple :
toutes les 50 actions
et sur :
changement de phase
incident majeur
pause
soumission
10431–10440 — Certificate Gate
Avant émission :
attempt submitted
jury finalized
critical gates resolved
appeal status allowed
reference valid for attempt snapshot
certificate rule satisfied
10441–10450 — Certificate ID
Je recommande un identifiant du type :
MZA-2026-CE-7F92KQ
plutôt qu’un simple :
CERT-123
10451–10460 — Verification Token
Le QR pointe vers un token de vérification public distinct de l’ID interne.
10461–10470 — Audit
Table :
wp_mza_audit_log
contient :
actor
action
object_type
object_id
before_hash
after_hash
reason
timestamp
ip_hash_if_required
Avec politique de données adaptée.
10471–10480 — Audit critique
À tracer obligatoirement :
modification barème
validation référentiel
publication examen
override Jury
certificat délivré
certificat révoqué
10481–10490 — Exam Freeze
À :
PUBLISHED
on crée un snapshot complet :
exam_snapshot
reference_snapshot
rubric_snapshot
scenario_snapshot
10491–10500 — Production Rule
Un examen en production n’est jamais modifié.
On crée :
v2
Puis les futures sessions utilisent v2.
10501–10510 — Health Check
Avant activation plugin :
PHP version
DB engine
required tables
REST
filesystem
permalinks
capabilities
queue
server time
10511–10520 — Self-Test
Bouton :
TESTER LE MOTEUR
crée une tentative fictive interne :
START
→ ANSWER
→ EVENT
→ SCORE
→ JURY
→ CERTIFICATE TEST
puis détruit les données de test.
10521–10530 — Runtime Monitor
Dashboard :
active attempts
actions/min
events/min
p95 latency
failed transactions
reconnects
queue lag
10531–10540 — Circuit Breaker
Si un composant non critique tombe :
Analytics par exemple,
le runtime candidat continue.
10541–10550 — Critical Failure
Si le moteur transactionnel tombe :
ne pas continuer en mode dégradé silencieux.
Mettre la tentative dans :
TECHNICAL HOLD
selon procédure.
10551–10560 — Database Indexes
Indexes indispensables notamment sur :
attempt_id
sequence_no
event_type
status
due_at
candidate_id
exam_version_id
competency_id
10561–10570 — Pagination
Jamais charger :
500 000 événements
dans une page Jury.
Pagination serveur + filtres.
10571–10580 — Archive Strategy
Les anciennes campagnes peuvent être déplacées vers stockage d’archive logique selon politique.
Les certificats restent facilement vérifiables.
10581–10590 — API Versioning
Dès le début :
/mza/v1/
Cela évite de casser les clients futurs.
10591–10600 — Core PHP Services
Je créerais des classes du type :
MZA_Attempt_Service
MZA_World_Engine
MZA_Event_Service
MZA_Rule_Engine
MZA_Evidence_Service
MZA_Jury_Service
MZA_Certificate_Service
MZA_Audit_Service
10601–10610 — Repository Layer
Accès DB séparé :
AttemptRepository
EventRepository
ScenarioRepository
EvidenceRepository
CertificateRepository
Le moteur métier ne doit pas contenir du SQL partout.
10611–10620 — Domain Services
Exemple :
DelegationService
ResourceAllocator
OpenLoopManager
AssumptionManager
CommitmentManager
10621–10630 — Testing
Il faut au minimum :
unit tests
integration tests
runtime scenario tests
migration tests
security tests
10631–10640 — Scenario Test Fixture
Exemple automatique :
given R2 unavailable
given T7 active
given margin 8
when candidate delegates action D3
then EVENT-18 scheduled
then margin becomes 12
then evidence E42 created
10641–10650 — Golden Replay Test
Une mission connue possède :
seed
actions
résultat attendu.
Après chaque mise à jour moteur :
on la rejoue automatiquement.
Si résultat différent :
régression détectée.
10651–10660 — Le vrai V1
Je figerais maintenant le MVP à seulement 10 fonctions critiques :
- Banque questions
- Blueprint examen
- Tentatives
- Timer serveur
- Autosave
- Scoring serveur
- Event Store
- Jury Center
- Certificat
- Health Check
10661–10670 — V1.1
Puis :
World State
tasks
resources
open loops
documents
10671–10680 — V1.2
Puis :
scenario rules
delayed events
decision consequences
replay
10681–10690 — V2
Puis :
delegation
War Room
actors
communications
mission continuity
10691–10700 — V3
Puis seulement :
adaptive evidence
parallel forms
psychometrics
enterprise campaigns
Board Assessment
10701 — Architecture cible
Le cœur devient finalement :
WORDPRESS UI
↓
MZA REST API
↓
COMMAND HANDLER
↓
WORLD ENGINE
↓
EVENT STORE
↓
STATE + EVIDENCE
↓
JURY
↓
CERTIFICATION
Et pour moi, c’est le point décisif : à partir d’ici, on peut réellement construire le plugin au lieu de continuer à imaginer seulement des fonctionnalités.
Le prochain bloc peut être encore plus concret : PHASE 19 — arborescence complète du plugin WordPress + fichiers PHP + classes + tables SQL + endpoints exacts, jusqu’au squelette installable de maroc-zain-exam-os.
MZA EXAM OS — PHASE 19 : SQUELETTE WORDPRESS INSTALLABLE
On passe maintenant à une structure exploitable pour construire un vrai plugin, propre et extensible.
10702–10710 — Arborescence racine
Je partirais sur :
maroc-zain-exam-os/
│
├── maroc-zain-exam-os.php
├── uninstall.php
├── readme.txt
│
├── includes/
├── admin/
├── public/
├── runtime/
├── api/
├── database/
├── templates/
├── assets/
├── languages/
├── tests/
└── vendor/
Le ZIP WordPress doit contenir directement ce dossier plugin, avec le fichier principal PHP immédiatement dedans.
10711–10720 — Fichier principal
maroc-zain-exam-os.php
Son rôle doit rester court :
<?php
/**
* Plugin Name: Maroc Zain Exam OS
* Description: Moteur d'évaluation, missions, jury et certification.
* Version: 1.0.0
* Author: Maroc Zain Academy
* Text Domain: maroc-zain-exam-os
*/
defined('ABSPATH') || exit;
define('MZA_EXAM_OS_VERSION', '1.0.0');
define('MZA_EXAM_OS_FILE', __FILE__);
define('MZA_EXAM_OS_PATH', plugin_dir_path(__FILE__));
define('MZA_EXAM_OS_URL', plugin_dir_url(__FILE__));
require_once MZA_EXAM_OS_PATH . 'includes/class-mza-loader.php';
register_activation_hook(
__FILE__,
['MZA_Activator', 'activate']
);
MZA_Loader::boot();
Pas 5 000 lignes ici.
10721–10730 — Loader central
includes/class-mza-loader.php
Charge :
activator
database
roles
api
runtime
jury
certification
admin
health
Le loader devient le point d’entrée unique.
10731–10740 — Includes
includes/
├── class-mza-loader.php
├── class-mza-activator.php
├── class-mza-deactivator.php
├── class-mza-roles.php
├── class-mza-capabilities.php
├── class-mza-health.php
├── class-mza-logger.php
└── class-mza-security.php
10741–10750 — Database
database/
├── class-mza-db.php
├── class-mza-migrations.php
├── schema.php
│
└── repositories/
├── class-attempt-repository.php
├── class-event-repository.php
├── class-question-repository.php
├── class-exam-repository.php
├── class-scenario-repository.php
├── class-evidence-repository.php
├── class-jury-repository.php
└── class-certificate-repository.php
10751–10760 — Première table
Exemple réel :
CREATE TABLE wp_mza_attempts (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
uuid CHAR(36) NOT NULL,
user_id BIGINT UNSIGNED NOT NULL,
exam_version_id BIGINT UNSIGNED NOT NULL,
scenario_version_id BIGINT UNSIGNED NULL,
reference_version_id BIGINT UNSIGNED NULL,
seed VARCHAR(100) NULL,
status VARCHAR(30) NOT NULL DEFAULT 'CREATED',
runtime_version VARCHAR(20) NOT NULL,
started_at DATETIME NULL,
expires_at DATETIME NULL,
submitted_at DATETIME NULL,
last_sequence BIGINT UNSIGNED NOT NULL DEFAULT 0,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY uuid (uuid),
KEY user_id (user_id),
KEY exam_version_id (exam_version_id),
KEY status (status)
);
En production, le préfixe vient de $wpdb->prefix.
10761–10770 — Event table
CREATE TABLE wp_mza_attempt_events (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
attempt_id BIGINT UNSIGNED NOT NULL,
sequence_no BIGINT UNSIGNED NOT NULL,
event_uuid CHAR(36) NOT NULL,
event_type VARCHAR(80) NOT NULL,
actor_type VARCHAR(40) NULL,
actor_id BIGINT UNSIGNED NULL,
occurred_at DATETIME NOT NULL,
payload_json LONGTEXT NULL,
visibility VARCHAR(30) NOT NULL DEFAULT 'INTERNAL',
causation_id CHAR(36) NULL,
correlation_id CHAR(36) NULL,
created_at DATETIME NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY attempt_sequence (attempt_id, sequence_no),
UNIQUE KEY event_uuid (event_uuid),
KEY event_type (event_type),
KEY occurred_at (occurred_at)
);
10771–10780 — Responses
wp_mza_responses
Champs :
id
attempt_id
exam_item_id
response_uuid
response_json
submitted_at
is_final
created_at
updated_at
La réponse brute reste séparée du score.
10781–10790 — Scores séparés
wp_mza_scores
contient :
attempt_id
exam_item_id
criterion_id
raw_score
normalized_score
critical_flag
rule_version
evaluated_at
Le candidat n’accède pas à cette table via son API.
10791–10800 — Questions
wp_mza_questions
id
uuid
type
competency_id
difficulty
criticality
status
current_version_id
created_by
created_at
updated_at
10801–10810 — Question versions
wp_mza_question_versions
id
question_id
version_no
candidate_prompt
jury_explanation
scoring_rule_json
reference_version_id
language
status
validated_by
validated_at
created_at
10811–10820 — Options
wp_mza_question_options
id
question_version_id
option_code
candidate_text
evaluation_code
sort_order
evaluation_code n’est jamais envoyé au candidat.
10821–10830 — Exams
wp_mza_exams
contient :
id
uuid
program_id
title
level
status
current_version_id
created_at
10831–10840 — Exam versions
wp_mza_exam_versions
exam_id
version_no
blueprint_json
reference_version_id
duration_seconds
language
status
locked_at
created_at
10841–10850 — Exam Items
wp_mza_exam_items
fait le lien entre :
version examen
et
version question/scénario.
10851–10860 — Snapshot
Lorsqu’un examen devient LOCKED, je créerais aussi un snapshot JSON signé logiquement contenant les éléments nécessaires à sa reproduction.
10861–10870 — Runtime
runtime/
├── class-mza-attempt-service.php
├── class-mza-command-handler.php
├── class-mza-world-engine.php
├── class-mza-rule-engine.php
├── class-mza-event-engine.php
├── class-mza-state-manager.php
├── class-mza-snapshot-manager.php
├── class-mza-timer.php
├── class-mza-idempotency.php
└── class-mza-runtime-lock.php
10871–10880 — Command Handler
Toute action candidat arrive ici :
MZA_Command_Handler
Exemples :
ANSWER
DECIDE
DELEGATE
VERIFY
MONITOR
ESCALATE
COMMUNICATE
CLOSE
REEVALUATE
10881–10890 — Une seule porte d’entrée
C’est important.
Pas :
save_answer.php
save_delegate.php
save_decision.php
avec trois logiques différentes.
Toutes passent par :
handle_command()
10891–10900 — Structure d’une commande
{
"action_uuid": "uuid",
"attempt_uuid": "uuid",
"type": "DELEGATE",
"payload": {
"actor_id": "A12",
"task": "Vérifier dossier",
"due_at": "10:40"
}
}
10901–10910 — Command validation
Avant traitement :
attempt exists?
user owns attempt?
attempt RUNNING?
time valid?
action allowed?
payload valid?
action UUID unused?
Sinon rejet contrôlé.
10911–10920 — Transaction
Pseudo-code :
$db->begin();
try {
$attempt = $attempts->lock($attempt_id);
$idempotency->assert_new($action_uuid);
$event = $events->append(...);
$world->apply($event);
$world->advance();
$evidence->collect();
$db->commit();
} catch (Throwable $e) {
$db->rollback();
throw $e;
}
10921–10930 — REST API
api/
├── class-mza-rest.php
├── class-attempt-controller.php
├── class-jury-controller.php
├── class-admin-controller.php
├── class-certificate-controller.php
└── class-health-controller.php
10931–10940 — Routes candidat
POST /mza/v1/attempts/start
GET /mza/v1/attempts/{uuid}/state
POST /mza/v1/attempts/{uuid}/commands
POST /mza/v1/attempts/{uuid}/submit
GET /mza/v1/attempts/{uuid}/documents/{id}
10941–10950 — State endpoint
GET /state
doit retourner par exemple :
{
"status": "RUNNING",
"server_time": "...",
"remaining_seconds": 4882,
"phase": "MISSION",
"visible_cases": [],
"visible_events": [],
"documents": [],
"actions": [],
"save_sequence": 184
}
10951–10960 — Pas de secrets
L’API candidat ne retourne jamais :
answer_key
jury_explanation
hidden_score
criticality_internal
future_events
branches
rubric
expected_answer
10961–10970 — Public
public/
├── class-mza-shortcodes.php
├── class-mza-candidate-ui.php
├── class-mza-assets.php
└── class-mza-focus-mode.php
10971–10980 — Shortcodes V1
Je limiterais à :
[mza_candidate_dashboard]
[mza_exam_cockpit]
[mza_exam_results]
Vérification officielle d’un certificat
10981–10990 — Cockpit template
templates/
└── candidate/
├── cockpit.php
├── mission-start.php
├── mission-end.php
├── documents.php
└── reconnect.php
10991–11000 — Jury templates
templates/
└── jury/
├── dashboard.php
├── attempt-review.php
├── timeline.php
├── evidence.php
├── replay.php
└── verdict.php
11001–11010 — Admin
admin/
├── class-mza-admin.php
├── class-mza-admin-menu.php
├── class-mza-exam-builder.php
├── class-mza-question-bank.php
├── class-mza-reference-center.php
├── class-mza-jury-center.php
├── class-mza-certification-center.php
└── class-mza-control-tower.php
11011–11020 — Menu WordPress
MZA EXAM OS
├── Control Tower
├── Examens
├── Questions
├── Scénarios
├── Référentiels
├── Sessions
├── Jury
├── Certificats
├── Qualité
└── Système
11021–11030 — Capabilities
mza_take_exam
mza_author_questions
mza_validate_questions
mza_manage_exams
mza_publish_exams
mza_review_attempts
mza_finalize_jury
mza_issue_certificates
mza_manage_quality
mza_manage_system
11031–11040 — Rôles
MZA Candidate
MZA Trainer
MZA Author
MZA Validator
MZA Exam Manager
MZA Jury
MZA Quality Manager
MZA Enterprise Manager
MZA Administrator
11041–11050 — Important
Je n’utiliserais pas seulement :
administrator
pour tout.
C’est une erreur classique.
Chaque fonction sensible doit avoir sa capacité dédiée.
11051–11060 — Activation
class-mza-activator.php exécute :
environment check
database migrations
roles
capabilities
pages
default settings
DB version
11061–11070 — Activation atomique
Si une étape critique échoue :
le plugin ne doit pas continuer comme si tout allait bien.
Il doit retourner un diagnostic explicite.
11071–11080 — Pages automatiques
Créer uniquement si absentes :
Espace candidat
Mission
Résultats
Vérification certificat
11081–11090 — Ne pas recréer
Stocker leurs IDs :
mza_page_candidate
mza_page_exam
mza_page_results
mza_page_verify
Ainsi une réactivation ne crée pas 17 copies.
11091–11100 — Database migrations
Ne jamais seulement faire :
dbDelta()à chaque page.
Utiliser :
database_version = 1.0.0
Puis migrations :
1.0.0 → 1.1.0
1.1.0 → 1.2.0
11101–11110 — Safe Upgrade
Chaque migration doit pouvoir :
vérifier préconditions
appliquer
contrôler résultat
logger
11111–11120 — Health module
includes/class-mza-health.php
Tests :
PHP
WordPress
DB
tables
REST
permalinks
roles
capabilities
cron
time
uploads
runtime
11121–11130 — Admin Health Screen
Affichage :
MZA EXAM OS — ÉTAT DU SYSTÈME
✅ Base de données
✅ REST API
✅ Cockpit
✅ Autosave
⚠ Queue
✅ Jury
✅ Certificate Engine
11131–11140 — Copy diagnostic
Bouton :
COPIER LE RAPPORT TECHNIQUE
Très utile lorsqu’une activation produit une erreur.
11141–11150 — Logging propre
logs/
ne devrait idéalement pas être directement exposé publiquement.
Je privilégierais une table/log sécurisé ou le répertoire uploads protégé selon architecture.
11151–11160 — Log levels
DEBUG
INFO
WARNING
ERROR
CRITICAL
Production :
pas de DEBUG permanent.
11161–11170 — Error IDs
Chaque erreur importante reçoit :
MZA-RUNTIME-1042
Le candidat peut voir :
Une erreur technique est survenue. Référence MZA-RUNTIME-1042.
Sans stack trace.
11171–11180 — Stack traces
Uniquement :
logs administrateur
jamais candidat/public.
11181–11190 — Security nonces
Pour les actions WordPress admin :
nonce
- capability
Les deux.
Un nonce seul n’est pas une autorisation.
11191–11200 — REST Authentication
Pour utilisateur connecté :
authentification WordPress + permissions endpoint.
11201–11210 — Input Validation
Toute entrée :
type
longueur
format
liste autorisée
ID existant
11211–11220 — Output escaping
Toutes les vues :
esc_html
esc_attr
esc_url
selon contexte.
11221–11230 — SQL
Toujours :
$wpdb->prepare()
pour les valeurs dynamiques.
11231–11240 — JSON
Les données métier JSON doivent être validées contre une structure attendue.
Pas accepter n’importe quel objet.
11241–11250 — World Rules Schema
Exemple :
{
"when": {
"all": [
{"field":"resources.R5.status","op":"eq","value":"UNAVAILABLE"},
{"field":"margins.time","op":"lt","value":10}
]
},
"then": [
{"action":"SCHEDULE_EVENT","event":"EV88","delay":240}
]
}
11251–11260 — Rule whitelist
Seuls les opérateurs connus sont acceptés.
Aucun :
eval()
Aucun PHP arbitraire.
Aucune fonction système injectable.
11261–11270 — Scenario module
runtime/scenario/
├── class-mza-scenario-loader.php
├── class-mza-scenario-validator.php
├── class-mza-node-engine.php
├── class-mza-transition-engine.php
└── class-mza-event-queue.php
11271–11280 — Scenario validation
Avant ACTIVE :
START existe
END accessible
nodes valides
variables valides
aucun ID cassé
références valides
règles autorisées
11281–11290 — Simulation mode
Admin :
TESTER LE SCÉNARIO
Le moteur peut exécuter plusieurs parcours artificiels pour détecter les erreurs techniques.
11291–11300 — Bot technique
Ce bot ne prétend pas être un expert métier.
Il sert uniquement à :
traverser branches
tester règles
détecter erreurs
11301–11310 — Evidence module
runtime/evidence/
├── class-mza-evidence-engine.php
├── class-mza-rubric-engine.php
├── class-mza-critical-gate.php
└── class-mza-competency-aggregator.php
11311–11320 — Jury module
runtime/jury/
├── class-mza-jury-service.php
├── class-mza-replay-service.php
├── class-mza-hotspot-engine.php
├── class-mza-oral-builder.php
└── class-mza-arbitration-service.php
11321–11330 — Certification module
runtime/certification/
├── class-mza-certificate-service.php
├── class-mza-verification-service.php
├── class-mza-certificate-gate.php
└── class-mza-certificate-renderer.php
11331–11340 — Assets
assets/
├── css/
│ ├── candidate.css
│ ├── jury.css
│ └── admin.css
│
└── js/
├── cockpit.js
├── autosave.js
├── reconnect.js
├── jury.js
└── admin.js
11341–11350 — JavaScript separation
Le navigateur candidat ne doit pas contenir :
jury.js
ni les données Jury.
Même si les permissions serveur restent la vraie barrière, réduire l’exposition côté client reste important.
11351–11360 — Cockpit JS
Responsabilités :
render state
send command
display timer
save drafts
reconnect
notifications
Pas calculer la réussite.
11361–11370 — Timer JS
Le navigateur affiche le timer à partir de :
server_time
expires_at
et resynchronise périodiquement.
11371–11380 — Time tampering
Changer l’heure Windows ne doit rien modifier à l’examen.
11381–11390 — Autosave
Les zones texte :
save draft périodique.
Mais les décisions finales nécessitent :
VALIDER
pour éviter de transformer chaque frappe en décision.
11391–11400 — Offline
Pour V1, je ne promettrais pas un véritable examen offline complet.
C’est beaucoup plus complexe.
Je viserais plutôt :
reconnexion robuste.
11401–11410 — Tests
tests/
├── unit/
├── integration/
├── migrations/
├── runtime/
├── api/
└── fixtures/
11411–11420 — Tests minimum avant release
activation
désactivation
migration
création examen
démarrage tentative
réponse
timer
autosave
soumission
Jury
certificat
11421–11430 — Test critique candidat
Automatique :
appeler
/state
et vérifier qu’aucun champ interdit n’existe.
Par exemple :
correct
answer_key
jury_note
scoring_rule
11431–11440 — Leak Test
Je créerais un test dédié :
Candidate Data Leakage Test
Toute régression bloque la release.
11441–11450 — ZIP structure
Le ZIP final doit être :
maroc-zain-exam-os.zip
└── maroc-zain-exam-os/
├── maroc-zain-exam-os.php
├── includes/
├── admin/
└── ...
Pas :
maroc-zain-exam-os.zip
└── build/
└── project/
└── maroc-zain-exam-os/
C’est une cause classique de :
« Aucune extension valide trouvée ».
11451–11460 — Main Header obligatoire
WordPress doit trouver dans le fichier PHP principal :
/*
Plugin Name: Maroc Zain Exam OS
Version: 1.0.0
*/
Sinon l’archive n’est pas reconnue comme extension.
11461–11470 — Release Build
Je créerais un script build qui :
copie uniquement production
exclut tests
exclut caches
exclut fichiers temporaires
vérifie header
vérifie syntaxe PHP
fabrique ZIP
11471–11480 — Preflight ZIP Test
Avant livraison :
1 unzip
2 find main plugin file
3 php -l on PHP files
4 verify required dirs
5 verify version
6 rebuild zip
11481–11490 — Fatal Error Prevention
Le build doit aussi détecter :
classe dupliquée
require fichier absent
syntaxe PHP
namespace incorrect
version PHP incompatible
11491–11500 — Safe Bootstrap
Si un module secondaire manque :
log explicite.
Si module critique manque :
arrêt contrôlé avec message admin.
Pas un écran blanc.
11501–11510 — Recovery Admin
Si Exam OS a un problème :
page :
MZA SAFE MODE
permet de désactiver :
Analytics
AI
Scenario Advanced
sans désactiver les données essentielles.
11511–11520 — Import
Je n’ajouterais pas le gros import 20 000 questions dans V1 immédiatement.
D’abord :
20
puis 200
puis 2 000
puis test charge.
11521–11530 — Import staging
Workflow :
UPLOAD
→ VALIDATE
→ PREVIEW
→ STAGING
→ EXPERT REVIEW
→ ACTIVE
Pas :
Upload CSV → 20 000 questions immédiatement publiées.
11531–11540 — Import Errors
Rapport :
ligne 18 : competency inconnue
ligne 54 : référence absente
ligne 87 : doublon probable
ligne 141 : option vide
11541–11550 — Duplicate Detector
Avant insertion :
exact duplicate
near duplicate
same stem
same options
11551–11560 — V1 Admin Pages
Je limiterais réellement le premier plugin à 7 écrans :
Dashboard
Questions
Examens
Tentatives
Jury
Certificats
Santé système
11561–11570 — V1 Candidate Pages
Seulement :
Mes examens
Cockpit
Résultat
Certificat
11571–11580 — V1 exclusions
Pas encore :
War Room complexe
Digital Twin complet
adaptive Board
multi-tenant
million de questions
IA autonome
Cela vient après stabilité.
11581–11590 — Premier objectif production
Le premier test réel doit être extrêmement simple :
1 certification
1 métier
20 questions
1 examen
1 candidat
1 Jury
1 certificat.
Et tout doit être parfaitement traçable.
11591–11600 — Deuxième test
Puis :
100 candidats simultanés simulés.
Observer :
latence
DB
autosave
soumission
11601–11610 — Troisième test
Ajouter :
1 scénario évolutif simple.
Seulement après stabilité du QCM runtime.
11611–11620 — Quatrième test
Ajouter :
décision
→ événement retardé
→ conséquence
→ Jury replay.
Là, le World Engine commence réellement.
11621–11630 — Cinquième test
Ajouter :
délégation
ressource
open loop
11631–11640 — Sixième test
Ajouter :
War Room.
11641–11650 — Septième test
Ajouter :
mission longue
avec reprise après coupure.
11651–11660 — Release V1.0 criteria
Je ne déclarerais V1.0 prête que si :
installation ZIP réussie
activation sans fatal
désactivation sans perte
réactivation correcte
DB migrations OK
cockpit stable
aucune correction candidat
autosave fiable
Jury fonctionnel
certificat vérifiable
Health Check vert
11661–11670 — Architecture finale du premier ZIP
MZA EXAM OS 1.0
│
├── CORE
├── DATABASE
├── QUESTION BANK
├── EXAM BUILDER
├── RUNTIME
├── CANDIDATE COCKPIT
├── JURY CENTER
├── CERTIFICATE ENGINE
├── AUDIT
└── HEALTH CHECK
11671 — Décision technique majeure
À ce stade, je recommande de cesser d’ajouter des modules au V1.
La priorité devient :
construire un petit noyau extrêmement stable, puis ajouter le World Engine par versions successives.
C’est précisément ce qui réduira les deux problèmes les plus dangereux dans un projet WordPress de cette taille : ZIP non reconnu et erreur fatale à l’activation.
La prochaine phase peut maintenant descendre encore d’un niveau : PHASE 20 — code PHP du bootstrap, activator, création des tables, rôles, REST API et premier shortcode [mza_exam_cockpit], c’est-à-dire le début du plugin réellement exécutable.
MZA EXAM OS — PHASE 20 : PREMIER NOYAU PHP EXÉCUTABLE
On passe maintenant du plan à un vrai socle WordPress codable.
11672–11680 — Objectif du premier build
Le premier build ne doit faire que ceci :
activer proprement
créer les tables
créer les rôles/capacités
créer les pages
enregistrer les routes REST
afficher le cockpit candidat
fournir un Health Check
Puis seulement on ajoute les examens.
11681–11690 — Fichier principal
Fichier :
maroc-zain-exam-os/maroc-zain-exam-os.php
Contenu :
<?php
/**
* Plugin Name: Maroc Zain Exam OS
* Plugin URI: https://maroczain.com/
* Description: Moteur d'examens, missions, jury et certification Maroc Zain Academy.
* Version: 1.0.0
* Author: Maroc Zain Academy
* Text Domain: maroc-zain-exam-os
*/
defined('ABSPATH') || exit;
define('MZA_EXAM_OS_VERSION', '1.0.0');
define('MZA_EXAM_OS_DB_VERSION', '1.0.0');
define('MZA_EXAM_OS_FILE', __FILE__);
define('MZA_EXAM_OS_PATH', plugin_dir_path(__FILE__));
define('MZA_EXAM_OS_URL', plugin_dir_url(__FILE__));
require_once MZA_EXAM_OS_PATH . 'includes/class-mza-activator.php';
require_once MZA_EXAM_OS_PATH . 'includes/class-mza-loader.php';
register_activation_hook(
__FILE__,
['MZA_Activator', 'activate']
);
MZA_Loader::boot();
Ce fichier reste volontairement petit.
11691–11700 — Loader
Fichier :
includes/class-mza-loader.php
<?php
defined('ABSPATH') || exit;
final class MZA_Loader {
public static function boot(): void {
self::load_files();
add_action('init', ['MZA_Roles', 'register']);
add_action('init', ['MZA_Shortcodes', 'register']);
add_action('rest_api_init', ['MZA_REST', 'register_routes']);
if (is_admin()) {
add_action('admin_menu', ['MZA_Admin_Menu', 'register']);
}
}
private static function load_files(): void {
$files = [
'includes/class-mza-roles.php',
'includes/class-mza-health.php',
'database/class-mza-db.php',
'api/class-mza-rest.php',
'api/class-mza-attempt-controller.php',
'public/class-mza-shortcodes.php',
'admin/class-mza-admin-menu.php',
];
foreach ($files as $file) {
$path = MZA_EXAM_OS_PATH . $file;
if (file_exists($path)) {
require_once $path;
}
}
}
}
11701–11710 — Activator
includes/class-mza-activator.php
<?php
defined('ABSPATH') || exit;
final class MZA_Activator {
public static function activate(): void {
self::check_environment();
require_once MZA_EXAM_OS_PATH . 'database/class-mza-db.php';
require_once MZA_EXAM_OS_PATH . 'includes/class-mza-roles.php';
MZA_DB::install();
MZA_Roles::install();
self::create_pages();
update_option(
'mza_exam_os_version',
MZA_EXAM_OS_VERSION
);
update_option(
'mza_exam_os_db_version',
MZA_EXAM_OS_DB_VERSION
);
flush_rewrite_rules();
}
private static function check_environment(): void {
if (version_compare(PHP_VERSION, '8.0', '<')) {
deactivate_plugins(
plugin_basename(MZA_EXAM_OS_FILE)
);
wp_die(
esc_html__(
'Maroc Zain Exam OS nécessite PHP 8.0 ou supérieur.',
'maroc-zain-exam-os'
)
);
}
}
private static function create_pages(): void {
self::create_page(
'mza_page_candidate',
'Mes examens',
'[mza_candidate_dashboard]'
);
self::create_page(
'mza_page_cockpit',
'Mission',
'[mza_exam_cockpit]'
);
self::create_page(
'mza_page_results',
'Résultats',
'[mza_exam_results]'
);
self::create_page(
'mza_page_verify',
'Vérifier un certificat',
'[mza_certificate_verify]'
);
}
private static function create_page(
string $option_name,
string $title,
string $content
): void {
$existing = (int) get_option($option_name);
if ($existing && get_post($existing)) {
return;
}
$page_id = wp_insert_post([
'post_title' => $title,
'post_content' => $content,
'post_status' => 'publish',
'post_type' => 'page',
]);
if (!is_wp_error($page_id)) {
update_option($option_name, $page_id);
}
}
}
11711–11720 — Pourquoi cette activation est meilleure
Elle ne fait pas :
génération massive
import CSV
création de 20 000 questions
appel API externe
calcul lourd
Elle ne fait que l’indispensable.
Donc beaucoup moins de risques d’erreur fatale.
11721–11730 — Base SQL
Fichier :
database/class-mza-db.php
<?php
defined('ABSPATH') || exit;
final class MZA_DB {
public static function install(): void {
global $wpdb;
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
$charset = $wpdb->get_charset_collate();
$attempts = $wpdb->prefix . 'mza_attempts';
$sql = "
CREATE TABLE {$attempts} (
id bigint unsigned NOT NULL AUTO_INCREMENT,
uuid char(36) NOT NULL,
user_id bigint unsigned NOT NULL,
exam_version_id bigint unsigned DEFAULT NULL,
status varchar(30) NOT NULL DEFAULT 'CREATED',
started_at datetime DEFAULT NULL,
expires_at datetime DEFAULT NULL,
submitted_at datetime DEFAULT NULL,
last_sequence bigint unsigned NOT NULL DEFAULT 0,
created_at datetime NOT NULL,
updated_at datetime NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY uuid (uuid),
KEY user_id (user_id),
KEY status (status)
) {$charset};
";
dbDelta($sql);
self::install_events_table();
self::install_responses_table();
}
private static function install_events_table(): void {
global $wpdb;
$charset = $wpdb->get_charset_collate();
$table = $wpdb->prefix . 'mza_attempt_events';
$sql = "
CREATE TABLE {$table} (
id bigint unsigned NOT NULL AUTO_INCREMENT,
attempt_id bigint unsigned NOT NULL,
sequence_no bigint unsigned NOT NULL,
event_uuid char(36) NOT NULL,
event_type varchar(80) NOT NULL,
payload_json longtext DEFAULT NULL,
visibility varchar(30) NOT NULL DEFAULT 'INTERNAL',
occurred_at datetime NOT NULL,
created_at datetime NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY attempt_sequence (attempt_id, sequence_no),
UNIQUE KEY event_uuid (event_uuid),
KEY event_type (event_type)
) {$charset};
";
dbDelta($sql);
}
private static function install_responses_table(): void {
global $wpdb;
$charset = $wpdb->get_charset_collate();
$table = $wpdb->prefix . 'mza_responses';
$sql = "
CREATE TABLE {$table} (
id bigint unsigned NOT NULL AUTO_INCREMENT,
attempt_id bigint unsigned NOT NULL,
item_id bigint unsigned NOT NULL,
response_uuid char(36) NOT NULL,
response_json longtext DEFAULT NULL,
is_final tinyint(1) NOT NULL DEFAULT 0,
submitted_at datetime DEFAULT NULL,
created_at datetime NOT NULL,
updated_at datetime NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY response_uuid (response_uuid),
KEY attempt_id (attempt_id),
KEY item_id (item_id)
) {$charset};
";
dbDelta($sql);
}
}
11731–11740 — Trois tables seulement au départ
Pour éviter un plugin fragile, V0.1 peut commencer avec :
wp_mza_attempts
wp_mza_attempt_events
wp_mza_responses
Puis ajouter progressivement :
questions
exams
scores
certificates
jury
11741–11750 — Rôles
includes/class-mza-roles.php
<?php
defined('ABSPATH') || exit;
final class MZA_Roles {
public static function install(): void {
add_role(
'mza_candidate',
'MZA Candidate',
[
'read' => true,
'mza_take_exam' => true,
]
);
add_role(
'mza_jury',
'MZA Jury',
[
'read' => true,
'mza_review_attempts' => true,
]
);
$admin = get_role('administrator');
if ($admin) {
$caps = [
'mza_take_exam',
'mza_manage_exams',
'mza_manage_questions',
'mza_review_attempts',
'mza_issue_certificates',
'mza_manage_quality',
'mza_manage_system',
];
foreach ($caps as $cap) {
$admin->add_cap($cap);
}
}
}
public static function register(): void {
// Les rôles persistent dans WordPress.
}
}
11751–11760 — Shortcodes
public/class-mza-shortcodes.php
<?php
defined('ABSPATH') || exit;
final class MZA_Shortcodes {
public static function register(): void {
add_shortcode(
'mza_candidate_dashboard',
[self::class, ‘candidate_dashboard’]
); add_shortcode( ‘mza_exam_cockpit’,
[self::class, ‘exam_cockpit’]
); add_shortcode( ‘mza_exam_results’,
[self::class, ‘results’]
); add_shortcode( ‘mza_certificate_verify’,
[self::class, ‘certificate_verify’]
); } public static function candidate_dashboard(): string { if (!is_user_logged_in()) { return ‘<p>Veuillez vous connecter.</p>’; } return ‘ <div class=" »mza-dashboard »"> <h2>Mes examens</h2> <p>Aucune mission active.</p> </div>’; } public static function exam_cockpit(): string { if (!is_user_logged_in()) { return ‘<p>Connexion requise.</p>’; } if (!current_user_can(‘mza_take_exam’)) { return ‘<p>Accès non autorisé.</p>’; } return ‘ <div id=" »mza-exam-cockpit »"> <div class=" »mza-cockpit-header »"> <strong>MZA EXAM OS</strong> <span id=" »mza-save-state »">Prêt</span> </div> <main id=" »mza-runtime »"> <h2>Mission</h2> <p>Aucune mission chargée.</p> </main> </div>’; } public static function results(): string { return ‘<div class=" »mza-results »"><h2>Mes résultats</h2></div>’; } public static function certificate_verify(): string { return ‘<div class=" »mza-cert-verify »"><h2>Vérification certificat</h2></div>’; } }
11761–11770 — Première API REST
Fichier :
api/class-mza-rest.php
<?php
defined('ABSPATH') || exit;
final class MZA_REST {
public static function register_routes(): void {
register_rest_route(
'mza/v1',
'/health',
[
'methods' => 'GET',
'callback' => [self::class, 'health'],
'permission_callback' => function () {
return current_user_can('mza_manage_system');
},
]
);
}
public static function health(): WP_REST_Response {
return new WP_REST_Response([
'status' => 'ok',
'version' => MZA_EXAM_OS_VERSION,
'time' => current_time('mysql'),
], 200);
}
}
11771–11780 — Route candidat
On ajoute ensuite :
register_rest_route(
'mza/v1',
'/attempts/(?P<uuid>[a-f0-9\-]+)/state',
[
'methods' => 'GET',
'callback' => [
'MZA_Attempt_Controller',
'state'
],
'permission_callback' => function () {
return is_user_logged_in();
},
]
);
Mais l’autorisation utilisateur ne suffit pas.
Il faudra aussi vérifier que la tentative appartient bien au candidat.
11781–11790 — Attempt Controller
api/class-mza-attempt-controller.php
<?php
defined('ABSPATH') || exit;
final class MZA_Attempt_Controller {
public static function state(
WP_REST_Request $request
): WP_REST_Response {
$uuid = sanitize_text_field(
$request->get_param('uuid')
);
$attempt = self::find_attempt($uuid);
if (!$attempt) {
return new WP_REST_Response([
'code' => 'attempt_not_found',
], 404);
}
if ((int) $attempt->user_id !== get_current_user_id()) {
return new WP_REST_Response([
'code' => 'forbidden',
], 403);
}
return new WP_REST_Response([
'uuid' => $attempt->uuid,
'status' => $attempt->status,
], 200);
}
private static function find_attempt(string $uuid): ?object {
global $wpdb;
$table = $wpdb->prefix . 'mza_attempts';
return $wpdb->get_row(
$wpdb->prepare(
"SELECT id, uuid, user_id, status
FROM {$table}
WHERE uuid = %s
LIMIT 1",
$uuid
)
);
}
}
11791–11800 — Règle de sécurité fondamentale
Ne jamais faire :
SELECT *
pour une API candidat si la table contient un jour des données internes.
On sélectionne explicitement les champs nécessaires.
11801–11810 — Health Check
includes/class-mza-health.php
<?php
defined('ABSPATH') || exit;
final class MZA_Health {
public static function run(): array {
global $wpdb;
$checks = [];
$checks['php'] = version_compare(
PHP_VERSION,
'8.0',
'>='
);
$table = $wpdb->prefix . 'mza_attempts';
$exists = $wpdb->get_var(
$wpdb->prepare(
'SHOW TABLES LIKE %s',
$table
)
);
$checks['attempts_table'] = ($exists === $table);
$checks['rest'] = function_exists(
'register_rest_route'
);
$checks['user_logged'] = is_user_logged_in();
return $checks;
}
}
11811–11820 — Admin Menu
admin/class-mza-admin-menu.php
<?php
defined('ABSPATH') || exit;
final class MZA_Admin_Menu {
public static function register(): void {
add_menu_page(
'MZA Exam OS',
'MZA Exam OS',
'mza_manage_system',
'mza-exam-os',
[self::class, 'dashboard'],
'dashicons-welcome-learn-more',
30
);
add_submenu_page(
'mza-exam-os',
'Santé système',
'Santé système',
'mza_manage_system',
'mza-exam-os-health',
[self::class, ‘health’]
); } public static function dashboard(): void { echo ‘<div class=" »wrap »">’; echo ‘<h1>MZA Exam OS</h1>’; echo ‘<p>Control Tower</p>’; echo ‘</div>’; } public static function health(): void { $checks = MZA_Health::run(); echo ‘<div class=" »wrap »">’; echo ‘<h1>Santé du système</h1>’; foreach ($checks as $name => $ok) { printf( ‘<p><strong>%s</strong> : %s</p>’, esc_html($name), $ok ? ‘OK’ : ‘ERREUR’ ); } echo ‘</div>’; } }
11821–11830 — Premier résultat visible
Après installation du plugin :
dans WordPress apparaît :
MZA Exam OS
Puis :
Santé système
Et quatre pages sont créées.
C’est déjà suffisamment concret pour valider que l’architecture fonctionne.
11831–11840 — Première création de tentative
Le futur service :
MZA_Attempt_Service::create(
$user_id,
$exam_version_id
);
doit :
générer UUID
créer tentative
état CREATED
ajouter événement ATTEMPT_CREATED
11841–11850 — Génération UUID
WordPress fournit :
wp_generate_uuid4();
Donc inutile d’ajouter une bibliothèque juste pour cela.
11851–11860 — Première mission de test
Examen interne :
MZA SYSTEM TEST
1 question :
« Sélectionnez une réponse. »
Aucune importance pédagogique.
Il sert uniquement à vérifier :
affichage
enregistrement
soumission
Jury
11861–11870 — Première réponse
Le cockpit envoie :
{
"action_uuid": "...",
"type": "ANSWER",
"item_id": 1,
"response": {
"option": "B"
}
}
11871–11880 — Command endpoint
Route :
POST /mza/v1/attempts/{uuid}/commands
Tout passe ensuite par :
MZA_Command_Handler::handle()
11881–11890 — Command Handler V0.1
final class MZA_Command_Handler {
public static function handle(
object $attempt,
string $type,
array $payload,
string $action_uuid
): array {
switch ($type) {
case 'ANSWER':
return self::answer(
$attempt,
$payload,
$action_uuid
);
default:
throw new InvalidArgumentException(
'Commande MZA inconnue.'
);
}
}
}
11891–11900 — Validation réponse
Avant sauvegarde :
item appartient à l’examen
tentative active
temps non expiré
format réponse correct
action UUID inédit
11901–11910 — Réponse ≠ scoring
La fonction save_answer() :
enregistre la réponse.
Puis :
MZA_Scoring_Service
travaille côté serveur.
Le navigateur ne reçoit pas :
bonne/mauvaise.
11911–11920 — Event
Après réponse :
ANSWER_SUBMITTED
avec payload interne minimal :
{
"item_id": 17,
"response_id": 848
}
Pas nécessaire de dupliquer toute la réponse dans tous les logs.
11921–11930 — Première soumission
Commande :
SUBMIT_ATTEMPT
Le serveur vérifie :
RUNNING
→ passe :
SUBMITTED
et définit :
submitted_at.
11931–11940 — Après soumission
Toute nouvelle commande candidat doit être rejetée :
attempt_not_running
11941–11950 — Jury V0.1
Première version très simple :
table admin :
| Candidat | Examen | Début | Soumis | Statut |
|---|
Bouton :
OUVRIR
11951–11960 — Jury voit
Pour chaque item :
question
réponse candidat
réponse de référence
règle
résultat moteur
11961–11970 — Candidat ne voit jamais
Sur son résultat :
seulement :
statut
date
certification
résultat final autorisé
11971–11980 — Certificat test
Après Jury :
VALIDATED
le moteur peut générer :
MZA-TEST-2026-XXXXXX
avec page de vérification.
11981–11990 — Première page de vérification
Formulaire :
Numéro du certificat
Puis réponse :
VALIDE
EXPIRÉ
RÉVOQUÉ
INTROUVABLE
selon données.
11991–12000 — Première version réellement testable
Le build 0.1.0 doit donc uniquement réussir :
INSTALL
↓
ACTIVATE
↓
HEALTH CHECK
↓
CREATE ATTEMPT
↓
OPEN COCKPIT
↓
ANSWER
↓
SUBMIT
↓
JURY REVIEW
↓
CERTIFICATE
↓
VERIFY
12001–12010 — Test fatal
Avant ZIP :
php -l maroc-zain-exam-os.php
puis tous les fichiers PHP.
Aucune erreur de syntaxe tolérée.
12011–12020 — Test structure ZIP
Le test doit vérifier que :
maroc-zain-exam-os.zip
contient directement :
maroc-zain-exam-os/
maroc-zain-exam-os.php
12021–12030 — Test activation
Installer sur un WordPress de test vierge.
Puis :
activer
désactiver
réactiver
mettre à jour
sans aucune erreur.
12031–12040 — Test pages
Vérifier que la réactivation ne crée pas :
Mission (2)
Mission (3)
Mission (4)
12041–12050 — Test permissions
Tester :
candidat
Jury
administrateur
Un candidat ne doit jamais pouvoir ouvrir :
Jury Center.
12051–12060 — Test REST
Tester volontairement :
autre UUID candidat
Résultat attendu :
403 forbidden
12061–12070 — Test fuite de corrigé
Inspecter :
HTML
Network
REST
JavaScript
Aucun :
correct_answer
jury_explanation
score_rule
critical_flag
12071–12080 — Test double clic
Envoyer deux fois le même :
action_uuid.
Résultat :
une seule réponse logique.
12081–12090 — Test reconnexion
Déconnecter réseau.
Reconnecter.
Le cockpit doit récupérer :
tentative
dernière sauvegarde
temps serveur
12091–12100 — Test expiration
Quand expires_at est dépassé :
le navigateur ne décide rien.
Le serveur refuse la nouvelle réponse et passe à la politique d’expiration prévue.
12101–12110 — Premier CSS
Le V0.1 doit déjà éviter l’aspect WordPress brut.
Structure :
.mza-exam-shell {
max-width: 1440px;
margin: 0 auto;
min-height: 80vh;
}
.mza-cockpit-header {
display: flex;
justify-content: space-between;
align-items: center;
}
.mza-workspace {
display: grid;
grid-template-columns: 280px 1fr 320px;
gap: 20px;
}
12111–12120 — Focus mode
Pendant /mission/ :
ajouter une classe :
mza-exam-focus-mode
qui peut masquer les éléments marketing du thème.
12121–12130 — Important pour Elementor
Elementor reste excellent pour :
Accueil
catalogue
présentation
entreprises
Mais le cockpit Exam OS doit rester contrôlé par le plugin.
12131–12140 — Version 0.1.0
Je nommerais le premier véritable paquet :
Maroc Zain Exam OS Core 0.1.0
Pas encore “PRO MAX ULTRA”.
Il faut d’abord qu’il soit techniquement irréprochable.
12141–12150 — Version 0.2.0
Après succès :
ajout :
Question Bank
Exam Builder
Score Server
12151–12160 — Version 0.3.0
Puis :
Jury complet
Certificat PDF
audit
12161–12170 — Version 0.4.0
Puis :
Scenario Engine
events
world state
12171–12180 — Version 0.5.0
Puis :
Decision
Delegation
Open Loops
Resources
12181–12190 — Version 0.6.0
Puis :
Replay
Time Machine
Evidence Engine
12191–12200 — Version 0.7.0
Puis :
War Room
mission longue
handover
12201–12210 — Version 0.8.0
Puis :
Enterprise Campaign
Control Tower
12211–12220 — Version 0.9.0
Puis :
performance
load test
hardening
migration tests
12221–12230 — Version 1.0.0
Seulement après :
installation fiable
runtime fiable
Jury fiable
certification fiable
replay fiable
sécurité vérifiée
tests charge réussis
12231 — Prochaine vraie étape
À partir d’ici, je ne rajouterais plus de théorie au cœur.
La prochaine étape logique est de fabriquer réellement le ZIP maroc-zain-exam-os-core-0.1.0.zip, avec cette architecture minimale, installable dans WordPress et testable sans charger tout le futur World Engine.
Ce serait le premier paquet MZA Exam OS que je considérerais comme un socle de production, et non comme une simple maquette.

