Macula - An Ecosystem for Mesh-native Computing

Macula - An Ecosystem for Mesh-native Computing

Macula - 一种网格原生计算生态系统

Macula is a mesh network for services and applications, built on Erlang/OTP: a node dials out over QUIC to one or more relay stations, which route its RPC calls, fan out its pub/sub events, and move content and streams between it and everyone else on the mesh. No inbound ports on the client side, no VPN, no central broker any one operator controls. Think of it less as “a client library for my server” and more as “the internet is one big distributed event bus, and here’s how you dial into it.”

Macula 是一个基于 Erlang/OTP 构建的面向服务和应用程序的网格网络:节点通过 QUIC 协议向一个或多个中继站发起外呼连接,由中继站负责路由 RPC 调用、分发发布/订阅事件,并在网格中的各方之间传输内容和流。客户端无需开放入站端口,无需 VPN,也不存在任何由单一运营商控制的中央代理。与其将其视为“服务器的客户端库”,不如将其理解为“互联网是一个巨大的分布式事件总线,而这就是你接入它的方式”。

It’s been in continuous development since late 2025, macula (the core SDK) is at v10.14.1 on hex.pm, and the station side runs our own production fleet today. Four language ports exist beyond Erlang (Go, Rust, PHP, .NET), plus a CLI, an MCP server, and the relay itself. What’s actually in the SDK, and what it’s built on macula (hex.pm, Erlang/OTP) is the client side: the primitives an application dispatches against. macula-station (separate repo, also Erlang/OTP) is the relay: it’s what actually does the routing, and it’s where most of the algorithmic work lives.

该项目自 2025 年底以来一直处于持续开发中,Macula(核心 SDK)目前在 hex.pm 上的版本为 v10.14.1,且中继站端目前已在我们的生产环境中运行。除了 Erlang 之外,还存在四种语言的移植版本(Go、Rust、PHP、.NET),以及一个 CLI 工具、一个 MCP 服务器和中继器本身。SDK 的核心内容及其构建基础(hex.pm, Erlang/OTP)构成了客户端侧:即应用程序进行调度的原语。macula-station(独立仓库,同样基于 Erlang/OTP)是中继器:它负责实际的路由工作,也是大部分算法逻辑所在之处。

QUIC (HTTP/3) transport: every connection is outbound-only, so a client never needs an open inbound port. Independent stream multiplexing means one slow stream doesn’t head-of-line-block the others (the actual problem QUIC was designed to fix over TCP-based HTTP/2), and connection migration means a session survives a network change, which matters once you’re talking to a phone switching from wifi to cellular mid-call. TLS 1.3 is built in, not bolted on. The transport itself is a Rust NIF (Quinn underneath), shared by the SDK and the station.

QUIC (HTTP/3) 传输:所有连接均为仅外呼模式,因此客户端无需开放入站端口。独立的流多路复用意味着一个缓慢的流不会阻塞其他流(这是 QUIC 旨在解决 TCP 协议下 HTTP/2 的核心问题),而连接迁移功能确保了会话在网络切换时依然存活,这对于手机在通话中从 Wi-Fi 切换到蜂窝网络等场景至关重要。TLS 1.3 是内置的,而非后期添加。传输层本身是一个 Rust NIF(底层使用 Quinn),由 SDK 和中继站共享。

Kademlia DHT: the routing table. Signed, TTL’d records for advertisements, endpoints, and presence, resolved via multi-round iterative lookup. This answers “which station is this capability actually reachable through”: resolve once against the DHT, then dial that station directly. One hop, no relay sitting in the data path afterward.

Kademlia DHT:路由表。通过多轮迭代查找来解析带有签名和 TTL(生存时间)的广告、端点和在线状态记录。它解决了“该功能实际上可以通过哪个中继站访问”的问题:先在 DHT 中解析一次,然后直接拨号连接该中继站。仅需一跳,后续数据路径中不再有中继器参与。

SWIM-Lifeguard: membership and failure detection, no central heartbeat server. Direct and indirect probing plus gossiped dissemination is plain SWIM; Lifeguard adds the adaptive suspicion timeout that keeps a busy node from getting falsely marked dead under load.

SWIM-Lifeguard:成员资格和故障检测,无需中央心跳服务器。直接和间接探测加上流言协议(gossip)传播是基础的 SWIM;Lifeguard 则增加了自适应怀疑超时机制,防止繁忙节点在高负载下被错误地标记为宕机。

HyParView + Plumtree: the newest layer (landed in the core SDK around 9.2.0-10.5.0, additive, no supervised OTP wrapper around it yet). HyParView keeps a bounded partial view of the mesh per realm instead of every station knowing about every other station; Plumtree builds an epidemic broadcast tree over that view so a fact reaches everyone without flooding the whole mesh to do it. This is what keeps pub/sub fan-out and multi-hop RPC relay from becoming an all-to-all problem as the mesh grows.

HyParView + Plumtree:最新层(在 9.2.0-10.5.0 版本左右进入核心 SDK,属于附加功能,尚未封装受监督的 OTP 包装器)。HyParView 为每个领域维护网格的有限局部视图,而不是让每个中继站都了解其他所有中继站;Plumtree 在该视图之上构建流行病广播树,使信息能够传达给所有人,而无需淹没整个网格。这防止了随着网格增长,发布/订阅分发和多跳 RPC 路由演变成全网广播问题。

Content addressing: BLAKE3-hashed blocks, MCID identifiers, chunked put/get with discovery. Cancel is a real peer-visible QUIC RESET_STREAM, not a local give-up that leaves the other side hanging. Identity and authorization: Ed25519 keypairs, UCAN capability tokens (mint/verify/introspect), DID documents, NIF-accelerated. Authorization is capability-based, a UCAN the caller presents, not a session or account the station has to look up.

内容寻址:BLAKE3 哈希块、MCID 标识符、带发现功能的块式存取。取消操作是真正的对等可见的 QUIC RESET_STREAM,而不是让对方挂起的本地放弃。身份与授权:Ed25519 密钥对、UCAN 能力令牌(生成/验证/内省)、DID 文档,均经过 NIF 加速。授权基于能力,即调用者出示的 UCAN,而非中继站需要查询的会话或账户。

macula-station is realm-agnostic and holds no application data of its own, realm membership and identity belong to whatever connects through it. One process, one Ed25519 identity, peers outbound with other stations to form the mesh; run one and it’s an island, give it peers and it’s part of something bigger.

macula-station 与领域无关,自身不持有任何应用程序数据,领域成员资格和身份属于通过它连接的任何事物。一个进程,一个 Ed25519 身份,通过向外与其他中继站建立对等连接来形成网格;运行一个节点它就是一座孤岛,为其添加对等节点,它就成为了更大系统的一部分。

It’s been running our own multi-station fleet continuously since 2026-04-14 (500+ commits at this point) against real traffic: DHT, SWIM, pub/sub relay, RPC relay (including genuine multi-hop, a call can cross two stations with no direct peering edge between them), streaming relay, content transfer. It’s already got real consumers beyond its own tooling.

自 2026 年 4 月 14 日以来,它一直在我们的多中继站集群中持续运行(目前已有 500 多次提交),处理真实流量:DHT、SWIM、发布/订阅中继、RPC 中继(包括真正的多跳,调用可以跨越两个没有直接对等连接的中继站)、流中继和内容传输。除了自身的工具外,它已经拥有了实际的消费者。

hecate-services (a separate org) builds independently-deployed services on Macula: RAG, an LLM gateway, DNS, git, mail, each an ordinary outbound-only Macula client, several sharing a common substrate library, hecate-om, for identity, health, and capability-advertising boilerplate. The most fun one to actually look at is hecate-whiteboard: a real-time collaborative whiteboard, Miro minus the company, a host runs it on their own node and collaborators dial into that host over Macula to draw together. It talks to Macula directly rather than through hecate-om, and cross-node sync is still the next piece; today it’s real-time within one host, but the mesh-hosting and identity side already works end to end.

hecate-services(一个独立的组织)在 Macula 上构建了独立部署的服务:RAG、LLM 网关、DNS、git、邮件,每个都是普通的仅外呼 Macula 客户端,其中几个共享一个公共基底库 hecate-om,用于处理身份、健康状况和能力广告的样板代码。最有趣的是 hecate-whiteboard:一个实时协作白板,即“去公司化的 Miro”,主机在自己的节点上运行它,协作者通过 Macula 拨入该主机进行共同绘图。它直接与 Macula 通信,而不是通过 hecate-om,跨节点同步仍是下一步工作;目前它在单个主机内实现了实时协作,但网格托管和身份验证端已经实现了端到端的工作。

Beyond Erlang: the other language ports. Four ports exist so far: Go, Rust, PHP, .NET, each a from-scratch reimplementation of the wire protocol, not a wrapper around the Erlang node. All are real, shipped, hex/npm-equivalent published. The Rust one is worth a closer look: its own README tagline is “mobile first, not mobile-only”. It’s feature-complete for a leaf/edge client and live-verified against the production station fleet: handshake (pinned or WebPKI trust), unary RPC, pub/sub, content transfer, and streaming RPC in both caller and provider roles, direct-dial with cert-chain authorization, UCAN mint/verify/introspect, and a per-platform-overridable KeyStore for identity persistence.

超越 Erlang:其他语言移植。目前已有四个移植版本:Go、Rust、PHP、.NET,每个都是对线路协议的从零重写,而非对 Erlang 节点的包装。所有版本都是真实的、已发布且等同于 hex/npm 的包。Rust 版本值得特别关注:其 README 的标语是“移动优先,而非仅限移动端”。它作为叶子/边缘客户端功能完备,并已在生产中继站集群中进行了实时验证:握手(固定或 WebPKI 信任)、一元 RPC、发布/订阅、内容传输,以及调用者和提供者角色的流式 RPC、带证书链授权的直接拨号、UCAN 生成/验证/内省,以及用于身份持久化的各平台可重写 KeyStore。

A separate macula-rust-ffi crate (structured the way iroh-ffi sits on top of iroh) wraps almost that entire surface with UniFFI and generates Kotlin and Swift bindings on every push, CI-checked both ways: one Rust core, generated bindings on both mobile platforms, instead of hand-maintaining two implementations of the same wire protocol. The mobile apps built on top of it are still early; the FFI layer underneath them is not.

一个独立的 macula-rust-ffi crate(结构类似于 iroh-ffi 之于 iroh)使用 UniFFI 封装了几乎整个接口,并在每次推送时生成 Kotlin 和 Swift 绑定,通过 CI 进行双向检查:一个 Rust 核心,在两个移动平台上生成绑定,而不是手动维护同一线路协议的两个实现。基于此构建的移动应用尚处于早期阶段,但底层的 FFI 层已经非常成熟。

The tools: what you actually run. Everything above is what you build with. Three things exist to actually run: macula-cli: a small, scriptable Go binary, no TUI, no interactive mode. Every command works identically with or without —json; human-readable output is a formatting choice, not a separate code path. connect stages the handshake.

工具:你实际运行的内容。以上所有内容都是你构建时使用的。实际运行的工具有三个:macula-cli:一个小型、可脚本化的 Go 二进制文件,没有 TUI,没有交互模式。每个命令在带或不带 —json 参数时工作方式完全相同;人类可读的输出只是一种格式化选择,而不是单独的代码路径。connect 命令用于执行握手阶段。