🎓 Formations professionnelles ✈️ Aérien • Tourisme • Management 🏆 Certifications

Former aujourd’hui. Exceller demain.

MZA EXAM OS — PHASE 13 : IMPERIAL OPERATIONS

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

email

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 :

  1. candidat revient ;
  2. serveur vérifie session ;
  3. recharge dernier état valide ;
  4. recalcule temps restant ;
  5. restitue événements déjà arrivés ;
  6. 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 :

  1. Banque questions
  2. Blueprint examen
  3. Tentatives
  4. Timer serveur
  5. Autosave
  6. Scoring serveur
  7. Event Store
  8. Jury Center
  9. Certificat
  10. 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 :

  1. Banque questions
  2. Blueprint examen
  3. Tentatives
  4. Timer serveur
  5. Autosave
  6. Scoring serveur
  7. Event Store
  8. Jury Center
  9. Certificat
  10. 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 :

CandidatExamenDébutSoumisStatut

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.