Skip to main content
Retour aux billets
Sept. 20269 min de lecture

Le canapé a emporté un morceau du mur du sous-sol en sortant. J'ai construit le planificateur que personne ne m'a vendu

Chaque planificateur de pièce jamais construit répond est-ce que ça rentre dans la pièce. Elbow Room répond à la question qui coûte de l'argent et du plâtre : est-ce que ça peut seulement y arriver. A prédit deux résultats réels chez moi qui s'étaient déjà produits (un canapé qui n'est pas passé, un chauffe-eau de 279 litres qui est passé), s'accorde à 1,63 x 10^-6 pouces près avec une solution fermée vieille de 300 ans pour l'angle, et embarque 19 outils WebMCP pour qu'un agent puisse piloter le canvas en parlant. Bonus inter-origines : une boutique de meubles séparée peut interroger mon escalier via un outil partagé en lecture seule, les deux côtés consentent par leur nom.

WebMCPModel Context ProtocolCanvasHomographyNumerical GeometryCross-OriginPlaywrightVercelHackathonShowDev
J'ai écrit ce billet pour le hackathon WebMCP (sept. 2026), et j'ai construit Elbow Room pour la même soumission. En direct sur elbowroom.jonathanandrei.com, code source sur github.com/JonathanSolvesProblems/elbow-room, les deux ouverts, sans clé, sans compte. #webmcp
La revendication en une phrase : chaque planificateur de pièce jamais construit répond est-ce que ça rentre dans la pièce. Elbow Room répond à la question qui coûte de l'argent et du plâtre : est-ce que ça peut seulement y arriver. Sur les deux objets que le même escalier a vus dans la vraie vie (un canapé de 91 x 36 po et un chauffe-eau Giant 172E-3F8M) il prédit ce qui s'est vraiment passé les deux fois. Deux sur deux, et le juge, c'est le plâtre.
Verdict d'Elbow Room : le canapé dépasse de 3 pi 9 1/2 po le virage. Chaque chiffre vient d'un ruban à mesurer, pas d'une estimation.
Le verdict, dans les unités que le ruban à mesurer a données. Le virage permet 3 pi 9 1/2 po à cette profondeur et le canapé fait 7 pi 7 po, plus du double de ce que ce coin passera jamais. La coloration par contact plutôt que par ajustement vient de la leçon du chauffe-eau : une chose peut techniquement rentrer et emporter le mur au passage.

Le problème, sur mon propre escalier

Un canapé est resté coincé dans l'escalier du sous-sol. Il s'est arrêté net dans le virage et refusait de tourner peu importe comment je l'inclinais. Il est sorti à la fin, et il a emporté un morceau du mur. Puis c'est arrivé à quelqu'un d'autre. Une inondation a forcé le remplacement d'un chauffe-eau et les installateurs ont descendu un réservoir de 279 litres par le même escalier sans rien poser d'abord sur les murs. Les éraflures le long du bord du soffite sont les leurs, pas celles du canapé. Deux objets, un escalier, personne n'a mesuré ni une fois ni l'autre, et nulle part où chercher. La fiche de la propriété donne les treize pièces au pouce près et ne dit rien sur les escaliers. La seule mesure qui décide si votre meuble peut entrer n'apparaît sur aucune fiche, aucun plan et aucune page produit.

Est-ce que ça marche, et qui le dit

Trois affirmations, aucune notée par moi. Premièrement, l'app a prédit deux résultats réels qui s'étaient déjà produits. L'escalier a une histoire qui précède ce logiciel. Le canapé fait 91 x 36 pouces sur un ruban. Le chauffe-eau est un Giant 172E-3F8M, 24 po de diamètre sur 59 7/8 de haut, d'après la fiche technique du fabricant plutôt que de mes propres mesures. Prédit que le canapé ne passe pas : il n'est pas passé, le mur a pris les dégâts. Prédit que le chauffe-eau passe : il est passé, le soffite a pris les dégâts. n=2, dit clairement, et deux de plus qu'une simple affirmation.

Un chauffe-eau rendu dans la cage d'escalier, celui-ci passant le virage. Les deux outils correctifs (try_removing_door, adjust_clearance) se désenregistrent dès qu'il n'y a plus d'échec.
Le réservoir passe. Il a aussi passé le virage avec 3 pi 9 1/2 po de marge dans la vraie vie et a quand même emporté le mur en descendant, ce qui explique pourquoi la vue 3D colore par contact et non par ajustement. Rentrer et rentrer sans rien toucher sont deux réponses différentes.

Les maths sur lesquelles personne n'a à me faire confiance

Deuxième affirmation : le solveur d'angle est d'accord avec un résultat vieux de trois cents ans. La plus longue tige mince qui tourne un angle droit entre des couloirs de largeur a et b est (a^(2/3) + b^(2/3))^(3/2), une forme fermée dans n'importe quel manuel de calcul. Elbow Room n'utilise pas cette formule. Il minimise a/sin t + b/cos t - w/(sin t x cos t) numériquement parce qu'un canapé a une largeur et qu'une tige n'en a pas. Fixez la largeur à zéro et les deux doivent s'accorder. Sur 169 paires de largeurs de 24 à 60 pouces, ils divergent d'au plus 1,63 x 10^-6 pouces, et sur le vrai escalier ils s'accordent à la précision machine. eval/closed_form.mjs, une commande, pas de clé. Un juge peut vérifier la formule en trente secondes sans faire confiance à une seule ligne de mon code.

Troisièmement : les maths photo-vers-pouces sont vérifiées contre une caméra qu'elles n'ont jamais vue. Quatre correspondances cliquées déterminent une homographie entre l'image et le plan du sol. Vérifiée contre une caméra synthétique avec de la vraie perspective, des distances que la calibration n'a jamais vues reviennent à quatre millièmes de pouce près. C'est ce qui fait de la page /measure/ des vrais pouces plutôt qu'une échelle de pixels devinée.

Quatre coins cliqués sur une photographie du sol du sous-sol, et chaque clic suivant tombe en vrais pouces sur le plan. Une photographie, aucune reconstruction.
Rectification métrique d'une seule image. Quatre coins de quelque chose dont vous connaissez la vraie taille deviennent une homographie ; chaque pixel de ce sol devient des pouces. Pas de GPU, pas d'upload, pas de serveur. L'agent vous accompagne et enregistre chaque mesure avec save_reading, et le planificateur tourne alors contre votre maison au lieu de la mienne.

Pourquoi WebMCP était la bonne forme

L'état intéressant vit dans un <canvas>, et un canvas est invisible pour un agent. Aucun élément à lire, rien à cliquer. Ce n'est pas une affirmation, c'est mesuré, sans tête et sans clé API, dans eval/interface_comparison.py. Le premier résultat m'a corrigé. En lisant l'état déjà à l'écran, l'arbre d'accessibilité répond à 7 questions sur 8, parce que la barre latérale affiche le verdict en texte. Le canvas est invisible, la page ne l'est pas. Ce tableau part exactement comme il est sorti.

La vraie question est de demander quelque chose que la page n'affiche pas, ou de le changer. Là, un agent piloté par le DOM a un contrôle pour seulement 3 tâches sur 7, contre 7 sur 7 via les outils du site. La distinction n'est pas lire contre lire : le DOM expose un état figé, les outils exposent la fonction. Un agent peut lire que ce canapé échoue. Sans outils il ne peut pas demander ce qui rentrerait, ne peut pas réessayer sans la porte, ne peut pas placer l'objet à une coordonnée, et ne peut pas soumettre une mesure à un humain pour approbation.

La vue document.modelContext en direct dans la page : 19 outils enregistrés sur trois surfaces, avec readOnlyHint sur les lectures et untrustedContentHint sur celui qui renvoie du texte tapé.
19 outils sur trois pages. 15 dans le planificateur (six lectures avec readOnlyHint, six écritures, record_measurement comme la consécutive derrière requestUserInteraction, deux qui ne s'enregistrent que pendant qu'il y a un échec et se désenregistrent via AbortSignal quand ça s'arrête). 4 dans la page de mesure. 1 partagé entre origines, en lecture seule. Noms sous 30 caractères, descriptions sous 500, sorties plafonnées à 1,5 Ko, zéro violation.

Une boutique de meubles séparée interroge votre escalier

halliwell-and-co.vercel.app est une origine séparée qui vend un canapé. Elle intègre le planificateur et appelle check_fit à travers la frontière. Le consentement est mutuel : l'outil nomme la boutique dans exposedTo, la boutique nomme l'origine de l'outil dans fromOrigins, et le navigateur refuse l'enregistrement dans une iframe inter-origines sans allow="tools". L'un des trois retiré et rien ne se passe. Exactement un outil est partagé, et il est en lecture seule. La boutique obtient un oui ou un non sur un canapé dont elle a déjà publié les dimensions ; elle n'apprend jamais vos mesures, ne voit jamais le plan et ne peut rien déplacer. C'est la partie de cette spec qui parle vraiment du web ouvert : deux sites sans API entre eux, sans SDK, sans compte partagé, qui coopèrent parce que les deux ont dit oui.

Halliwell and Co, une origine séparée qui vend un canapé, montrant un verdict Passes check-fit renvoyé par mon escalier via le partage d'outils inter-origines de WebMCP.
La boutique de meubles demande, mon escalier répond, les deux côtés ont consenti par leur nom. Pas de compte, pas de clé API, pas de SDK, pas d'URL de rappel. Toute la poignée de main tient dans deux chaînes d'origine concordantes et un attribut de permission du navigateur.

Ce que le chauffe-eau a appris à l'app

Le chauffe-eau a passé le virage avec 3 pi 9 1/2 po de marge et a quand même emporté le mur en descendant. Alors rentrer, et rentrer sans rien toucher, sont devenues deux réponses différentes. La vue 3D colore l'objet selon qu'il touche, pas selon qu'il rentre, à cause de cet après-midi. Limitations honnêtes : corps rigides uniquement, donc un matelas plie et son verdict est une borne inférieure. La hauteur au-dessus du virage est estimée plutôt que mesurée, et eval/headroom_sensitivity.mjs balaie toutes les valeurs plausibles pour montrer que le verdict ne bouge pas. La vérité terrain pour les prédictions du monde réel, ce sont deux objets. n=2, dit comme n=2.

Projet associé

Elbow Room: before you buy the couch, find out whether it can get up the stairs

Voir le projet