En 2012, j'ai écrit un [postmortem pour Plancast](https://markmhendrickson.com/posts/a-postmortem-for-plancast/), une startup sur laquelle j'avais passé trois ans. Le principe était simple : les gens font des plans, les plans valent la peine d'être partagés, et un flux d'événements à venir provenant de personnes en qui vous avez confiance ferait ressortir des choses que vous ne saviez pas vouloir faire. Cela n'a pas fonctionné. La pièce expliquait pourquoi.

En le relisant douze ans plus tard, les diagnostics superficiels tiennent toujours. Les plans sont trop rares pour maintenir une habitude alimentaire quotidienne. Le partage de projets futurs donne de faibles boucles de vanité par rapport au partage de photos. Les forfaits expirent, de sorte que tout élément de contenu a une durée de conservation de plusieurs heures. La plupart des forfaits sont géographiquement locaux, de sorte que la plupart des forfaits de votre réseau ne sont pas pertinents la plupart du temps. Et le problème le plus profond : les gens ne veulent pas être conscients d’événements auxquels ils n’ont pas été personnellement invités. La prise de conscience sans invitation ressemble à une exclusion. La plupart des gens ne souhaitent pas non plus partager chaque forfait avec l’ensemble de leur réseau. Les mauvaises personnes peuvent se présenter ou la pièce ne semble plus contrôlable.

Ce qui m'a manqué en 2012, c'est qu'aucun de ces problèmes n'était réellement un problème mécanique du produit. Il s'agissait de problèmes de substrat. Le substrat disponible à l’époque, un flux au sein d’un réseau social centralisé, n’était pas adapté à chacun d’entre eux. J'ai essayé de concevoir autour du substrat avec des fonctionnalités. Le substrat était encore un plafond bas sur chaque métrique.

## Qu'est-ce qui n'allait pas réellement

Un flux n'est pas une primitive appropriée pour le partage de plans car :

- Un flux suppose un flux constant de contenu. Les plans n'arrivent pas sous forme de flux.
- Un flux de récompenses diffusé. Les plans doivent s’adresser à des publics cibles.
- Un flux a une fonction de réduction. Plancast a choisi « le plus tôt en premier » par date d'événement, les flux sociaux choisissent « le plus récent en premier » par heure de publication. Quoi qu’il en soit, il s’agit d’une sorte chronologique. Les plans bénéficient de nombreuses fonctions de requête, et les plus utiles (qui part dans votre graphique de confiance, ce qui convient ce jeudi, qui est en ville) sont rarement de type chronologique.
- Un flux rend chaque élément de contenu visible à tous ceux qui vous suivent. Les plans ont besoin de portées.
- Un flux traite la consommation comme la surface face à l'utilisateur. Les plans doivent être composés avec d'autres systèmes (calendriers, RSVP, transports en commun, météo).
- Un flux centralise la médiation. Les plans sont intrinsèquement entre les gens.

Une fois cette liste sur la table, chaque échec de Plancast que j'ai cité en 2012 est un symptôme en aval. Le substrat ne pourrait pas exprimer ce que veut réellement être le partage de plans.

## Le substrat dont j'avais besoin

Le substrat sur lequel je voudrais maintenant construire comporte deux pièces, dont aucune n’existait sous une forme utilisable en 2012.

**État durable, avec ajout uniquement pour les agents d'IA personnels.** C'est ce que je construis en tant que [Neotoma](https://neotoma.io). Chaque observation faite par un agent (un contact ajouté, un événement confirmé, une invitation émise, une participation confirmée) devient une entité typée avec une provenance, des contraintes de schéma et un historique immuable. L'agent IA de l'utilisateur y lit et écrit. Il n’existe pas de graphe social centralisé. L'utilisateur est propriétaire de l'État.

**Un maillage souverain de carnets d'adresses et d'étendues de confiance.** C'est à cela que sert [Darkmesh](https://github.com/markmhendrickson/darkmesh) (mon fork de l'original de [Anand Iyer](https://www.anandiyer.com/)). Darkmesh permet à une personne de publier des tranches adressables de son contexte (contacts spécifiques, groupes spécifiques, étendues spécifiques) sur les nœuds de maillage d'autres personnes sous consentement explicite. Le consentement est conservé à la périphérie du réseau. L'agent d'un expéditeur ne peut pas mettre un message dans l'état d'un destinataire à moins que le nœud maillé du destinataire n'ait admis la portée de l'expéditeur.

Les agents personnels d’IA communiquent entre eux à travers le maillage. Déclarez qu'ils se soucient durablement de la vie dans le propre Neotoma de chaque utilisateur. Il n’existe pas de serveur central détenant les plans de chacun.

## Comment la mission originale devient réalisable

Le pitch original de Plancast était le suivant : des rencontres fortuites issues d'une conscience partagée des projets. L’erreur a été de penser que la conscience partagée devait provenir d’un flux.

Sur ce nouveau substrat, un même pitch se décompose en œuvres différentes.

1. **L'ingestion d'événements est automatique.** Mon agent connaît déjà les événements auxquels j'ai répondu sur Luma, les événements de mon calendrier, les événements dans les e-mails de confirmation d'Eventbrite ou Meetup. Il les écrit sur mon Neotoma en tant qu'entités « événement » avec provenance. Je ne les tape jamais nulle part.

2. **Le partage est soumis au consentement et adressé.** Lorsque je réponds à quelque chose, mon agent peut signaler les étendues qui devraient savoir que j'y vais. Ce ne sont pas des publications de fil. Il s'agit d'observations adressées qui voyagent à travers le maillage uniquement aux personnes dont les nœuds ont admis ma portée.

3. **La découverte est une requête, pas un flux.** La surface la plus naturelle pour « ce qui se passe dans mon monde » n'est pas un flux. C'est une question que je pose à mon propre agent. *Qui, dans mon réseau de confiance, va où dans les deux prochaines semaines. Lequel de ces événements correspond à ma soirée de jeudi. Qui est en ville que je n'ai pas vu depuis un an.* Chaque requête est calculée au moment de la récupération sur mon Neotoma ainsi que sur toutes les étendues admises par mon maillage. Il n'y a pas de flux.

4. **Les invitations sont de première classe.** C'est la partie sur laquelle la pièce de 2012 a insisté, et la partie que la plupart des tentatives de produits ont ignorée.

## Comment les invitations devraient réellement fonctionner

Plancast avait des invitations explicites, mais elles étaient manuelles. Ils se trouvaient au-dessus d’un plan que vos abonnés pouvaient déjà voir. La nourriture était toujours la première surface. Une balise, une mention ou des métadonnées qui vous signalaient avaient la même forme : la visibilité ambiante venait en premier, le clic personnel en second. Une véritable invitation est censée inverser cet ordre.

Dans ce substrat, une invitation est une entité typée sur le propre état du destinataire. En gros :

```
invitation
  expéditeur : contact_id
  destinataire : contact_id
  event_ref : event_id
  portée : "1:1" | "petit_groupe" | "co_attending_set"
  note_to_recipient : chaîne (obligatoire, non vide)
  relation_basis : chaîne (pourquoi cette personne, pourquoi cet événement)
  slot_budget_used : entier (budget par événement)
  expires_at : horodatage
  conditional_on : prédicat de quorum facultatif
  provenance : agent / source / horodatage
```

Quelques éléments découlent de cette forme.

**Le substrat refuse de livrer si le maillage n'a pas admis la portée de l'expéditeur.** Cela tue les invitations de masse froide à la vitesse de la machine au seul niveau où elles peuvent être supprimées : la périphérie du réseau.

**Les budgets d'invitation par événement forcent la sélectivité.** Chaque événement dispose d'un petit nombre configurable d'espaces d'invitation qu'un expéditeur peut dépenser. C'est le substrat, et non la volonté, qui impose de "ne pas détruire votre carnet d'adresses". La tension vanité-sélectivité de 2012 devient un paramètre de substrat.

**Le tirage avec autorisation préalable est le modèle dominant.** Lorsque mon agent exécute sa requête permanente, il ne voit que les personnes dont les propres agents m'ont signalé comme quelqu'un qu'ils accueilleraient à cet événement spécifique. L'intersection de « qui dans mon réseau y va » et « qui m'accueillerait là-bas » est beaucoup plus petite que « qui dans mon réseau a posté ». Ce n'est pas un flux. Il s’agit d’un index soumis à autorisation.

**Le contexte personnel est obligatoire au niveau du type.** `note_to_recipient` et `relationship_basis` sont des champs obligatoires. Vide n'est pas un état valide. Mon agent peut les rédiger à partir de mon graphique Neotoma (dernier chevauchement, contexte partagé, contacts communs) mais une ligne confirmée par un humain est la valeur par défaut. C’est ce que soulignait l’article de 2012 lorsqu’il insistait sur le fait que les gens veulent se sentir personnellement invités. Le substrat fait de la note personnelle une exigence structurelle et non une courtoisie facultative.

**Le refus est silencieux et non attribué.** Les destinataires répondent par « accepter », « passer » ou « crayon ». Seul « accepter » est visible pour l'expéditeur. « pass » se résout par « pas de réponse » sans confirmation de lecture et sans raison. Le destinataire conserve la provenance privée. Vous pouvez auditer votre propre charge sociale sans l’exposer.

**Le quorum est une primitive de première classe.** L'article de 2012 qualifie la procrastination d'échec majeur : les gens gardent les options ouvertes et refusent de s'engager tôt. Le substrat répond à ce problème directement avec `conditional_on` : "J'irai à X si Aaron et Diwaker s'engagent également." Le substrat surveille le prédicat et le résout. Pas de rôle de coordinateur, pas de fil de discussion de groupe, pas de flocon.

**Composabilité avec le graphique d'événements existant.** Lorsqu'une invitation est acceptée, l'agent accède à la plateforme propriétaire du RSVP canonique (Luma, Eventbrite, calendrier) et rédige la réservation réelle. L'entité Neotoma `attendance_commitment` reste canonique pour qui fait confiance à qui va où. Le RSVP tiers reste canonique pour le lieu et la porte. Deux enregistrements, une source de vérité par préoccupation, liés.

## Ce que les agents décident réellement

Le système ci-dessus ne fonctionne que si les agents effectuent un travail non trivial localement. Les deux questions, dans les deux sens de la boucle, sont concrètes.

**Sortant, qui accueillerait favorablement ce plan.** Lorsque mon agent voit que j'ai répondu à quelque chose, il note mes contacts contre l'événement, pas contre moi. Signaux locaux utiles :

- les contacts dont Neotoma porte des sujets partagés ou des événements co-assistés avec celui-ci,
- des contacts avec qui j'ai vécu des choses similaires au cours de la dernière année,
- des contacts qui se sont explicitement inscrits dans une catégorie (me signaler la musique live dans cette ville),
- les contacts dont le propre horaire ou emplacement observé chevauche la fenêtre de l'événement.

L'agent produit une liste de candidats classés, jamais de tir automatique. Les budgets de créneaux sont dépensés par moi ou avec ma confirmation, et le champ `relationship_basis` est rempli à partir du même score afin que je puisse voir pourquoi une personne a été suggérée avant mon envoi.

**Entrant, quels plans passant par le maillage valent la peine d'être signalés.** Mon agent exécute la requête symétrique sur les invitations entrantes et sur les observations de fréquentation ambiante admises par mon champ d'application. Signaux locaux :

- depuis combien de temps et à quelle fréquence j'ai co-assisté avec les personnes impliquées,
- si le sujet correspond à une catégorie dans laquelle je suis resté engagé,
- si mon propre calendrier a de la place,
- si un quorum qui me tient à cœur est en train de se former.

La plupart des pings entrants sont archivés et non affichés. Ceux qui font surface sont accompagnés du court paragraphe de l'agent expliquant pourquoi celui-ci et pas les autres.

Les deux directions sont lourdes et restent toutes deux locales. Il n'y a pas de classement central. L'agent de chaque utilisateur calcule par rapport à l'état que possède l'utilisateur, et le score peut être inspecté par cet utilisateur. C’est ce qui fait que l’expérience commence à ressembler à une infrastructure qui peut agir en votre nom sans devenir une plateforme.

## Comment les relations évoluent comme observé

Dans un flux, votre graphique relationnel est généralement statique une fois formé. Vous suivez les gens, vous ne les suivez que rarement, et tout le reste n'est que signal sonore que la plateforme interprète pour vous. Dans ce substrat, le graphique est façonné par les observations.

Chaque écriture dactylographiée déplace légèrement une relation. Une invitation envoyée déplace le bord dans une direction. Une invitation acceptée le fait avancer. Le chevauchement de fréquentation enregistré par les deux agents le déplace encore plus loin. Une conversation enregistrée, une note partagée ou une entité de projet que les deux nœuds touchent chacun laissent une observation à la limite entre deux contacts, avec provenance et horodatage.

L’inverse est également vrai. Les bords se dégradent lorsque rien ne se passe. Un contact que vous n'avez pas invité, avec lequel vous n'avez pas assisté ou sur lequel vous n'avez pas écrit depuis un an est un type d'avantage différent de celui que vous avez vu le week-end dernier. La dégradation n’est pas une suppression. L'historique est toujours là pour la récupération. Mais le score de pertinence de l'agent demain utilise la pondération la plus récente, donc une année de silence coûte de la visibilité avant de coûter à la relation elle-même.

Cela inverse le modèle de flux de la manière qui compte. Les flux font du graphique l’entrée et de l’activité la sortie. Ce substrat fait de l’activité l’entrée et du graphique la sortie. Les relations évoluent parce que le comportement est un état structuré, et non parce que quelqu'un a cliqué sur « Suivre » une fois en 2014 et que la plateforme prétend depuis lors que le bord signifie toujours quelque chose.

## Qu'est-ce que ce n'est pas

Il ne s’agit pas d’une tentative de remplacer les invitations créées par des humains. Le travail du substrat est de rendre une invitation manuscrite moins chère à envoyer, plus sûre d'atterrir et plus difficile à spammer. Chaque couche ci-dessus est destinée à repousser l’expérience vers ce que j’ai correctement identifié en 2012 comme la véritable monnaie sociale : quelqu’un en qui vous avez confiance a pensé à vous spécifiquement. Le substrat ne peut pas fabriquer cette pensée. Il peut refuser de livrer des substituts.

## Ce qui est encore ouvert

Il y a quelques points pour lesquels je n'ai pas encore de bonnes réponses.

- Comment les budgets d'invitation doivent être libellés et renouvelés. Par événement, par semaine, par mesh ? Lié au taux d’acceptation ?
- Comment les changements de portée du maillage se propagent lorsque les relations changent. À quoi cela ressemble-t-il de révoquer une portée sans brûler une relation ?
- Interopérabilité entre maillages lorsque les participants exécutent différentes implémentations de maillage. Cela nécessite-t-il une fine couche de protocole ?
- Gestion des abus lorsqu'un expéditeur précédemment admis commence à envoyer du spam. Qui applique la pénalité, le nœud de maillage du destinataire ou le substrat dans son ensemble ?
- Histoire de migration pour les événements dont le RSVP canonique se trouve derrière un paywall ou une connexion.

Ce sont de vraies questions, mais ce sont des questions de produits et de protocoles qui s’ajoutent à un substrat qui fonctionne déjà. Ce ne sont pas des inconnus architecturaux.

## Pourquoi j'écris ceci maintenant

Il y a quelques semaines, Oo Nwoye a laissé un commentaire public sur un [article récent](https://markmhendrickson.com/posts/) sur la mémoire des agents et a demandé, en quelques termes, si Plancast devait être ressuscité pour l'ère de l'IA. La réponse est la même que celle ci-dessus. La mission initiale était correcte. Le substrat n'était pas le bon. Le substrat existe désormais.

Je ne pense pas que la solution soit de reconstruire Plancast en tant qu'application. La réponse est de créer des invitations, des présences et des étendues de confiance en tant que primitives sur une couche d'état personnel souverain, de laisser les agents faire le travail d'ingestion et de routage, et de laisser la mécanique sociale émerger du fait qu'une invitation est une écriture tapée dans un état durable au lieu d'un événement de flux ambiant.

Si vous avez construit ou êtes en train de construire quelque chose dans ce quartier, j'aimerais en parler.