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.
Tu diriges, ou tu évalues le risque pour la TI? Chaque bloc se termine par une
ligne « En clair » — l'essentiel, sans le jargon.
Pas de slideware ici — la stack réelle : desktop Tauri 2 (Rust), inférence locale llama.cpp (GGUF Qwen3.5→3.8 pis Ornith 1.0, épinglés SHA-256), mémoire hybride PostgreSQL (tsvector + pgvector, fusion RRF) avec curation nocturne, notes markdown versionnées dont chaque version nomme son auteur, partage par capacités fines (Keto), journal d'audit chiffré à hash d'intégrité vérifiable par un tiers, pis un seul gateway MCP — les intégrations natives plus les modules plateforme. Aucun fine-tuning nulle part : 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 pour une raison précise : 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 par navigateur — aucun token à coller. Le jeton vit dans le trousseau du système, hors de portée des devtools; sur un 401, la session se rafraîchit et la requête est rejouée au lieu de te renvoyer au login.
En clair : ça s'installe comme n'importe quel logiciel signé, ça se met à jour tout seul, et l'IA continue de travailler fenêtre minimisée.
L'enregistreur
Détection par l'état matériel du micro — pas le calendrier, pas un scan de processus. Listener CoreAudio (macOS — attrape Meet dans un onglet), introspection PulseAudio (Linux), registre ConsentStore (Windows).
Jamais le lobby — machine à états débouncée, état « Arming » de 2 s. 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+) — la question posée au système : « est-ce qu'un processus AUTRE que moi capture? ». Raccrocher arrête l'enregistrement, même si l'onglet Meet reste ouvert.
Deux flux, un WAV — mic + audio système fusionnés en stéréo (un canal chacun). Le mute écrit du silence pour préserver l'alignement temporel; l'anti-larsen exclut son propre audio (excludesCurrentProcessAudio).
File d'upload durable — manifeste atomique, retry/backoff, dédup par session, et un journal append-only jamais purgé : une chaîne de possession des enregistrements.
En clair : rien ne rejoint l'appel, le lobby n'est jamais enregistré, et chaque enregistrement garde une chaîne de possession — précieux quand la conservation des communications est une obligation.
Le nœud edge — l'IA sur ton poste
Jumelage en une commande — luge-edge pair : un code court, approuvé depuis un appareil déjà connecté. Le jeton s'applique à chaud (~2 s), et le re-jumelage se fait sans redémarrage — modèle chargé et agents intacts.
llama.cpp en sidecar — compilé par plateforme (Metal / CUDA / Vulkan). Catalogue edge de 10 modèles GGUF épinglés par SHA-256 (2,7 → 22 Go) : Qwen3.5→3.8 (4B → 35B), Ornith 1.0, entre autres. Le dernier entré, Qwen3.8 27B (qwen3.8-27b-q4, 17,9 Go), est le premier modèle dense du tier haut du catalogue : les MoE voisins n'activent que 3-4B paramètres par token, lui mobilise ses 27B au complet. (Le catalogue edge — épinglé, borné — n'est pas la liste du guide des modèles locaux, qui recense tout ce qui roule.) Téléchargement streamé, hash au fil de l'eau, rename atomique.
Transcription locale — Parakeet ONNX via sherpa-onnx (+ Canary, Cohere), diarisation (qui a parlé, quand) opt-in. Jobs checkpointés par chunk : une interruption ne re-transcrit rien. Décodage audio 100 % Rust (symphonia — zéro ffmpeg).
Agents de code installés à distance — tu choisis un agent ACP dans Luge (Claude Code, Codex, Copilot, Cursor, entre autres) et il s'installe sur le poste sans ouvrir un terminal — via le nœud luge-edge (le CLI ou le service), jamais par l'app desktop, qui n'héberge aucun agent. Ce qui traverse le fil, c'est un id de catalogue — jamais une ligne de commande : le poste résout l'id localement et compose lui-même sa commande. Les permissions se posent dans le fil de la conversation.
Secrets 1Password — l'agent manipule secret://alias/champ, résolu sur le poste juste avant l'exécution, liable à un domaine enregistrable. L'agent ne voit jamais la valeur (le détail — default-deny, scrubbing — est au bloc Outils & secrets).
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.
Mise à jour signée, fail-closed — self-update vérifié minisign : signature invalide = pas de mise à jour, jamais l'inverse.
CLI headless (« edge light ») — pour serveurs : pairable en SSH, config TOML rechargée à chaud (commentaires préservés), installable en service OS.
Pas une installation complète de Luge sur ton poste — l'agent hébergé sur ta machine n'a ni la mémoire Luge, ni les outils Luge, ni la recherche documentaire : il travaille avec ce que tu lui donnes, sous tes droits et tes permissions. On préfère le dire nous-mêmes.
En clair : l'IA peut rouler entièrement sur le poste, un agent de code s'y installe depuis Luge sans terminal, et le nuage n'a aucun moyen d'en prendre le contrôle.
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
Au plus 5 mémoires par tour — après chaque réponse IA, un appel LLM léger extrait les faits durables (test : « 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.
Attribution et portée — 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
Rappel hybride — tsvector + pgvector, fusion RRF (Reciprocal Rank Fusion : k=60, 50 candidats par côté), pondérée par la 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.
Core memory sous budget dur — un tier toujours injecté, plafonné (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.
Bilingue dans le schéma — FTS accent-folded des deux côtés (« prefere » tapé sans accent matche « préfère » stocké), extraction dans la langue de la conversation. Pas un patch.
La nuit
Dream sweep (4 h 30 UTC) — la mémoire est curée chaque nuit : é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). Le curateur réorganise; il n'invente jamais et ne DELETE jamais.
Re-scoping des fuites personnelles — en distinguant « fait sur une personne tierce » (reste à l'équipe) de « fait personnel du contributeur » (redevient privé).
Résurrection — un fait archivé 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.
Correctifs réversibles — 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).
En clair : tes agents retiennent ce qui compte, oublient proprement le reste, et rien ne s'écrit dans leur mémoire sans passer par du code validé. Aucun réentraînement, jamais.
L'écriture — notes, canevas et recherche
Notes markdown versionnées — chaque sauvegarde crée une version, et l'historique nomme l'auteur de chacune : une personne dans l'éditeur, une IA agissant pour elle, ou une clé d'accès programmatique. Pas de mystère sur la plume.
Restaurer = nouvelle version — revenir à une version ancienne en crée une nouvelle par-dessus. L'histoire ne se réécrit jamais.
Références @ et rétroliens — une note pointe vers n'importe quel objet de la plateforme. La référence se résout selon les droits du lecteur : le même texte n'affiche à chacun que ce qu'il a le droit de voir. Les rétroliens montrent qui pointe vers la note.
Anti-écrasement en co-édition — humain et agent peuvent écrire dans la même note; une écriture basée sur une version périmée est refusée au lieu d'écraser silencieusement le travail de l'autre.
Canevas — des blocs sur un plan 2D pour bâtir un document à plusieurs mains, exportables dans un format d'échange ouvert.
Recherche unifiée — notes + documents, par le sens, bornée aux droits d'accès : la question n'est même pas posée sur ce que tu ne peux pas voir. Ce n'est pas une recherche plein texte sur toute la plateforme — on le dit tel quel.
Graphe de l'espace de travail — 15 familles d'objets (conversations, notes, documents, réunions, agents, captures, tables…) reliées en graphe, profondeur d'exploration réglable. Chaque lien respecte les droits d'accès dont il vient.
En clair : tes notes gardent la trace de qui a écrit quoi — humain ou IA —, rien ne s'efface en douce, et la recherche ne peut pas te montrer ce qui ne t'appartient pas.
Le modèle de partage
Capacités fines (Keto) — chaque geste passe par une permission nommée. Une feature sans capacité n'apparaît même pas dans l'UI; les capacités destructives et critiques portent des flags dédiés.
Visibilité Privé / Toute l'organisation — deux niveaux, des défauts assumés : ouverts pour les mémoires et les documents (le savoir d'équipe sert l'équipe), fermés pour tout le reste.
Partage Lecture / Écriture + demande d'accès — une ressource se partage en lecture ou en écriture; ce qui ne t'est pas partagé se demande en un clic. Même un admin doit demander.
Dossiers de documents en cascade — partager un dossier ouvre sa branche entière, pas besoin de redonner l'accès pièce par pièce. (Les dossiers de notes, eux, rangent : le partage s'y fait note par note.)
Un agent agit toujours avec les droits de la personne qui lui parle — pas de compte de service omniscient. Demande à l'agent un document que tu ne peux pas voir : il ne le voit pas non plus.
Isolation multi-tenant structurelle — pas une option de configuration : les requêtes sont scopées au tenant par construction. Non configurable — donc non déconfigurable.
Invités externes à adresse prouvée — une personne hors de l'organisation prouve son adresse (Google, Microsoft ou code à usage unique) et n'atteint que ce qui lui est nommément partagé. En date de v0.59.
En clair : chaque personne — et chaque IA — ne voit que ce qu'elle a le droit de voir, l'accès se demande au lieu de se contourner, et un invité de l'extérieur prouve qui il est avant d'entrer.
Les outils et les secrets
Un seul gateway MCP — les 25 intégrations natives (Slack, Teams, Gmail, Jira, GitHub, HubSpot…) plus les modules plateforme (documents, mémoire, notes, boards, téléphonie, HITL — human-in-the-loop…), sur un seul serveur FastMCP. OAuth par utilisateur, 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).
En clair : toutes les intégrations passent par une seule porte surveillée, et tes mots de passe ne transitent jamais par le modèle.
Journal d'audit chiffré, archive signée exportable — 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 : Avertir / Anonymiser / Bloquer — détection GLiNER 100 % on-prem + regex (NAS, RAMQ, cartes…), trois actions au choix par politique. En mode Anonymiser, le round-trip est complet : masquage avant l'envoi au modèle, 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.
Gemini servi depuis le projet GCP du tenant, région épinglée — prompts et réponses restent dans une seule juridiction : Gemini est appelé depuis le propre projet Google Cloud du tenant (facture, quotas et journaux chez lui, vérifiables dans sa console), avec une région obligatoire à chaque couche — aucun défaut nulle part. Une requête sans région ne part tout simplement pas.
Chokepoint unique (hook BEFORE_BROADCAST) — consentement IA fail-closed et budget mensuel au même point de passage, peu importe la porte d'entrée : web, voix, courriel, Telegram, webhooks, automatisations. Un quota posé juste sur l'UI fuit par les automatisations. Le blocage est réel — mais un appel vocal établi n'est jamais coupé, ça tombe au tour suivant.
Téléphonie SIP direct — trunks, REGISTER, rotation de credentials sans redémarrage : la minute au prix du trunk, pas d'un intermédiaire CPaaS (plateforme téléphonique revendue à la minute). Et call_colleague : un agent texte peut téléphoner à un collègue — l'objectif est passé au voice agent, le résultat livré dans la room d'origine.
Salons vocaux, preneur de notes — un canal d'équipe peut devenir un salon vocal permanent. En réunion, le preneur de notes est un participant que tout le monde voit; il écoute chaque personne séparément — c'est de là que vient l'attribution réelle par locuteur, pas d'une devinette après coup.
API compatible OpenAI — POST /api/v1/chat/completions (streaming inclus) avec ta clé Luge.
En clair : l'audit se vérifie sans nous croire sur parole, les renseignements personnels sont masqués avant tout appel externe, et le consentement bloque pour vrai.
La sécurité — les détails qui comptent en pentest
Token WebSocket hors des logs — il voyage dans Sec-WebSocket-Protocol, spécifiquement pour ne jamais apparaître dans les access logs.
llama-server 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 durcis — 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 mesurable — zéro panic!()/TODO hors tests dans ~17 800 lignes Rust, 338 tests, clippy en gate dur sur 3 OS. (En date d'edge v0.12.0.)
En clair : les angles qu'un test d'intrusion regarde en premier sont déjà couverts.
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. (En date d'août 2026.)
Expertise du contributeur — la pondération existe dans la formule de rappel… mais vaut 1.0 partout : la plomberie attend son moteur.
Pas de porte d'approbation sur les correctifs de la boucle d'amélioration — position assumée : journal avant-mutation, revert bit-à-bit, blacklist des correctifs revertés.
Pas d'index ANN (approximate nearest neighbor) sur les embeddings — choix documenté lié au multi-tenant : le rappel est exact, pas approximatif, et on surveille la latence.
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.