hultra-link
v1.0.1
Published
Annuaire vérifié des capacités appelables par les agents — ce qui répond encore, mesuré et daté.
Readme
Contrôle technique de l'écosystème des agents
Dossier de transmission, constitué le 12 août 2026, remis à l'état du dépôt le 14 août 2026 (#33) puis le 19 août (#56), puis le 25 août (#93, #113) - la section « État » ci-dessous porte sa propre date, et c'est elle qui compte. Destiné à un agent qui reprend le projet sans aucun contexte préalable.
Ordre de lecture
| # | Fichier | Pourquoi le lire | Durée |
|---|---|---|---|
| 1 | PRESENTATION.md | le pourquoi du projet, en dix minutes | court |
| 2 | CHIFFRES.md | tout ce qui a été mesuré, avec la méthode | moyen |
| 3 | SOURCES.md | ce qu'il faut avoir lu avant d'écrire une ligne | moyen |
| 4 | PRD.md | les spécifications complètes - le quoi et le comment | long |
| 5 | NOTES.md | la direction visuelle | court |
| 6 | mesures/ | le code qui a produit les chiffres, et ses résultats - trace, pas socle | à consulter |
| 7 | AGENTS.md | les règles de travail dans le dépôt, pour un agent | court |
| 8 | docs/ | format.md : le contrat des fichiers publiés. methode.md : comment chaque verdict est produit. agents/ : domaine, suivi des tickets, étiquettes | à consulter |
| 9 | src/, deploiement/ | le code qui tourne, et comment le poser sur une machine | à consulter |
Ne pas commencer par le PRD. Il suppose acquis le problème et les chiffres.
La carte de travail est le ticket #3 : elle porte le protocole de session obligatoire, les décisions déjà prises et ce qui reste ouvert. Le dossier dit le projet ; la carte dit où il en est.
Les trois choses à retenir avant tout
1. Le but n'est pas de classer ce qui marche, mais de trouver ce qui ne marche pas. Toute décision de conception se tranche par cette question. Les classements de gagnants existent déjà ; le détecteur de pannes n'existe nulle part.
2. Trois erreurs de méthode ont été commises pendant les mesures, toutes dans
le sens d'une surestimation de la casse. Elles sont documentées dans PRD.md
§4.2 et CHIFFRES.md §12. Les lire avant d'écrire le moindre sondeur : elles
coûtent une journée chacune à retrouver.
3. Aucune valeur sans sa source et sa date. C'est la règle qui distingue ce projet des six annuaires morts qu'il recense - leurs chiffres n'avaient pas d'âge, donc personne n'a vu qu'ils avaient vieilli.
État au 25 août 2026
Mesuré (12 août 2026, détail et méthode en CHIFFRES.md) : le registre MCP
paginé en entier (71 049 entrées), 2019 serveurs sondés en JSON-RPC, 28 376
outils collectés, brique d'audit validée en conditions réelles, risque de blocage
d'IP testé et écarté. Depuis, sous Bun : 141 serveurs/s au plateau
(#17, 13 août 2026) et les
277 registres shadcn sondés en 16,1 s, 88,1 % vivants
(#22, 13 août 2026).
Sept familles sont mesurées au 25 août 2026, et une famille n'existe qu'à
un seul endroit — src/familles.ts : MCP, shadcn (289 registres),
A2A (#90),
llms.txt (#95), les
marketplaces Claude Code
(#98), OpenAPI
(#102) et NANDA
(#105) — les cinq
dernières entrées les 24 et 25 août.
Le sondage d'entrée d'A2A porte sur 245 agents — 246 annoncés par
a2aregistry.org, dont un enregistrement que le registre ne sait pas sérialiser
— avec 172 vivants et 134 à la portée appel (CHIFFRES.md §9.5, 12:50 UTC).
Celui de llms.txt porte sur 1 584 URL publiées par llmstxt.site :
1 221 sont un llms.txt conforme au format publié, soit 77,1 % — c'est la
première fois que le produit mesure la justesse d'un annuaire vivant
(CHIFFRES.md §9.6, 14:08 UTC). C'est aussi la première famille sans
registre : sa liste de départ est amorcée, donc sa couverture n'est jamais
affichable en pourcentage.
Celui des marketplaces Claude Code porte sur 273 dépôts — le topic publié
claude-code-marketplace plus le dépôt officiel, qui ne le porte pas : 239
ont un marketplace.json conforme, soit 87,5 %, et 11,4 % se déclarent
marketplaces sans avoir de fichier de marketplace (CHIFFRES.md §9.7,
15:53 UTC).
Celui d'OpenAPI porte sur 1 978 spécifications sondées chez leur
fournisseur et non dans l'annuaire : 725 ne répondent plus, soit 36,7 % —
le taux le plus élevé de toutes les familles. Son annuaire, api.apis.guru,
a l'air vivant et ne l'est pas : dernière spécification touchée le 21 avril
2023, dernier commit sur son dépôt le 20 avril 2026, 4 539 étoiles, non archivé
(CHIFFRES.md §9.8, 17:16 UTC).
Celui de NANDA porte sur 264 documents de faits : son index annonce
13 600 agents et en rend 300 (×45,3), et le factsUrl qu'il publie rend
404 pour 195 d'entre eux. Son status, lui, est juste à 84,3 % — on attendait
que le mensonge soit le statut, c'est l'URL qui ment (CHIFFRES.md §9.9,
25 août 2026).
Les sept familles sont dans le latest.json publié — 29 779 entrées au
25 août 2026 à 08:16 UTC : 25 139 mcp, 1 978 openapi, 1 584 llmstxt,
289 shadcn, 277 marketplace, 264 nanda, 248 a2a
(curl -s https://donnees.hultra.link/latest.json). Les cinq dernières y sont
entrées par la boucle seule, sans passe-droit.
Elles sont dans le latest.json publié depuis le 24 août 2026 : la boucle
les a ingérées, sondées et exportées seule, sans passe-droit — 244 entrées a2a
sur 25 502, sous les sources registre-a2a et sonde-a2a
(curl -s https://donnees.hultra.link/latest.json, 24 août 2026, 14:05 UTC).
Écrit : les blocs §10.1 à §10.4 de l'ordre de construction. Depuis le
14 août s'ajoutent la CLI dans ses deux canaux — npm et PyPI, avec la
fixture commune de verifie-config que le §4.9 rend obligatoire
(#42) — et le serveur
MCP, qui annonce la version courante de la spec et figure dans son propre
annuaire — son entrée est dans le latest.json publié, sous la source
auto-inscription (#44).
Elle y attend son tour de sondage comme les 23 485 autres : aucun passe-droit,
donc aucune mesure tant que l'élection ne l'a pas prise (sante.motif:
jamais_sonde au 19 août). Le sondeur du produit la valide en local — vivant,
spec 2026-07-28, 5 outils, 106 ms.
234 tests TypeScript et 8 Python passent (bun run test:tout, 25 août 2026),
dont un test différentiel qui fait passer les mêmes entrées dans les deux canaux
de la CLI. Aucune CI ne les lance : ces deux suites se lancent à la main, et
PRD.md §4.9 le dit désormais
(#56).
Au 14 août 2026, origin/main portait déjà huit modules sous src/ (base
SQLite, sondeur MCP, sondeur de registres shadcn, ingestion du registre, passage,
auto-mesure, export, veilleur), 35 tests qui passent (bun test, 14 août
2026), six unités systemd sous deploiement/ (trois services, trois timers), le
Worker veilleur (wrangler.jsonc,
#15) et les deux templates
d'applications sous apps/ (702 fichiers suivis, mesurés par
git ls-tree -r --name-only c7bc967 apps | wc -l le 19 août 2026 ; #20 en
annonçait 704,
#20) - ces templates ne
sont plus là : ramenés à 220 fichiers par
#38, puis à 49 par
#57 (find apps -type f |
wc -l, 19 août 2026). Socle Bun / TypeScript, tranché en séance sur mesures
(#9) ; entre les deux
implémentations du socle, socle-src a été retenue
(#25).
Publié, mais pas encore autonome : au 18 août 2026, l'export est en ligne —
https://donnees.hultra.link/latest.json, 23 264 entrées, plus sante.json,
latest.md, llms.txt et les instantanés datés
(#12). Le veilleur est
déployé et son alerte a été vue partir et arriver
(#15).
« Pas encore autonome » n'est plus vrai, et le dire compte autant que l'avoir
écrit. Au 20 août 2026, sante.json mesurait 40 adresses contrôlées sur
12 738 joignables en 24 h (0,3 %) et les deux cycles du 18 août avaient été
lancés à la main. Depuis le 21 août la boucle tourne seule — crontab de
l'utilisateur agent, quatre travaux : passage toutes les 5 min, ingestion à
:07, export à :37, sauvegarde à 23:50. Au 25 août, retard_max_h vaut 0
et jamais_controlees 0, sur 29 832 entrées publiées.
Ce qui a été réparé le 25 août, et qui explique pourquoi elle ne tenait pas
avant : la poussée R2 n'avait ni délai ni reprise — un export a tourné
11 147 s et gelé la boucle, trous de sondage de 226 et 104 minutes, 14
passages morts en SQLITE_BUSY
(#113) ; ouvre()
écrivait à chaque ouverture et SQLite abandonnait le verrou sans attendre,
faute de busy_timeout
(#107) ; et aucun travail
n'était borné dans le temps sur le chemin cron
(#13). La base n'avait
aucune sauvegarde — 73 297 contrôles qui ne se reconstituent pas
(#115).
Le veilleur est armé et il tire. Son cron horaire était installé mais
vide, et son code lisait un champ supprimé depuis #77 ; redéployé le 25 août,
il alerte [email protected], et la chaîne complète a été prouvée de bout en
bout — cron, code, Resend, boîte reçue
(#93).
Ce qui manque encore, et il ne faut pas l'arrondir non plus :
deploiement/installe.shn'a jamais été lancé : il demande root, qui n'est pas disponible sur cette machine. Le chemin cron a rattrapé la seule garantie qui lui manquait — la borne de durée, aux mêmes valeurs que les unités — mais le durcissement (ProtectSystem, utilisateur système dédié) reste au seul chemin systemd (#72).- La sauvegarde est sur la même machine que la base. Une copie hors machine demande une destination privée : le seau R2 de publication est servi publiquement en entier.
- Le compte des sept jours consécutifs n'a pas commencé, et il ne peut pas
encore être tenu :
retard_max_hest calculée à chaque export et publiée, mais jamais conservée. Les instantanés n'en gardent qu'un point par jour ; une dérive entre deux instantanés serait invisible. Tant que la série n'est pas journalisée, le critère §11 ne pourra qu'être affirmé, jamais constaté — c'est #13, et c'est le chemin critique.
Reste : les blocs §10.5 à §10.7 (audit, recensement des familles,
popularité) et les deux applications, qui repartent de zéro — et cette fois
sans filet : apps/ n'est plus une bibliothèque de templates où piocher. La
réserve « au cas où » de #20
et #19 a été révisée par le
porteur le 19 août 2026 (#29
groupe D) et appliquée par
#57 : il reste 49 fichiers
dans apps/, les deux applications confondues (find apps -type f | wc -l,
19 août 2026). Ordre de construction en PRD.md §10 ; état ticket par ticket sur
la carte #3.
Conditions de fin de la v1 : elles sont trois depuis #19, et l'ordre compte — les deux applications lisent l'export, rien ne se vérifie avant qu'il existe.
- La machine — le fichier d'état se régénère seul chaque nuit, sans aucune intervention. Vérifiable :
auto_mesure.retard_max_hreste sous 1 h pendant sept jours consécutifs, sans que personne n'ait touché la machine (PRD.md§11). Ce critère disait « l'âge du contrôle le plus ancien reste sous 24 h » — inatteignable sur une machine parfaite, le palierstableespaçant délibérément ses entrées à 72 h. Arbitré par le porteur le 24 août 2026 (#71).apps/public— un script tire N entrées au hasard delatest.json, ouvre le site publié, et échoue si une valeur affichée diverge du fichier ou si l'âge affiché n'est pas celui de l'export. Sept nuits consécutives.apps/admin— un tour complet depuis le navigateur seul : inviter un compte, déclarer un serveur privé, le voir sondé et daté, émettre un ordre de resondage, trancher une contestation qui apparaît dans lelatest.jsonsuivant. Un seulsshnécessaire = pas fini.
Décisions non prises
Volontairement laissées ouvertes, à trancher avec le porteur du projet :
- l'entité, personnelle ou société - dans les deux cas rattachée à l'UE, condition du droit sui generis sur la base de données (dir. 96/9/CE art. 11). Hors périmètre de la carte #3 : ne conditionne pas la régénération nocturne
- la procédure de contestation des verdicts publiés sur des tiers, exigée avant
la première publication sur des tiers nommés (
PRD.md§8, §12)
Tranché depuis :
- la licence des données - ODbL 1.0 + DbCL 1.0 pour les données, Apache-2.0
pour le code (
LICENSE-DONNEES.md,LICENSE), #10, 13 août 2026 - le nom et le domaine - produit Link,
hultra-linkpartout (npm, PyPI, exécutable), hôte uniquehultra.linkavec l'export à la racine, #9, 13 août 2026. Le dépôt s'appellehultra-linkdepuis le 31 août 2026 (#18) : le renommage était reporté à avant la première publication, il a eu lieu une semaine après elle. Le nomconnectest brûlé — la redirection GitHub depuis l'ancien nom meurt si un dépôt du compte le reprend
Détail en PRD.md §12.
Contenu du dossier
README.md ce fichier
PRESENTATION.md le projet, son pourquoi, son modèle économique
CHIFFRES.md tous les chiffres mesurés, datés et sourcés
SOURCES.md les sources à maîtriser, classées par nécessité
PRD.md les spécifications complètes
NOTES.md direction visuelle
AGENTS.md les règles de travail dans le dépôt, pour un agent
LICENSE Apache-2.0, pour le code
LICENSE-DONNEES.md ODbL 1.0 + DbCL 1.0, pour les données
src/ le socle qui tourne - Bun / TypeScript
base.ts le schéma SQLite et les accès
familles.ts LE REGISTRE DES FAMILLES — le seul endroit où une famille
existe : sa sonde, son ingestion, ses clés de source, sa
table de santé (#66, #90)
registre.ts ingestion du registre MCP ; son point d'entrée itère FAMILLES
sonde.ts le sondeur MCP : handshake JSON-RPC et verdict
shadcn.ts le sondeur de registres shadcn, et l'index (#22)
a2a.ts le sondeur A2A et le registre a2aregistry.org (#90)
llmstxt.ts le sondeur llms.txt et son amorçage par liste publiée (#95)
marketplace.ts le sondeur des marketplaces Claude Code (#98)
openapi.ts le sondeur OpenAPI, aux origines déclarées par apis.guru (#102)
nanda.ts le sondeur AgentFacts, index projectnanda (#105)
passage.ts un passage de la boucle : élection par palier, puis sondage
mesure.ts l'auto-mesure §4.11
sauvegarde.ts la copie datée de la base, VACUUM INTO + rotation (#115)
export.ts latest.json / latest.md / snapshots / llms.txt, et la poussée
veilleur.ts le Worker Cloudflare qui alerte sur l'âge publié (#15)
annuaire.ts la lecture de l'annuaire publié, partagée CLI + MCP (#29)
cli.ts la CLI, canal npm - six commandes (#42)
mcp.ts le serveur MCP, Worker, cinq outils (#44)
*.test.ts 234 tests (`bun run test`, 25 août 2026)
cli-py/ la CLI, canal PyPI - seconde implémentation, stdlib (#42)
docs/fixtures/ la fixture commune de `verifie-config`, passée par les deux (§4.9)
deploiement/ six unités systemd (passage, registre, export), la marche à
installe.sh suivre pour poser la boucle et publier, et le script qui fait
les sept gestes en une fois — relançable, `--verifie` sous
n'importe quel utilisateur (#72)
docs/
format.md le contrat des fichiers publiés (#8)
methode.md comment chaque verdict est produit — publié à côté des
données, une section par sondeur (#93)
agents/ domaine, suivi des tickets, étiquettes de triage
apps/ les deux applications, ramenées à leur squelette (#38 puis
admin/ #57) : 49 fichiers en tout au 19 août 2026, builds statiques
public/ sous Bun, ni SSR ni Vercel. La réserve de composants ReUI
(#20) est partie (#57) ; restent les deux primitives que
`routes/__root.tsx` monte réellement, sonner et tooltip
wrangler.jsonc la configuration du Worker veilleur (src/veilleur.ts)
wrangler-mcp.jsonc la configuration du Worker serveur MCP (src/mcp.ts, #44)
package.json les scripts Bun : ingestion, passage, export, test, typecheck
bun.lock
tsconfig.json
mesures/ la trace de la mesure - Python, pas le socle
crawl.py santé HTTP de masse
sonde_mcp.py handshake JSON-RPC, version de spec négociée
outils_mcp.py session complète et collecte des outils
popularite.py pagination du registre, npm et PyPI
debits.ts les débits re-mesurés sous Bun (#17)
echo_version.ts la contre-mesure du piège 4 : 94,4 % d'écho (#63)
a2a.ts le sondage d'entrée de la famille A2A, n = 245 (#90)
llmstxt.ts le sondage d'entrée de llms.txt, n = 1 584 (#95)
marketplace.ts le sondage d'entrée des marketplaces, n = 273 (#98)
openapi.ts le sondage d'entrée d'OpenAPI, n = 1 978 (#102)
nanda.ts le sondage d'entrée de NANDA, n = 264 (#105)
openapi_appel.ts le plafond `appel` d'OpenAPI — « la spec ment », n = 86 (#68)
*.json les résultats réels de ces scriptsLes scripts de mesures/ sont en Python stdlib pur, sans aucune dépendance. Ils
portent en commentaire la panne qui a motivé chaque choix - c'est là que se
trouve le savoir qui ne se redevine pas.
Ils ne sont pas le socle du projet. Le produit s'écrit en Bun /
TypeScript (PRD.md §3 #16, tranché le 13 août 2026) sous src/ ; mesures/
est la trace datée de la mesure et reste en Python, tel quel. Le lire pour la
méthode et pour les pannes, jamais pour le runtime.
