Pourquoi l'IA de Guimauve ne peut pas envoyer de message
Ce n'est pas une promesse. C'est une contrainte dans la base, et un test qui échouerait si on la retirait. Voici comment c'est fait, et ce qu'on a observé ailleurs.
Il y a une loi dans Guimauve, la neuvième, qui tient en cinq mots : l'IA propose, l'humain envoie. Une loi qu'on se dit à soi-même ne vaut rien. Celle-ci est écrite là où elle ne peut pas être oubliée : dans la base de données.
Ce qui se passe quand un message part.
Chaque geste dans Guimauve est un événement. Un message envoyé est un événement message_sent. Il ne s'écrit que par une seule fonction, record_event. Cette fonction refuse un message_sent dans trois cas : si personne n'est connecté, si la personne connectée n'est pas celle déclarée comme expéditeur, et si la source de l'événement est « ai ». Ce sont les trois seuls chemins qu'une IA pourrait emprunter, et les trois sont fermés.
Et si on contournait la fonction ?
On a pensé à ça aussi. Depuis la migration 0032, un déclencheur sur la table elle-même applique les mêmes refus à toute insertion, quelle que soit l'origine. On ne peut pas non plus modifier un événement après coup : la table est en ajout seul, un test vérifie qu'aucune ligne n'est modifiable, et un autre qu'aucune fonction de la base n'écrit dans cette table à part record_event.
Ce que l'IA écrit, alors.
Un brouillon est un événement draft_generated, marqué comme venant de l'IA. Il est posé dans le composer. Quand la personne l'envoie tel quel, le message porte l'identifiant du brouillon. Quand elle le retouche, la retouche est un événement draft_edited, signé par elle. Le brouillon suivant, dans la même situation, reprend ses mots. Rien n'est réentraîné : c'est une phrase qu'elle a écrite, réutilisée.
Ce qu'on a vu ailleurs.
On a passé une après-midi sur le setter IA d'un concurrent, sur un vrai compte. Il ne parle pas seul non plus : il suggère, et un humain envoie. Sur ce point, on est d'accord avec eux. Mais deux choses nous ont décidés. La première : il n'y a pas d'interrupteur. Ni par organisation, ni par conversation ; seul le support peut retirer le module. La seconde : à « dis-moi juste le prix maintenant », il a proposé deux réponses qui recadraient vers l'appel, alors que le playbook demandait une réponse franche. Le script a gagné contre la règle.
Ce qu'on a fait de ces deux observations.
La coupure existe à deux niveaux : l'organisation, dans les réglages, et le fil, en un clic. La règle du prix est un réglage du Playbook, à trois valeurs : dire le prix, donner la fourchette, renvoyer à l'appel. Le brouillon applique la valeur, et dit laquelle. S'il n'y a pas de prix dans le Playbook, il ne l'invente pas : il renvoie à l'appel et l'écrit dans sa raison.
Pourquoi c'est un argument de vente.
Parce que tes prospects sont des gens. Une réponse envoyée par une machine sous ton nom, sans que tu l'aies lue, est une réponse dont tu es responsable sans l'avoir décidée. On préfère un brouillon prêt à la lecture et un humain qui appuie sur Entrée. Si un jour on change d'avis, il faudra modifier la base, et le test échouera. Tu le verras avant nous.
Eole, fondateur. Les tests cités : packages/db/test/ia.test.ts, packages/db/test/events.test.ts, apps/web/e2e/ia.spec.ts.

