Unsay : un agent IA de sécurité médicamenteuse qui revient et défait ce qu'il a dit. Quand la FDA élève un rappel, il corrige chaque patient nommé qu'il avait déjà rassuré, en quelques secondes.
La mémoire d'agent a un mode d'échec que la qualité de récupération ne peut pas réparer : le contexte périmé. La similarité à une mémoire stockée ne prouve pas que la mémoire est encore vraie. Pour la plupart des agents c'est embarrassant. Dans une pharmacie c'est un rappel de Classe I. Le correctif d'Unsay est un schéma bitemporel sur CockroachDB (`valid_from`/`valid_to` pour le monde, `asserted_at`/`retracted_at` pour la croyance de ce système), et un join qu'aucune base vectorielle ne peut exprimer : chaque réponse encore debout qui s'appuyait sur une version d'affirmation qu'on ne croit plus. La relecture fonctionne encore au-delà de l'horizon AS OF SYSTEM TIME, et chaque correction est exactly-once à travers une panne de région.

Revendication 1 : réparer, pas seulement rappeler
Quand la FDA publie un rappel, un certain nombre de réponses déjà données sont maintenant fausses. Elles étaient correctes quand elles ont été données. Rien à leur sujet n'a changé ; le monde a bougé en dessous. Les trouver est une requête SQL. Lisez-la en français : chaque réponse encore debout qui s'est appuyée sur une version d'une affirmation qu'on ne croit plus. Une base vectorielle ne peut pas exprimer cette requête. Ni lentement, ni approximativement, pas du tout. Elle n'a pas la notion qu'une mémoire a des versions, et aucun enregistrement de quelle version une réponse donnée a consommé. Le plus qu'elle puisse renvoyer, ce sont les voisins les plus proches d'aujourd'hui, ce qui ne vous dit rien sur ce que vous avez dit en mars. Reconstruire l'histoire est une couche d'insight ; Unsay ferme la boucle en re-décidant chaque réponse affectée contre la mémoire actuelle, et là où le verdict bouge, rédige une correction et met en file une notification pour une personne nommée.


Revendication 2 : la relecture n'expire pas
La façon évidente de construire « ce que l'agent savait quand il a décidé » sur CockroachDB est de stocker le read timestamp et le rejouer avec `AS OF SYSTEM TIME`. C'est élégant, n'a pas besoin de tables supplémentaires, et est correct jusqu'à ce que le garbage collector passe au-delà du timestamp sauvegardé. La doc de CockroachDB le dit : `gc.ttlseconds` « n'est pas destiné à être une solution pour la rétention à long terme de l'historique ; pour ça, il faut gérer le versioning dans la conception du schéma au niveau applicatif. » La fenêtre par défaut est de 4 heures. 25 heures est la plus grande valeur régulièrement testée par Cockroach Labs. Le mécanisme durable d'Unsay est le schéma bitemporel que cette doc prescrit, et `AS OF SYSTEM TIME` reste comme chemin rapide à l'intérieur de la fenêtre. `scripts/expiry.py` pose une question dans les deux sens à trois âges différents : à l'intérieur de la fenêtre, les deux concordent exactement (un contrôle qui compte, parce qu'il prouve que le modèle bitemporel reconstruit une vraie histoire plutôt que d'en inventer une commode) ; au-delà de l'horizon, une route est partie et l'autre répond encore.
![Sortie terminal de scripts/expiry.py comparant la reconstruction bitemporelle à AS OF SYSTEM TIME à trois âges. À l'intérieur de la fenêtre GC : les deux concordent, v[2] = v[2], agree=True. Au-delà de l'horizon : route A (bitemporelle) A RÉPONDU avec la bonne affirmation historique ; route B (AS OF SYSTEM TIME) A ÉCHOUÉ avec « batch timestamp must be after replica GC threshold ».](/projectImages/unsay_06_expiry.png)
Les propriétés que le design porte
La provenance est écrite atomiquement avec la réponse. La ligne de décision et son read-set commitent ensemble ou pas du tout. Il n'y a pas de chemin de code qui stocke une réponse sans enregistrer ce qui l'a produite, parce qu'une réponse dont la provenance est perdue ne peut jamais être réparée, et un système de mémoire qui laisse tomber la provenance sous charge n'en a effectivement aucune. Les corrections sont exactly-once à travers une panne de région : la correction, le changement de statut, l'entrée outbox et la ligne d'audit sont une transaction. La dedupe_key de l'outbox est un hash déterministe de (décision, nouveau verdict, version de fait déclenchante), donc un sweep tué à mi-course et relancé recalcule la même clé et la contrainte d'unicité transforme la relecture en no-op. « Zéro notifications patient dupliquées » est une propriété du schéma, pas un espoir sur la façon dont le processus se termine. La résidence est appliquée par le stockage, pas par le code : `patient` est REGIONAL BY ROW, donc la mémoire d'un patient EU vit dans eu-west-1 parce que CockroachDB l'y met. Le cluster local tourne 9 noeuds à travers 3 régions AWS simulées sous SURVIVE REGION FAILURE, ce qui place 5 répliques de sorte qu'aucune région ne détient une majorité.

Unsay: An AI Medication-Safety Agent that Goes Back and Un-Says What It Told You. When the FDA Escalates a Recall, It Corrects Every Named Patient It Already Reassured, in Seconds.
Voir le projet
Assay : un tracker soin de la peau avec une barre d'erreur. Recadrer la même photo déplace la texture de 5,81 points, alors un verdict ne s'affiche que si le changement dépasse ce plancher sur votre visage.
La mesure existe : l'API YouCam Skin Analysis note seize résultats de peau depuis une photographie, et c'est un vrai bon instrument (entrée octet-identique donne sortie octet-identique). Le problème est qu'un score rapporté sans son erreur est un nombre avec lequel on ne peut pas prendre de décision. Sur mon propre visage avec une variable changée à la fois, la luminosité ±8 % déplace les boutons de 4,85 points et recadrer la même photo différemment déplace la texture de 5,81. Un effet de traitement réaliste sur quatre semaines est d'environ cinq. Assay mesure sa propre erreur d'abord, puis n'appelle un changement réel que quand il dépasse ce plancher.

Bloom : personne n'annule, on cesse simplement de venir. Bloom lit le rythme de visite propre à chaque client, signale ceux qui s'en écartent, et écrit une note personnelle à chacun. Les règles décident QUI, Gemini décide QUOI DIRE.
Un salon typique perd environ 40 % de ses clients chaque année, un premier-timer qui ne re-réserve pas dans les 30 jours a environ une chance sur cinq de jamais revenir, et un habitué fidèle vaut plusieurs centaines de dollars par an. Le signal est invisible parce que c'est une absence, répartie sur des centaines de personnes qui ont chacune leur propre rythme. L'architecture de Bloom est l'idée : les règles décident QUI (moteur de risque déterministe sur l'écart de visite médian propre à chaque client), Gemini décide QUOI DIRE (une note courte dans la voix du propriétaire, référençant l'histoire réelle de cette personne). La démo de toute la thèse est deux clientes : Aisha et Jane sont toutes deux à 44 jours depuis leur dernière visite ; Aisha vient toutes les 8 semaines, Jane toutes les 4. Tout outil qui signale « pas de visite en 60 jours » se trompe sur l'une d'elles.