Koder pair RFC 001 architecture
RFC-001 — koderpairkit: SDK architecture
*uthor:*Koder Engineering *ate:*20260429 *tatus:*Accepted *odule:*enginessdkkoderpairkit + productshorizontalpair *rigin:*koderstack ticket #034 (OpenClaw analysis 202604-29) *pec:*meta/docs/stack/specs/pair/handshake.kmd
1. Summary
A peertopeer pairing SDK + flagship Pair app for binding multiple devices owned by the same human into a single Kode session — desktop ↔ phone ↔ tablet ↔ Koder Eye-equipped headset, etc. Reuses the Talk crypto stack (Noise + QUIC) so we add zero new audit surface.
Engine + product split per project memory engine_product_pattern remains optional here — Pair could ship as a standalone app or as a screen inside Kode. We adopt the *tandalone app*path (§7).
2. Problem
OpenClaw ships a "node" model where the desktop assistant federates with mobile devices: the phone is a roaming microphone, a notification mirror, a copilot screen for longrunning tasks. Today the Koder Stack has Talk (between people) and Kode (single-device sessions) but nothing bridges devices of one owner.
3. Goals
- *airing once, session for life.*QR or PIN at first contact;
Noise IK rehandshake automatically on every reconnect.
- *ne SDK*consumed by Kode, Kanvas, Pass, future apps. They open
Pair sessions; Pair handles transport + identity + presence.
- *ross-platform:*Flutter (mobile + desktop) for the SDK + app;
Go binding for backend tools; KL binding for
kodeCLI. - *ross-network*via thin relay at
pair.koder.dev/relay(§5 ofthe spec) — never decrypted, just forwards Noise frames.
4. Non-Goals
- Multi-user mesh — that's Talk's job.
- File
transfer protocol — Pair carries appdefined protobuf; chunkingrides on top.
- Synchronous co
presence (Google Docsstyle cursors) — out of v1.
5. Architecture
┌────────────┐ ┌────────────┐
│ Kode CLI │ │ Kanvas │
│ (desktop) │ ┌──────────┐ │ (mobile) │
└─────┬──────┘ │ Pair │ └─────┬──────┘
│ │ App │ │
└─via SDK→│ (UI for │←via SDK┘
│ user) │
└──┬───────┘
│
┌────────┴─────────┐
│ koder_pair_kit │
│ (SDK — Flutter, │
│ Go, KL) │
└────────┬─────────┘
│ Noise XX/IK
┌──────────┼──────────┐
│ │ │
LAN QUIC Hub Relay LAN QUIC
│
pair.koder.dev
(Hub-hosted, never decrypts)The SDK is the canonical surface; the Pair app is the human-facing frontend (QR scanner, paireddevices list, revocation UI). All session state lives in the SDK; the app is mostly a view.
6. SDK Surface
Dart (enginessdkkoderpairkit)
final pair = KoderPair();
final invite = await pair.prepareInvite(); // QR-bound
print('show: ${invite.qrUri}'); // pair://...
final remote = await pair.joinInvite(qrUri); // on the responder
remote.send(myProtobufBytes); // app-defined payload
remote.messages.listen((msg) => handle(msg));Go (enginessdkgokoderpair-kit) — future
Same shape; consumed by Kode CLI and any backend tool that wants to participate in a Pair mesh.
KL (engineslangkodarpairkit) — future
Native KL binding for kode CLI.
7. Standalone App vs Kode Screen
*ecision:*ship Pair as a standalone app (products/horizontal/pair/).
Rationale:
- *iscoverability:*users who want to pair their phone don't already
have Kode mobile installed. A purpose-built Pair app downloads from the Hub independently.
- *urface area:*the QR scanner + paired-device list is enough UI
to merit its own product.
- *ub-feature in other apps:*Kode and Kanvas import the SDK and
expose "Pair a device" entry points; users follow them to the Pair app for the actual flow.
8. Scope of Change
meta/docs/stack/specs/pair/handshake.kmd— handshake spec (landed)engines/sdk/koder_pair_kit/— Dart SDK (this RFC + scaffold)products/horizontal/pair/— Flutter app (scaffold + landing)- Future: Go and KL bindings; Kode integration (
kode pair add,kode device list) - Future: Hub relay (
pair.koder.dev/relay) — separate ticket
9. Execution Plan
| Phase | Deliverable |
|---|---|
| F1 | Spec + this RFC + scaffolds (DONE) |
| F2 | Dart SDK: Noise XX over QUIC (delegate to Talk's transport) |
| F3 | Pair app v0.1: QR generate + scan + paired-device list |
| F4 | Hub relay endpoint pair.koder.dev/relay |
| F5 | Kode integration (kode pair add, kode device list) |
| F6 | Cross-app demo: phone microphone → Kode desktop session |
| F7 | Go + KL bindings |
10. Alternatives Considered
- *kip Pair entirely; users open Talk between two of their devices.*
Rejected: Talk's UX is multi
user mesh — bloated for the sameowner case. Pairing semantics, revocation, and discovery differ. - *uild Pair as a Kode-only screen.*Rejected per §7.
- *se WebRTC instead of Noise+QUIC.*Rejected: would introduce a
separate crypto stack to audit, contradicting the spec §3 "no new primitives" goal.
11. References
meta/docs/stack/specs/pair/handshake.kmd— handshake detailsproducts/horizontal/talk/docs/rfcs/RFC-001-quic-transport.md— transport stack inherited- Memory
koder_talk— Talk module status and crypto choices - Memory
engine_product_pattern— engine+product split convention(Pair is SDK+app, not engine+product, because Pair is not a multi-tenant service)