Le socle · le framework

Une application, c’est un ensemble de Workers.
Le framework fait le reste.

Socle V005 est le cadre de code commun à toutes nos applications. Il démarre, surveille et arrête des unités de traitement autonomes, expose leurs actions aux humains comme aux agents IA, et fournit tout l’outillage technique qu’une application réécrit d’habitude.

À quoi il sert

Socle V005 est un framework Java 21, bâti sur Spring Boot 4.1.2 et exécuté sur la machine virtuelle GraalVM Community Edition 21. Nous l’écrivons et nous le maintenons. Il en est à la lignée 5.11.

Son idée est simple. Une application est faite de Workers : des unités de traitement autonomes, chacune chargée d’une seule chose. Un orchestrateur commun, le MOP (Main Orchestrator Process), les démarre dans l’ordre, les surveille, relance celui qui tombe et arrête proprement l’ensemble. Le développeur écrit son métier ; le cycle de vie, la supervision, la journalisation, l’exposition des actions et la base technique sont déjà là.

La documentation de référence du framework le présente comme un cadre pour des applications « pilotées par les événements » et « AI-First ». Cinq principes la guident :

  • AI-First : chaque action d’un Worker devient un outil appelable par un agent IA ;
  • piloté par les événements : les Workers réagissent à ce qui arrive plutôt que de s’attendre ;
  • à base de Workers : un Worker, une responsabilité, un fichier ;
  • décisions déclaratives : les règles métier vivent dans des tables, pas dans le code compilé ;
  • observabilité intégrée : état, métriques et journaux sont fournis sans rien ajouter.

La même documentation dit aussi, à l’affirmative, où d’autres outils conviennent mieux : Spring Boot seul pour un simple CRUD, Temporal ou Camunda pour des processus humains longs, Spring Batch pour un traitement massif par lots.

Anatomie d'une application Socle V005 : le MOP au centre, les Workers autour, le KvBus, la TechDB, les portes REST et MCP

Le MOP, chef d’orchestre

Le MOP prend la main quand l’application est prête. Aucun Worker ne se planifie lui-même : c’est le MOP qui décide quand chacun travaille.

Il prépare le terrain

Il monte d’abord les données partagées et le bus d’événements, puis le superviseur et les métriques.

Il enregistre les Workers

Chaque Worker déclaré dans l’application est inscrit, avec sa priorité de démarrage.

Il les démarre dans l’ordre

Les Workers démarrent par priorité croissante. Si l’un échoue à s’initialiser, l’application refuse de démarrer : un défaut se voit tout de suite, pas trois jours plus tard.

Il publie les actions

Le registre des actions est construit, l’API d’administration ouverte, et l’application passe à l’état « en marche ».

Il surveille

Un Worker qui se déclare malade trois fois de suite est relancé automatiquement. Les Workers d’infrastructure (le serveur web, le tableau de bord, le moteur de règles…) sont exclus de cette relance automatique.

Il arrête proprement

À l’arrêt, il vide d’abord les pipelines en cours, puis ferme la porte d’entrée HTTP en premier, arrête les Workers métier, et l’infrastructure en dernier.

L’état du MOP suit un chemin fixe : initialisation, démarrage, marche, vidange, arrêt — plus un état d’erreur. L’arrêt se déclenche par le signal du système, par l’API d’administration ou par le superviseur.

Les Workers et leurs types

Un Worker répond à une interface courte : un nom, une initialisation, un démarrage, un cycle de travail, un arrêt, un état de santé et des statistiques. Il s’exécute à intervalle régulier, selon une expression cron (à cinq champs, avec des raccourcis comme @daily), ou seulement quand on l’appelle — on le dit alors passif. Deux exécutions cron d’un même Worker ne se chevauchent jamais.

Le framework livre des gabarits pour chaque forme de Worker. Le choix se fait par la question « mon Worker doit faire quoi ? ».

Les types de Workers de Socle V005 et la question qui mène à chacun

Passerelle (Gateway)

Appeler une API ou un service externe. L’appel est protégé dans cet ordre : limiteur de débit, coupe-circuit, nouvel essai.

Scrutation (Polling)

Une tâche répétée toutes les N millisecondes : relever une file, vérifier un état.

Planifié (Cron)

Une tâche à heure fixe, par exemple chaque nuit à trois heures.

Passif (Action)

Piloté uniquement par des appels REST ou MCP, jamais de lui-même.

Événementiel

Réagir aux événements internes du bus, ou consommer un sujet Kafka, sur des threads virtuels Java 21.

Agrégation

Regrouper des événements par clé sur une fenêtre de temps, en mémoire ou en base technique.

Pipeline

Enchaîner des étapes à la demande : moteur de pipeline V1, ou orchestrateur et étapes typées V2.

Récepteur de webhooks

Recevoir des appels HTTP entrants d’un service tiers et les transformer en événements.

Pages et API métier

Servir des pages HTML (Thymeleaf) ou des points d’API REST métier, à côté des Workers.

Des règles absolues encadrent l’écriture d’un Worker. Les six premières figurent en tête de chaque projet :

  1. un Worker par fichier Java ;
  2. l’abonnement au bus d’événements se fait uniquement à l’initialisation ;
  3. jamais de thread lancé à la main, de boucle infinie ni de planification maison : le MOP s’en charge ;
  4. les méthodes de l’interface ne laissent pas échapper d’exception générique ;
  5. chaque Worker est un composant Spring, injecté par son constructeur ;
  6. lecture bloquante pour le bus interne, lecture avec délai pour Kafka ou NATS.

Le guide destiné aux agents IA en ajoute d’autres, tout aussi concrètes : un état de santé qui répond en moins de dix millisecondes, un arrêt qu’on peut appeler deux fois sans dommage, des statistiques et des actions sûres en accès concurrent.

Les actions, en REST et en MCP

Un Worker publie ce qu’il sait faire sous forme d’actions. Chaque action est décrite une fois : son nom, sa description, ses paramètres typés, son mode synchrone ou asynchrone, si elle ne fait que lire, si elle demande une confirmation. Le framework découvre ces descriptions tout seul : aucun code de liaison à écrire.

Une même action est alors joignable par deux portes :

  • REST, pour un programme ou une interface : une liste des actions, un appel par action, un mode asynchrone qui rend la main tout de suite et se suit par un identifiant de tâche ;
  • MCP (Model Context Protocol), pour un agent IA : l’action devient un outil nommé worker__action, que l’agent découvre et appelle.

Chaque appel rend une enveloppe fixe — succès, données, erreur, durée — et chaque appel est consigné dans la base technique. Les paramètres sensibles sont masqués dans ce journal.

Un explorateur, MCPagger, présenté comme « le Swagger de Socle », génère pour chaque application une page qui liste ses actions et permet de les essayer, ainsi que leur description OpenAPI et MCP.

Le détail du pilotage par un agent a sa propre page : comment un agent IA pilote une application →

Le KvBus, le bus d’événements interne

Le KvBus : un magasin clé-valeur avec durée de vie et un mécanisme de publication par sujets entre Workers

Un Worker publie, un autre réagit

Le KvBus est à la fois un magasin clé-valeur, avec une durée de vie par clé, et un bus de publication par sujets. Un Worker publie un événement ; ceux qui y sont abonnés le reçoivent, sans que l’un connaisse l’autre.

Il offre aussi des opérations atomiques — incrémenter, comparer puis remplacer, poser seulement si la clé est libre — qui suffisent à coordonner des Workers sans verrou maison.

Son implémentation se choisit par la configuration, sans recompiler : en mémoire par défaut, ou Redis quand plusieurs instances d’une application doivent partager le même bus.

À côté du bus, un registre de données partagées tient des compteurs, des jauges, des états et des séquences, avec des seuils d’alerte et l’historique des mille derniers changements.

La TechDB, la mémoire technique

La TechDB : la base H2 embarquée qui garde les offsets, l'état des Workers, les événements, les journaux et l'audit des actions

Une base embarquée pour tout ce qui est technique

Chaque application embarque une base H2, en mode fichier et compatible PostgreSQL. Elle est réservée aux données techniques : les positions de lecture, l’état de chaque Worker, les événements, un tampon de journaux, l’audit des actions, des résultats d’API, ses propres migrations.

Elle se purge seule chaque nuit selon des durées fixées : une semaine pour les événements, trois jours pour les journaux, un mois pour les actions. Ses migrations n’ajoutent jamais rien qu’on ne puisse rejouer.

Elle se sauvegarde et se restaure à chaud, par des actions dédiées ; une restauration exige un jeton de confirmation valable dix minutes.

Les données métier d’une application vivent ailleurs, en général dans un schéma PostgreSQL que le Hub lui provisionne. Le framework fournit des Workers prêts à l’emploi pour interroger une base H2, PostgreSQL ou MariaDB.

Décider sans redéployer : JDM, Janino et règles

Une règle métier change plus souvent que le code qui l’entoure. Le framework permet de la sortir du code compilé, de trois façons.

Les tables de décision JDM

Des graphes de décision au format JSON — tables de décision, expressions, branchements, sous-décisions — que l’on dessine dans un éditeur visuel. Le moteur lit le format de l’éditeur GoRules. Chaque évaluation est auditée, et un cache évite de recalculer.

Les scripts Janino

Du code Java déposé dans le dépôt de l’application et compilé à chaud en bytecode. Les accès sensibles (fichiers, réseau, réflexion) sont bloqués par défaut.

Le moteur de règles

Des règles Java écrites comme une condition et une conséquence, évaluées par un Worker dédié, avec un journal d’audit des décisions gardé trente jours.

Ces fichiers vivent dans le dépôt de l’application (repository/) : décisions, scripts, gabarits. Ils se rechargent à la demande, sans redémarrer.

Les pipelines, V1 et V2

Pipeline V1

Des étapes écrites en scripts, sur des données non typées, exécutées par un réservoir de threads commun. Simple et souple.

Pipeline V2

Des étapes typées — chaque étape déclare ce qu’elle reçoit et ce qu’elle rend —, déclarées en Java, chacune avec sa file, son niveau de concurrence et son délai, sur des threads virtuels.

Les deux coexistent. La documentation décrit les formes courantes : extraction-transformation- chargement, éventail vers plusieurs branches, reprise avec état, compensation. Pour des pipelines en graphe avec validation humaine et traçabilité, un pack ajoute une couche au-dessus de la V2 : socle-pack-pipeline →

gRPC entre socles

Deux applications Socle — ou deux machines — peuvent se parler en gRPC, un protocole binaire à contrats versionnés. Le service est optionnel. Il offre un échange en flux dans les deux sens, des sessions (conversation, synchronisation, diffusion, pipeline), la découverte des pairs et le pilotage à distance des Workers. Les connexions aux pairs se gardent en réservoir, se maintiennent et se rétablissent seules ; on monte une étoile autour d’un centre ou un maillage complet. Une passerelle gRPC-Web, désactivée par défaut, permet à un navigateur d’y parler.

C’est le même socle de contrats qui relie le Hub à ses agents de terrain : le minihub →

Résilience, fournie

Le coupe-circuit

Après cinq échecs, il s’ouvre et cesse d’appeler le service malade ; il le réessaie ensuite prudemment, et se referme au premier succès.

Les nouveaux essais

Par défaut trois tentatives, espacées de façon exponentielle à partir d’une seconde, plafonnées, avec une part d’aléa pour éviter que tous les clients réessaient en même temps.

Le limiteur de débit

Un seau à jetons : cent appels par seconde, des pointes à cent cinquante, puis l’attente.

Dans un Worker passerelle, les trois s’empilent toujours dans le même ordre : limiteur, puis coupe-circuit, puis nouvel essai.

Supervision, tableau de bord, journaux

Le superviseur

Un battement toutes les cinq secondes. Sans nouvelles, un composant passe en alerte, puis en état critique, puis en échec. L’escalade va du simple avertissement à la relance du composant, puis, en dernier recours, à l’arrêt d’urgence.

Le tableau de bord

Servi par l’application elle-même, sur /dashboard, sans port dédié : l’état de chaque Worker, ses statistiques et les dernières erreurs, en direct.

La santé et les métriques

Des points de santé (vivant, prêt — qui répond « pas prêt » pendant une vidange), des métriques au format Prometheus, un état d’administration.

Les journaux

Log4j2 en écriture asynchrone, au format JSON, avec rotation et rétention. Chaque ligne porte le nom de l’application, du Worker et l’identifiant d’exécution. Un relais optionnel les envoie vers un collecteur central.

Configuration et sécurité

La configuration tient dans un application.yml, complété par des profils de développement et de production. Les secrets ne sont jamais écrits dans la configuration : ils viennent de l’environnement ou d’un coffre-fort, que le Hub fournit.

Côté sécurité, le framework fournit ses filtres : une clé d’administration sur les routes d’administration, une limite de débit sur ces mêmes routes, et la vérification des jetons OIDC (signature, émetteur, audience, expiration, portée). Les certificats et les noms de domaine sont une affaire de plateforme : c’est le Hub qui les rend.

L’arrêt est gracieux : le serveur web suspend l’accueil de nouvelles requêtes, laisse finir celles en cours, et les points de santé restent joignables pendant toute la vidange. C’est ce qui permet de livrer une nouvelle version sans couper le service.

Ce que le framework embarque

  • 21
    Workers intégrés au framework, prêts à servir
  • 96
    Actions qu’ils exposent d’emblée, en REST et en MCP
  • 148
    Cas d’usage documentés, en 17 familles
  • 78
    Fiches de référence technique

Les Workers intégrés couvrent les besoins de toute application : le serveur HTTP, le tableau de bord, la lecture, la sauvegarde et la purge de la base technique, les bases H2, PostgreSQL et MariaDB, le moteur JDM, Janino, le moteur de règles, le serveur gRPC, le contrôle et la maintenance, le rapport d’erreurs, la licence. Le moteur JDM, à lui seul, expose douze actions.

Les 148 cas d’usage disent, pour chaque besoin, par quel mécanisme du framework passer : Workers, bus, actions, base technique, domaine, sécurité, configuration, supervision, outillage, Workers intégrés, résilience, règles et code dynamique, pipelines, intégrations, interface, fichiers, contrats. Ils sont recopiés dans chaque nouvelle application, pour qu’elle reste autonome : la fabrique →

Ce qu’il apporte

Des applications qui se ressemblent

Toutes nos applications ont la même structure. Qui en connaît une sait lire les autres.

Un agent IA dans chaque application

Parce que chaque action est aussi un outil MCP, toute application de la flotte se pilote par un agent, sans développement spécifique.

Le temps passé sur le métier

Cycle de vie, supervision, journaux, résilience, base technique : rien de cela n’est réécrit.

On le voit à l’œuvre dans chacune de nos applications. Un démonstrateur en fait le tour avec trente Workers branchés sur des API publiques : AppDemo →. Et les fiches Things, TheDash, Entreprises ou DataApp en montrent l’usage réel.

La suite du socle

Les packs ajoutent des capacités au framework ; le Hub rend tout ce qui entoure une application.

Gérer mes cookies