Communitygithub.com

voluminor/skill-yggdrasil

Skill de agente para construir aplicaciones de red mesh Yggdrasil en Go (mediante la librería ratatoskr): clientes embebidos, servidores HTTP/TCP/UDP, SOCKS5, reenvío de puertos, gestión de pares, NodeInfo/sigilos — en espacio de usuario, sin TUN ni root.

¿Qué es skill-yggdrasil?

Este skill permite a un agente de IA (como Claude Code, Cursor o Codex) crear programas en Go que se conectan y sirven en la red mesh cifrada de extremo a extremo Yggdrasil. Soporta clientes embebidos, servidores HTTP/TCP/UDP, proxies SOCKS5, reenviadores de puertos y nodos que publican metadatos de descubrimiento. El nodo se ejecuta **en espacio de usuario** sobre una pila de red gVisor — sin dispositivo TUN, sin root, sin demonio `yggdrasil` externo, y sin binario `yggstack`. La librería de embebido es `github.com/voluminor/ratatoskr`, y se usa creando el nodo con `ratatoskr.New` y manejando todo a través de su API Go estándar (`net.Conn`, `net.Listener`, `net.PacketConn`, `http.Transport`). El skill enfatiza el diseño para una malla restringida (alta latencia, bajo ancho de banda, pérdidas) y ofrece referencias detalladas para cada componente: pares, SOCKS, reenvío, NodeInfo, sigilos personalizados y plantillas de integración con frameworks como net/http, fasthttp, gRPC y gnet. También incluye una guía de errores comunes y un mapa de referencias para mantener el archivo `SKILL.md` como capa de navegación.

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

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

Redes Yggdrasil en Go

Resumen

Usa este skill para construir programas Go que se conecten y sirvan en la malla cifrada de extremo a extremo IPv6 de Yggdrasil: clientes, servidores HTTP/TCP/UDP, proxies SOCKS5, reenviadores de puertos y nodos que publiquen metadatos de descubrimiento. El nodo se ejecuta en espacio de usuario sobre una pila de red gVisor — sin dispositivo TUN, sin root, sin demonio yggdrasil externo y sin binario yggstack. Te conectas y escuchas sobre Yggdrasil con interfaces Go estándar (net.Conn, net.Listener, net.PacketConn, http.Transport).

La librería de embebido es github.com/voluminor/ratatoskr: crea el nodo con ratatoskr.New y maneja todo a través de su API Go. El alcance y la estabilidad de sus paquetes se resumen a continuación.

Diseño para una malla restringida

Yggdrasil es una malla superpuesta cifrada de extremo a extremo, no un tejido de centro de datos. Los enlaces tienen alta latencia, bajo ancho de banda, pérdidas y son intermitentes; un par alcanzable ahora puede desaparecer un segundo después, y el tráfico puede cruzar muchos saltos. Construye cada solución Yggdrasil como si fuera para una conexión débil e inestable. Esto no es un pulido opcional — es la forma predeterminada del código correcto aquí.

  • Nunca sin límite. Un plazo límite en cada llamada y solicitud (context.WithTimeout); reintentos acotados; colas acotadas. Sin esperas infinitas.
  • Limita la concurrencia. Restringe el trabajo en vuelo: SOCKS MaxConnections, reenvío SetMaxUDPSessions, http.Transport.MaxConnsPerHost/MaxIdleConnsPerHost, tus propios pools de workers. Ambos valores por defecto son ilimitados — establece límites reales.
  • Fragmenta transferencias grandes, verifica, reanuda. Nunca muevas un archivo grande de una sola vez. Divídelo en trozos pequeños (p. ej., HTTP Range), verifica cada uno (tamaño/checksum) y hazlo reanudable para que un enlace caído cueste un trozo, no toda la transferencia.
  • Reintenta con retroceso + jitter, de forma idempotente. Espera desconexiones durante la operación. Haz las operaciones reanudables/idempotentes; retroceso exponencial con jitter; limita los intentos.
  • Mantén las cargas pequeñas. Evita protocolos charlatanes y sondeos; comprime; usa codificaciones compactas. Mantén NodeInfo/sigilos muy por debajo del límite de 16 KB.
  • Ajusta los buffers al enlace. Usa node.MTU() para buffers de paquetes (la MTU en espacio de usuario es dinámica, con mínimo en 1280).
  • Degrada, no golpees. Ante fallos, retrocede y devuelve resultados parciales; nunca reintentes agresivamente a un par ni inundes la malla.

Un enfoque ingenuo de "servir un archivo grande sobre net/http" o "una solicitud/respuesta gigante" es la forma incorrecta. La forma correcta es acotada, fragmentada, reanudable y tolerante a fallos por defecto. Consulta el patrón de transferencia en malla restringida en references/integrations.md.

Fuente de la verdad

El módulo activo es la autoridad — no la memoria, ni texto README desactualizado, ni este skill. Antes de escribir orientación específica de una versión, inspecciona de qué depende realmente el proyecto:

go list -m github.com/voluminor/ratatoskr   # versión seleccionada
go doc github.com/voluminor/ratatoskr       # API raíz compilada
go doc github.com/voluminor/ratatoskr/mod/peermgr ConfigObj

Para leer el código fuente real de la versión seleccionada, resuélvelo desde la caché del módulo en lugar de adivinar una ruta:

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

No congeles la versión mínima de Go del texto README — puede ir por detrás de la directiva go.mod. Lee el go.mod activo de la versión Ratatoskr seleccionada.

Flujo de trabajo predeterminado

  1. Identifica la forma de la aplicación: nodo embebido, cliente/servidor HTTP, TCP/UDP puro, SOCKS5, reenvío de puertos, gestión de pares, o NodeInfo/sigilos.
  2. Usa el paquete raíz github.com/voluminor/ratatoskr para aplicaciones. Accede a mod/core solo a través del contrato core.Interface; evita *core.Obj/UnsafeCore() a menos que un paquete de bajo nivel lo requiera genuinamente.
  3. Posee un context.Context, pásalo como ratatoskr.ConfigObj.Ctx, y aún así haz defer node.Close() después de un inicio exitoso. Ambos son necesarios.
  4. Configura pares en exactamente un lugar:
    • Pares Yggdrasil estáticos: cfg.Config.Peers
    • Gestor de pares Ratatoskr: ratatoskr.ConfigObj.Peers (entonces deja cfg.Config.Peers vacío, o New devuelve ErrPeersConflict).
  5. Usa node.DialContext para TCP/UDP saliente y node.Listen / node.ListenPacket para servicios dentro de Yggdrasil.
  6. Encierra direcciones IPv6 entre corchetes en URLs y cadenas host-puerto: http://[200:abcd::1]:8080, nunca http://200:abcd::1:8080.
  7. Trata el enlace como débil: pon un plazo límite en cada llamada, limita la concurrencia y fragmenta/verifica/reanuda transferencias grandes (consulta Diseño para una malla restringida).
  8. Cuando generes código en un proyecto real, añade una verificación de compilación o una prueba enfocada en lugar de asumir que compila.

Alcance del módulo y estabilidad

Las direcciones Yggdrasil se derivan de la clave del nodo, por lo que la superficie de red es pequeña y estable. Prefiere las partes que la librería considera terminadas; marca explícitamente el resto en lugar de construir sobre ello.

PaqueteEstadoÚsalo a través de
raíz ratatoskrEstable, API principalNew, EnableSOCKS, Ask/AskAddr, Snapshot, Close
mod/coreContrato establelos métodos core.Interface embebidos en el nodo
mod/peermgrEstableratatoskr.ConfigObj.Peers
mod/socksEstablenode.EnableSOCKS (no instancies directamente)
mod/resolverEstablecreado automáticamente por EnableSOCKS; el uso directo es avanzado
mod/forwardEstableforward.New → Add* → Start
mod/sigils (+ info, services, public, inet)Estableratatoskr.ConfigObj.Sigils
mod/ninfoEstablenode.Ask / node.AskAddr
mod/probeAvanzado / inestable — requiere UnsafeCore(), la API puede cambiarsolo cuando se requiera explícitamente trazado de topología/ruta
mod/settingsTrabajo en curso — esquema no finalizadoevita; usa yggdrasil-go/src/config directamente
cmd/*Aplicaciones de ejemplo, no API de librería importableléelas como patrones, nunca las importes

Raíz vs submódulos: por defecto usa ratatoskr.New (core + SOCKS + gestor de pares + ninfo + sigilos detrás de un solo Close). Baja a mod/core mediante core.New solo para la superficie más pequeña (llamada/escucha raw), o compón submódulos alrededor de core.Interface para transportes personalizados y pruebas. Cada submódulo (peermgr/socks/forward/resolver/ninfo) recibe un core.Interface. Consulta references/overview.md.

Sigilos del sistema — publica aquí primero

NodeInfo es cómo un nodo se describe a sí mismo en la red. Cuatro sigilos integrados ("del sistema") son analizados automáticamente por cada nodo, por lo que los datos que pongas en ellos serán reconocidos por otros participantes. Recurre a estos antes de inventar un sigilo personalizado; pásalos a través de ratatoskr.ConfigObj.Sigils. Mantén cada uno pequeño — comparten un presupuesto de NodeInfo de 16 KB.

SigiloQué pertenece aquíPor qué usarlo
infoIdentidad del nodo: nombre, tipo, ubicación, contactos, descripciónPermite que otros sepan quién/qué es tu nodo.
servicesPuertos que expones dentro de Yggdrasil, como nombre → puertoDescubrimiento de servicios sin escaneo de puertos.
publicTus URIs de peering público agrupadas por redPermite que otros se conecten directamente contigo.
inetTus direcciones del mundo real (dominios/IPs)Mapa tu nodo Yggdrasil a identidad en Internet claro.

Pon datos estándar y detectables en estos para que toda la red pueda leerlos. Solo define un sigilo personalizado para datos que ninguno de los cuatro cubra — y recuerda que solo los pares que ejecuten tu código lo analizarán. Los constructores validan y devuelven errores; manéjalos antes de ratatoskr.New. Detalles, límites exactos, acceso tipado y creación de sigilos personalizados: references/nodeinfo-sigils.md y references/custom-sigils.md.

Mapa de referencias

Lee solo los archivos necesarios para la tarea actual:

Errores comunes

ErrorCorrección
Iniciar un demonio Yggdrasil externo para una aplicación embebidaUsa ratatoskr.New; ejecuta una pila de red gVisor en espacio de usuario.
Recomendar yggstack para integración de libreríayggstack es un binario para usuario final. Usa Ratatoskr para control de API Go.
Establecer tanto cfg.Config.Peers como ConfigObj.PeersElige pares estáticos o el gestor de pares; nunca ambos → ErrPeersConflict.
Pasar Ctx pero omitir Close (o viceversa)Haz ambos: la cancelación desencadena el apagado, Close libera recursos.
Construir URLs sin corchetes IPv6Usa fmt.Sprintf("http://[%s]:%d", ip, port).
Crear ninfo.New para consultas básicasUsa node.Ask / node.AskAddr; el objeto raíz ya construye ninfo.
Ensamblar o registrar sigilos dinámicamente en tiempo de ejecuciónLos sigilos se ensamblan estrictamente en código; las claves duplicadas o sobrescritas son errores graves por diseño, no fusiones silenciosas. Publica mediante ConfigObj.Sigils; lee tus propias claves de res.Node.Extra.
Recurrir a UnsafeCore() / mod/probe / mod/settings por defectoMantente en la API raíz; estos son avanzados o trabajo en curso.
Hardcodear una versión de Go desde READMELee el go.mod activo de la versión del módulo seleccionado.

Validación

Mantén SKILL.md como capa de navegación y pon los detalles pesados de la API en references/. Prueba los cambios contra los escenarios en evals/evals.json antes de publicar.

Skills relacionados