Architecture

Un core, des apps réellement indépendantes

Kubuno n'est pas un monolithe. Un petit core en Rust orchestre une constellation de modules autonomes — chacun son processus, son dépôt et ses paquets — qui dialoguent par HTTP et par des événements partagés. Voici comment tout s'emboîte.

CLIENTS Navigateur web App bureau Mobile Clients API / CLI HTTPS Frontend host · React 19 Shell unifié — charge l'UI de chaque module au runtime via import maps ESM requête authentifiée (JWT) Core · Rust + Axum Reverse-proxy Authentification Bus d'événements Stockage reverse-proxy · secret interne MODULES INDÉPENDANTS · processus séparés sur 127.0.0.1 Office :3105 Drive :3101 Mail :3111 p2pnas :3123 Assistant :3107 +18 chacun s'enregistre auprès du core au démarrage · paquet natif ou installation à chaud SQL · NOTIFY/LISTEN · file de jobs PostgreSQL 16 — un seul moteur, trois rôles Base de données Bus d'événements · LISTEN/NOTIFY File de jobs · SKIP LOCKED

Les couches

Six couches, des responsabilités nettes

Le core (Rust + Axum)

Une passerelle unique : reverse-proxy (HTTP et WebSocket), authentification, bus d'événements, file de jobs et accès au stockage. Il pilote le cycle de vie des modules mais ne contient aucune logique métier.

Des modules indépendants

Chaque app est un processus séparé sur 127.0.0.1, livré en paquet natif (.deb, .rpm, macOS, Windows) ou installé à chaud depuis la marketplace, sans redémarrer le core.

Frontend chargé au runtime

Un host React 19 unique charge l'UI de chaque module à la volée via des import maps ESM. Toutes les apps partagent un shell, une session et un design cohérents.

PostgreSQL, triple emploi

Un seul moteur joue trois rôles : base de données, bus d'événements (LISTEN/NOTIFY) et file de jobs (SKIP LOCKED). Ni Redis, ni broker externe.

Isolé & sécurisé

Un schéma PostgreSQL dédié par app, un bac à sable seccomp qui fait échouer execve (sauf pour les rares modules qui appellent légitimement un binaire, comme le transcodage vidéo), et des routes internes signées par un secret dérivé par module.

Prêt pour les agents IA (MCP)

Chaque module peut déclarer des outils Model Context Protocol ; le core les agrège derrière un endpoint /mcp unique, authentifié par jeton d'API. Un assistant agit alors sur votre instance avec vos droits. Désactivé par défaut.

Extensible par conception

Des points d'extension bien définis (routes, événements, entrées de menu) laissent la communauté ajouter des modules sans toucher au core.

Sous le capot

Le cycle de vie d'une requête

De l'ouverture du navigateur à l'écriture en base, sans jamais quitter votre serveur.

1

Chargement du shell

Le navigateur charge le host React ; les import maps résolvent chaque module vers son entrée ESM /modules/<id>/entry.js.

2

Appel authentifié

L'app envoie sa requête au core en HTTPS, accompagnée d'un JWT (avec refresh token en cookie HttpOnly).

3

Le core fait office de passerelle

Il vérifie l'identité, puis agit en reverse-proxy vers le module concerné sur 127.0.0.1:31xx, avec un en-tête interne signé (X-Internal-Secret).

4

Le module agit

Le module lit ou écrit dans son schéma PostgreSQL, puis publie un événement via NOTIFY.

5

Réactions & tâches de fond

Les autres modules réagissent à l'événement (LISTEN) ; les traitements longs partent dans la file de jobs (SKIP LOCKED).

Envie d'aller plus loin ?

La documentation technique détaille le core, le manifeste des modules, les points d'extension et la sécurité.

Lire la doc technique