Communitygithub.com

voluminor/skill-yggdrasil

Compétence d'agent pour créer des applications de réseau maillé Yggdrasil en Go (via la bibliothèque ratatoskr) : clients embarqués, serveurs HTTP/TCP/UDP, SOCKS5, redirection de ports, gestion de pairs, NodeInfo/sigils — en espace utilisateur, sans TUN ni root.

Qu'est-ce que skill-yggdrasil ?

Cette compétence permet de développer des programmes Go qui se connectent et servent sur le réseau maillé Yggdrasil, un overlay IPv6 chiffré de bout en bout. Elle inclut la création de clients, serveurs HTTP/TCP/UDP, proxies SOCKS5, redirections de ports, et nœuds publiant des métadonnées de découverte. Le nœud s'exécute entièrement en espace utilisateur via une pile réseau gVisor, sans nécessiter de périphérique TUN, de privilèges root, de démon Yggdrasil externe ni de binaire yggstack. Tout le contrôle s'effectue via l'API Go de la bibliothèque `github.com/voluminor/ratatoskr`. La compétence met l'accent sur une conception adaptée aux contraintes du maillage : latence élevée, bande passante faible, pertes et instabilité. Les recommandations incluent l'utilisation de délais d'expiration, la limitation de la concurrence, le découpage en blocs et la reprise des transferts, ainsi que la gestion des erreurs avec backoff et jitter. Elle couvre également les sigils système (info, services, public, inet) pour la découverte et la publication de données standardisées. Les plateformes cibles sont les agents comme Claude Code, Cursor ou Codex, où elle sert de guide pour implémenter des applications Yggdrasil robustes en Go.

Compatible avec✓Claude Code~Codex CLI~Cursor
npx skills add voluminor/skill-yggdrasil

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Réseautage Yggdrasil en Go

Aperçu

Utilisez cette compétence pour créer des programmes Go qui se connectent et servent sur le Yggdrasil — un maillage IPv6 chiffré de bout en bout : clients, serveurs HTTP/TCP/UDP, proxies SOCKS5, redirections de ports, et nœuds publiant des métadonnées de découverte. Le nœud s'exécute en espace utilisateur sur une pile réseau gVisor — pas de périphérique TUN, pas de root, pas de démon yggdrasil externe, et pas de binaire yggstack. Vous établissez des connexions et écoutez sur Yggdrasil avec les interfaces Go standard (net.Conn, net.Listener, net.PacketConn, http.Transport).

La bibliothèque d'intégration est github.com/voluminor/ratatoskr : créez le nœud avec ratatoskr.New et pilotez tout via son API Go. La portée et la stabilité de ses paquets sont résumées ci-dessous.

Conception pour un maillage contraint

Yggdrasil est un maillage superposé chiffré de bout en bout, pas un tissu de centre de données. Les liaisons sont à latence élevée, faible bande passante, sujettes aux pertes et intermittentes ; un pair joignable maintenant peut disparaître une seconde plus tard, et le trafic peut traverser de nombreux sauts. Construisez chaque solution Yggdrasil comme si elle était destinée à une connexion faible et instable. Ce n'est pas une amélioration facultative — c'est la forme par défaut d'un code correct ici.

  • Jamais sans limite. Un délai d'expiration sur chaque appel et requête (context.WithTimeout) ; tentatives limitées ; files d'attente bornées. Pas d'attentes infinies.
  • Limitez la concurrence. Limitez le travail en cours : MaxConnections SOCKS, SetMaxUDPSessions pour la redirection, http.Transport.MaxConnsPerHost/MaxIdleConnsPerHost, vos propres pools de workers. Par défaut, tout est illimité — définissez des limites réelles.
  • Segmentez les gros transferts, vérifiez, reprenez. Ne déplacez jamais un gros fichier en une seule fois. Divisez en petits morceaux (par ex. Range HTTP), vérifiez chacun (taille/somme de contrôle), et rendez-le reprenable afin qu'une connexion perdue coûte un seul morceau, pas tout le transfert.
  • Répétez avec backoff + jitter, de manière idempotente. Attendez-vous à des déconnexions en cours d'opération. Rendez les opérations reprenables/idempotentes ; backoff exponentiel avec jitter ; limitez les tentatives.
  • Gardez les charges utiles petites. Évitez les protocoles bavards et le polling ; compressez ; utilisez des encodages compacts. Gardez les NodeInfo/sigils bien en dessous de la limite de 16 Ko.
  • Taille des buffers adaptée à la liaison. Utilisez node.MTU() pour les tampons de paquets (la MTU en espace utilisateur est dynamique, plancher à 1280).
  • Dégradation, pas de martelage. En cas d'échec, réduisez la cadence et retournez des résultats partiels ; ne répétez jamais agressivement une tentative vers un pair ou n'inondez pas le maillage.

Un « servir un gros fichier via net/http » naïf ou « une seule requête/réponse géante » est la mauvaise forme. La bonne forme est limitée, segmentée, reprenable, tolérante aux pannes par défaut. Voir le modèle de transfert pour maillage contraint dans références/intégrations.md.

Source de vérité

Le module actif est faisant autorité — pas la mémoire, pas un texte README obsolète, pas cette compétence. Avant d'écrire des conseils spécifiques à une version, inspectez ce dont le projet utilise réellement comme dépendances :

go list -m github.com/voluminor/ratatoskr   # version sélectionnée
go doc github.com/voluminor/ratatoskr       # API racine telle que compilée
go doc github.com/voluminor/ratatoskr/mod/peermgr ConfigObj

Pour lire le code source réel de la version sélectionnée, résolvez-le depuis le cache de modules autrement que par la devinette d'un chemin :

go list -m -f '{{.Dir}}' github.com/voluminor/ratatoskr

Ne figez pas la version minimale de Go à partir du texte README — elle peut être en retard par rapport à la directive go.mod. Lisez le go.mod actif de la version de Ratatoskr sélectionnée.

Flux de travail par défaut

  1. Identifiez la forme de l'application : nœud embarqué, client/serveur HTTP, TCP/UDP brut, SOCKS5, redirection de ports, gestion de pairs, ou NodeInfo/sigils.
  2. Utilisez le paquet racine github.com/voluminor/ratatoskr pour les applications. Accédez à mod/core uniquement via le contrat core.Interface ; évitez *core.Obj/UnsafeCore() sauf si un paquet de bas niveau l'exige véritablement.
  3. Possédez un context.Context, passez-le comme ratatoskr.ConfigObj.Ctx, et utilisez quand même defer node.Close() après un démarrage réussi. Les deux sont nécessaires.
  4. Configurez les pairs à un seul endroit :
    • Pairs Yggdrasil statiques : cfg.Config.Peers
    • Gestionnaire de pairs Ratatoskr : ratatoskr.ConfigObj.Peers (puis laissez cfg.Config.Peers vide, sinon New retourne ErrPeersConflict).
  5. Utilisez node.DialContext pour le TCP/UDP sortant et node.Listen / node.ListenPacket pour les services à l'intérieur d'Yggdrasil.
  6. Mettez les adresses IPv6 entre crochets dans les URL et les chaînes hôte-port : http://[200:abcd::1]:8080, jamais http://200:abcd::1:8080.
  7. Traitez la liaison comme faible : mettez un délai d'expiration sur chaque appel, limitez la concurrence, et segmentez/vérifiez/reprenez les gros transferts (voir Conception pour un maillage contraint).
  8. Lorsque vous générez du code dans un projet réel, ajoutez une vérification de compilation ou un test ciblé plutôt que de supposer que cela se compile.

Portée et stabilité du module

Les adresses Yggdrasil sont dérivées de la clé du nœud, donc la surface réseau est petite et stable. Préférez les parties que la bibliothèque considère comme finalisées ; signalez le reste explicitement plutôt que de vous appuyer dessus.

PaquetStatutUtilisation via
racine ratatoskrStable, API principaleNew, EnableSOCKS, Ask/AskAddr, Snapshot, Close
mod/coreContrat stableles méthodes core.Interface intégrées au nœud
mod/peermgrStableratatoskr.ConfigObj.Peers
mod/socksStablenode.EnableSOCKS (ne pas instancier directement)
mod/resolverStablecréé automatiquement par EnableSOCKS ; l'utilisation directe est avancée
mod/forwardStableforward.New → Add* → Start
mod/sigils (+ info, services, public, inet)Stableratatoskr.ConfigObj.Sigils
mod/ninfoStablenode.Ask / node.AskAddr
mod/probeAvancé / instable — nécessite UnsafeCore(), l'API peut changeruniquement lorsque le traçage de topologie/route est explicitement requis
mod/settingsEn cours — schéma non finaliséà éviter ; utilisez yggdrasil-go/src/config directement
cmd/*Applications d'exemple, pas une API de bibliothèque importablelisez comme modèles, n'importez jamais

Racine vs sous-modules : par défaut, utilisez ratatoskr.New (core + SOCKS + gestionnaire de pairs

  • ninfo + sigils derrière un seul Close). Descendez à mod/core via core.New uniquement pour la surface minimale (dial/listen brut), ou composez des sous-modules autour de core.Interface pour des transports personnalisés et des tests. Chaque sous-module (peermgr/socks/forward/resolver/ninfo) prend un core.Interface. Voir références/aperçu.md.

Sigils système — publiez ici d'abord

NodeInfo est la façon dont un nœud se décrit sur le réseau. Quatre sigils système (intégrés) sont analysés automatiquement par chaque nœud, donc les données que vous y mettez sont reconnues par les autres participants. Utilisez-les avant d'inventer un sigil personnalisé ; passez-les via ratatoskr.ConfigObj.Sigils. Gardez chacun très petit — ils partagent un budget NodeInfo de 16 Ko.

SigilCe qui va iciPourquoi l'utiliser
infoIdentité du nœud : nom, type, emplacement, contacts, descriptionPermet aux autres de savoir qui/qu'est votre nœud.
servicesPorts que vous exposez dans Yggdrasil, sous forme nom → portDécouverte de services sans scan de ports.
publicVos URI de peering public regroupés par réseauPermet aux autres de se peer directement avec vous.
inetVos adresses du monde réel (domaines/IP)Mappe votre nœud Yggdrasil à une identité clearnet.

Mettez des données standard et découvrables dans ces sigils pour que tout le réseau puisse les lire. Ne définissez un sigil personnalisé que pour des données qu'aucun des quatre ne couvre — et rappelez-vous que seuls les pairs exécutant votre code l'analyseront. Les constructeurs valident et retournent des erreurs ; gérez-les avant ratatoskr.New. Détails, limites exactes, accès typé, et création de sigils personnalisés : références/nodeinfo-sigils.md et références/sigils-personnalisés.md.

Carte de référence

Lisez uniquement les fichiers nécessaires à la tâche en cours :

Erreurs courantes

ErreurCorrection
Démarrer un démon Yggdrasil externe pour une application embarquéeUtilisez ratatoskr.New ; il exécute une pile réseau gVisor en espace utilisateur.
Recommander yggstack pour l'intégration bibliothèqueyggstack est un binaire utilisateur final. Utilisez Ratatoskr pour le contrôle via l'API Go.
Définir à la fois cfg.Config.Peers et ConfigObj.PeersChoisissez les pairs statiques ou le gestionnaire de pairs ; jamais les deux → ErrPeersConflict.
Passer Ctx mais sauter Close (ou vice versa)Faites les deux : l'annulation déclenche l'arrêt, Close libère les ressources.
Construire des URL sans crochets IPv6Utilisez fmt.Sprintf("http://[%s]:%d", ip, port).
Créer ninfo.New pour des requêtes de baseUtilisez node.Ask / node.AskAddr ; l'objet racine construit déjà ninfo.
Assembler ou enregistrer des sigils dynamiquement à l'exécutionLes sigils sont assemblés strictement dans le code ; les clés en double ou écrasantes sont des erreurs dures par conception, pas des fusions silencieuses. Publiez via ConfigObj.Sigils ; lisez vos propres clés depuis res.Node.Extra.
Utiliser UnsafeCore() / mod/probe / mod/settings par défautRestez sur l'API racine ; ceux-ci sont avancés ou en cours de développement.
Coder en dur une version de Go depuis le READMELisez le go.mod actif de la version de module sélectionnée.

Validation

Gardez SKILL.md comme couche de navigation et mettez les détails lourds de l'API dans références/. Testez les changements par anticipation par rapport aux scénarios dans évaluations/évaluations.json avant de publier.

Skills associés