# Yonexus Yonexus is a cross-instance communication system for OpenClaw built as **three separate repositories**: | Repository | Role | |---|---| | `Yonexus` | Umbrella — architecture, planning, and coordination | | `Yonexus.Server` | Central hub plugin — accepts client connections, handles pairing/authentication | | `Yonexus.Client` | Client plugin — connects to server, manages local identity | | `Yonexus.Protocol` | Shared protocol specification — referenced as a submodule by both Server and Client | ## Overview ### Yonexus.Server Installed on the central OpenClaw instance. Responsibilities: - run the WebSocket server - maintain the client registry - handle pairing and authentication - track heartbeat and liveness state - relay messages to connected clients - rewrite inbound client messages before rule dispatch - notify a human administrator of pairing requests via Discord DM ### Yonexus.Client Installed on follower OpenClaw instances. Responsibilities: - connect to `Yonexus.Server` - manage local keypair and shared secret - complete pairing with out-of-band pairing code - authenticate on reconnect - send periodic heartbeat - send messages to server - receive messages from server via rule dispatch ### Yonexus.Protocol Shared protocol specification repository. Both `Yonexus.Server` and `Yonexus.Client` reference this as a submodule at `protocol/`. --- ## Repository Structure ``` Yonexus (umbrella) ├── Yonexus.Protocol ← shared protocol submodule ├── Yonexus.Server ← server plugin submodule │ └── protocol/ ← points to Yonexus.Protocol └── Yonexus.Client ← client plugin submodule └── protocol/ ← points to Yonexus.Protocol ``` --- ## Architecture A Yonexus network contains: - exactly one OpenClaw instance running `Yonexus.Server` - one or more OpenClaw instances running `Yonexus.Client` Topology rules: - `Yonexus.Server` must be reachable via a stable address - `Yonexus.Client` instances connect outbound to the server - direct client-to-client sockets are not required in v1 - client-to-client communication, if needed, is relayed by the server --- ## Security Model Pairing is intentionally **out-of-band**. When a new client needs pairing: - the server generates a pairing code - the server sends that pairing code by Discord DM to a configured human admin - the pairing code is **not** sent over the Yonexus WebSocket connection - the human relays the code to the client side manually - the client submits the code back through the protocol After pairing: - the server issues a shared secret - the client stores its private key and secret locally - reconnect authentication uses signed proof derived from `secret + nonce + timestamp` --- ## Current Repository Spec Files ### Umbrella (`Yonexus`) - `PLAN.md` — project plan and architecture - `ARCHITECTURE.md` — architecture overview and repository graph - `FEAT.md` — implementation feature checklist ### Protocol (`Yonexus.Protocol`) - `PROTOCOL.md` — shared communication protocol specification ### Server (`Yonexus.Server`) - `PLAN.md` — server-specific implementation plan - `protocol/` — submodule pointing to `Yonexus.Protocol` ### Client (`Yonexus.Client`) - `PLAN.md` — client-specific implementation plan - `protocol/` — submodule pointing to `Yonexus.Protocol` --- ## Planned TypeScript APIs ### Yonexus.Server ```ts sendMessageToClient(identifier: string, message: string): Promise registerRule(rule: string, processor: (message: string) => unknown): void ``` ### Yonexus.Client ```ts sendMessageToServer(message: string): Promise registerRule(rule: string, processor: (message: string) => unknown): void ``` Message format: ```text ${rule_identifier}::${message_content} ``` Reserved rule: `builtin` --- ## Planned Server Config ```json { "followerIdentifiers": ["client-a", "client-b"], "notifyBotToken": "", "adminUserId": "123456789012345678", "listenHost": "0.0.0.0", "listenPort": 8787, "publicWsUrl": "wss://example.com/yonexus" } ``` ## Planned Client Config ```json { "mainHost": "wss://example.com/yonexus", "identifier": "client-a", "notifyBotToken": "", "adminUserId": "123456789012345678" } ``` --- ## Shared Terminology To keep the umbrella repo, protocol repo, and both plugin repos aligned, Yonexus uses these terms consistently: - `identifier`: the stable logical name of a follower/client instance, unique within one Yonexus network. - `rule_identifier`: the exact-match application routing key used in `${rule_identifier}::${message_content}`. - `builtin`: the reserved rule namespace for Yonexus protocol/control messages only. - `pairingCode`: the short-lived out-of-band code generated by `Yonexus.Server` and delivered to a human admin by Discord DM. - `secret`: the server-issued shared secret established after successful pairing and used in reconnect authentication proof construction. - `publicKey` / `privateKey`: the client-owned signing keypair used for auth proof signing and verification. - `nextAction`: the server decision returned in `hello_ack`, currently one of `pair_required`, `waiting_pair_confirm`, `auth_required`, or `rejected`. ## v1 Scope Boundaries In scope for v1: - WebSocket transport between one server and one or more clients - out-of-band pairing via Discord DM to a human administrator - signed reconnect authentication using `secret + nonce + timestamp` - heartbeat/liveness tracking (`online | unstable | offline`) - exact-match rule dispatch - lightweight persistence for trust/state material - optional `heartbeat_ack` - exponential reconnect backoff on the client side Explicitly out of scope for v1: - multi-server topology - direct client-to-client sockets - offline message queues / delivery guarantees - advanced rule matching (prefix/regex/wildcard) - management UI - distributed consensus / clustering - automatic admin approve/deny workflows beyond human relay of the pairing code - encryption-at-rest hardening beyond documenting local sensitive storage behavior ## Status - umbrella/specification repo is aligned with the split architecture - core implementation work is underway in `Yonexus.Server`, `Yonexus.Client`, and `Yonexus.Protocol` - protocol/types/codec/test scaffolding already exists in `Yonexus.Protocol` - runtime, transport, pairing, auth, heartbeat, rule dispatch, and test coverage are largely implemented in submodules; remaining work is focused on boundary cleanup and leftover failure-path coverage --- ## Repository URLs - [Yonexus (umbrella)](https://git.hangman-lab.top/nav/Yonexus) - [Yonexus.Server](https://git.hangman-lab.top/nav/Yonexus.Server) - [Yonexus.Client](https://git.hangman-lab.top/nav/Yonexus.Client) - [Yonexus.Protocol](https://git.hangman-lab.top/nav/Yonexus.Protocol)