Ce qui roule vraiment, avec les vrais noms des composants et les vrais mécanismes.
Si tu cherches le pitch, il est sur l'accueil.
En bref
La stack réelle de Luge : desktop Tauri 2 (Rust), inférence locale llama.cpp (modèles GGUF Qwen3.5/3.6 et Ornith 1.0 épinglés SHA-256), mémoire hybride PostgreSQL (tsvector + pgvector, fusion RRF) avec curation nocturne, audit à hash d'intégrité vérifiable par un tiers, et un gateway MCP unique de 43 modules. Aucun fine-tuning : l'auto-amélioration repose sur la mémoire.
Tauri 2 — webviews React 19 + noyau Rust. Pas d'Electron. Le runtime edge vit en Rust précisément parce que le WebView gèle son JavaScript en arrière-plan (leçon de la v0.19.0) — l'inférence et les outils survivent à la fenêtre minimisée.
Installateurs signés : Developer ID + notarisation (macOS), Authenticode EV (Windows), .deb/.rpm (Linux). Mises à jour minisign, manifeste public vérifiable.
Jumelage d'appareil via navigateur (aucun token à coller); jeton stocké au trousseau du système, hors de portée des devtools; session rafraîchie et requête rejouée sur 401 au lieu de te renvoyer au login.
L'enregistreur
Détection par l'état matériel du micro, pas par le calendrier ni un scan de processus : listener CoreAudio (macOS — attrape Meet dans un onglet), introspection PulseAudio (Linux), registre ConsentStore (Windows).
Machine à états débouncée avec un état « Arming » de 2 s — parce qu'enregistrer le lobby est exactement ce qu'il ne faut pas faire. Un client Zoom ouvert mais idle ne déclenche rien; les glyphes que Chrome greffe aux titres d'onglets (🔊 🔴) sont nettoyés avant classification.
Auto-stop per-process (macOS 14.4+) : « est-ce qu'un processus AUTRE que moi capture? » — raccrocher arrête l'enregistrement même si l'onglet Meet reste ouvert.
Double flux mic + audio système fusionné en WAV stéréo (un canal chacun); le mute écrit du silence pour préserver l'alignement temporel; anti-larsen par exclusion de son propre audio (excludesCurrentProcessAudio).
File d'upload durable (manifeste atomique, retry/backoff, dédup par session) + journal append-only jamais purgé — une chaîne de possession des enregistrements, utile quand la conservation des communications est une obligation réglementaire.
Le nœud edge — l'IA sur ton poste
llama.cpp en sidecar compilé par plateforme (Metal / CUDA / Vulkan), catalogue de 9 modèles GGUF épinglés par SHA-256 (2,7 → 22 Go) — Qwen3.5/3.6 (4B → 35B), Ornith 1.0, entre autres. Téléchargement streamé avec hash au fil de l'eau et rename atomique. Ce qui roule sur quoi : voir le guide des modèles locaux.
Transcription locale Parakeet ONNX via sherpa-onnx (+ Canary, Cohere), diarisation opt-in, jobs checkpointés par chunk (une interruption ne re-transcrit rien), décodage audio 100 % Rust (symphonia — zéro ffmpeg).
Gating honnête des capacités : un nœud n'annonce inference_capable que si le modèle est sur disque ET le serveur résolvable — « pourquoi mon agent local répond pas? » est rendu impossible par construction.
Le cloud ne commande jamais le poste : le backend ne peut ni choisir quel modèle charge le nœud, ni quels binaires MCP il exécute — les lignes de commande sont rédigées localement, par design.
CLI headless (« edge light ») pour serveurs : pairable en SSH, config TOML rechargée à chaud (commentaires préservés), self-update SHA-256, installable en service OS.
La mémoire et l'auto-amélioration — le système au complet
Aucun fine-tuning nulle part : tout repose sur PostgreSQL. C'est le morceau le plus profond du produit, alors le voici au complet.
L'écriture
Après chaque réponse IA, un appel LLM léger extrait au plus 5 mémoires durables par tour (test de durabilité : « encore vrai dans 30 jours? »). Une liste vide est le résultat normal attendu.
Déduplication à 3 couches avant chaque insertion : hash SHA-256 exact → rang FTS ≥ 0.5 (paraphrases) → cosinus vectoriel ≥ 0.85 (paraphrases sans mots communs). Un doublon re-confirme l'original au lieu de s'empiler.
Anti-hijack par conception : l'extracteur refuse de stocker des ordres impératifs (« une directive stockée est rejouée dans chaque contexte futur ») et l'identité du locuteur; il replie en privé au moindre doute. Le modèle propose, le code applique : aucun LLM n'écrit directement en base — JSON validé, catégories clampées à l'enum, verrouillé par tests.
Chaque mémoire porte son contributeur (humain ≠ IA, jamais confondus) et sa portée : entreprise / équipe (partage Keto) / personnelle / éphémère — et l'éphémère l'est vraiment : rien de dérivé n'est persisté.
La lecture
Stockage hybride tsvector + pgvector, rappel par fusion RRF (k=60, 50 candidats par côté), pondéré par décroissance de fraîcheur (demi-vie 7 jours, plancher 0.7).
Fraîcheur honnête : last_confirmed_at (le fait a été re-énoncé) ≠ last_used_at (simple rappel) — deux horodatages distincts pilotent la décroissance.
Un tier core memory toujours injecté, sous budget dur (1 200 caractères entreprise / 800 personnel) : un ajout qui déborde est rejeté. La rareté est le mécanisme de curation — préambule prévisible, pas de dérive de contexte.
FTS accent-folded des deux côtés (« prefere » tapé sans accent matche « préfère » stocké) et extraction dans la langue de la conversation — le bilinguisme est dans le schéma, pas dans un patch.
La nuit
Dream sweep à 4 h 30 UTC : élagage SQL déterministe d'abord (vieux + jamais rappelé + peu utilisé, catégories durables exemptées), re-jugement LLM par lots ensuite (keep/archive avec raisons typées), fusion des redondances, résolution des contradictions (superseded_by), et re-scoping des fuites personnelles vers privé — en distinguant « fait sur une personne tierce » (reste à l'équipe) de « fait personnel du contributeur » (redevient privé). Le curateur réorganise; il n'invente jamais et ne DELETE jamais.
Résurrection : un fait archivé qui est re-énoncé en conversation est automatiquement désarchivé — il a repassé la barre de l'extracteur, il est manifestement vivant.
La boucle sur les skills et les prompts
Anti juge-et-partie (décision produit datée, 2026-06-05) : l'agent qui a produit une réponse ne la juge jamais. Un observateur tiers relit uniquement les conversations signalées par des déclencheurs déterministes (👎, longueur anormale) et ne consigne que des faits de friction.
Pipeline observer → proposer → author → apply → revert : journal avant-mutation, revert bit-à-bit, la raison du revert redevient du feedback, le triple reverté est blacklisté. Le dashboard mesure si le correctif a servi (activations_since) et si la friction a cessé (recurrence_since).
Les outils et les secrets
43 modules MCP sur un seul serveur FastMCP : 21 intégrations externes (Slack, Teams, Gmail, Jira, GitHub, HubSpot…) + 22 modules plateforme (documents, mémoire, todos, boards, téléphonie, HITL…). OAuth par utilisateur avec refresh automatique.
Gateway N+1→1 : les serveurs MCP configurés par chaque tenant sont montés en proxys namespacés sur le même gateway — cache, circuit breaker et santé PAR serveur (un serveur tenant lent ne dégrade jamais les autres), hot-reload par Redis pub/sub.
Secrets 1Password : l'agent manipule secret://alias/champ, résolu localement juste avant l'exécution — default-deny, liaison au domaine enregistrable (les sous-domaines SSO passent, bank.com.evil.com est bloqué), scrubbing du résultat sous trois encodages (brut, HTML, URL). ~19 tests dédiés.
Exécution de code : Claude Code dans un sandbox Docker/K8s séparé (4 Go / 2 CPU, workspace éphémère, 7 hooks de cycle de vie, reprise de session).
Audit à hash d'intégrité : content_hash par ligne calculé sur le texte en clair à l'écriture — contrat verrouillé par un test de régression — plus une racine SHA-256 sur les paires id:hash à l'export. La falsification est détectable par un tiers, sans clé de déchiffrement. Packages de preuves PDF exportables (beta).
PII round-trip : détection GLiNER 100 % on-prem + regex (NAS, RAMQ, cartes…), anonymisation avant l'envoi au modèle et ré-identification de la réponse via reverse-map — le LLM externe ne voit jamais la vraie valeur, l'utilisateur voit une réponse intacte.
Chokepoint unique (hook BEFORE_BROADCAST) pour le consentement IA (fail-closed) et le budget mensuel (blocage réel, mais un appel vocal établi n'est jamais coupé — le blocage tombe au tour suivant). Un seul point de passage couvre web, Telegram, Teams et les automatisations — un quota posé juste sur l'UI fuit par les automatisations.
Téléphonie SIP direct (trunks, REGISTER, rotation de credentials sans redémarrage) — la minute au prix du trunk, pas d'une API CPaaS. Et call_colleague : un agent texte peut téléphoner à un collègue, but injecté au voice agent, résultat livré dans la room d'origine.
API compatible OpenAI : POST /api/v1/chat/completions (streaming inclus) avec ta clé Luge.
La sécurité — les détails qui comptent en pentest
Le token WebSocket voyage dans Sec-WebSocket-Protocol — spécifiquement pour ne jamais apparaître dans les access logs.
Le llama-server local est verrouillé même en loopback : port éphémère + clé API aléatoire de 24 octets par processus, passée par variable d'environnement (pas par cmdline world-readable); les processus orphelins sont traqués et tués.
Webhooks sortants : registre validé anti-SSRF (double résolution), signature HMAC X-Luge-Signature-256, journal de livraison par destination avec copie du payload exact envoyé.
Hygiène edge mesurable : zéro panic!()/TODO dans ~9 850 lignes Rust, 70 tests, clippy en gate dur sur 3 OS.
Ce qui n'est pas encore là
Audio système Windows (WASAPI) — écrit, pas encore branché. Transcription locale Windows — en route. macOS et Linux sont complets.
L'inférence edge est en beta; la transcription locale, elle, est en production.
La pondération par expertise du contributeur dans le rappel mémoire existe dans la formule… mais vaut 1.0 partout : la plomberie attend son moteur.
Les correctifs de la boucle d'amélioration s'appliquent sans porte d'approbation — position assumée : journal avant-mutation, revert bit-à-bit, blacklist des correctifs revertés.
Pas d'index ANN sur les embeddings (choix documenté lié au multi-tenant) — le rappel est exact, pas approximatif, et on surveille la latence.
Le code de la plateforme n'est pas open source. La fondation d'orchestration (RoomKit) l'est; le dépôt de distribution avec signatures est public. On préfère le dire nous-mêmes.