aboutsummaryrefslogtreecommitdiffstats
path: root/PLAN.md
diff options
context:
space:
mode:
authorbndw <ben@bdw.to>2026-03-08 21:59:24 -0700
committerbndw <ben@bdw.to>2026-03-08 21:59:24 -0700
commit53b10eab74d83522dd90af697773e32279469b30 (patch)
tree05429ae0439990ed52121b38bb927f474058ea12 /PLAN.md
parente3ac28b9f829c54f88db20245ad58b7d64629d19 (diff)
add implementation plan
Diffstat (limited to 'PLAN.md')
-rw-r--r--PLAN.md99
1 files changed, 99 insertions, 0 deletions
diff --git a/PLAN.md b/PLAN.md
new file mode 100644
index 0000000..ab277d9
--- /dev/null
+++ b/PLAN.md
@@ -0,0 +1,99 @@
1# Axon — Implementation Plan
2
3## Dependency Philosophy
4
5Minimize external dependencies at every layer. The protocol is designed so that the Go implementation requires nothing beyond the standard library and `golang.org/x/crypto`. The JS implementation requires only `@noble/curves` and `@msgpack/msgpack` — both small, audited, zero-dependency libraries. No frameworks, no ORMs, no generated code.
6
7---
8
9## Phase 1: Core Package
10
11**Everything depends on this. Do not move to Phase 2 until the signing spec is fully verified.**
12
13- `Event` struct, `Tag`, kind constants matching the registry in PROTOCOL.md
14- Canonical signing payload construction — byte-exact per the spec
15- Tag sorting (`canonical_tags` hash)
16- Ed25519 sign and verify (`crypto/ed25519`)
17- X25519 key conversion from Ed25519 keypair (`golang.org/x/crypto/curve25519`)
18- ChaCha20-Poly1305 encrypt/decrypt for DMs (`golang.org/x/crypto/chacha20poly1305`)
19- MessagePack encode/decode for events
20
21**Test vectors — write these before any implementation:**
22
23Publish a set of known-input → known-output pairs for:
24- `canonical_tags` hash given a specific tag list
25- `canonical_payload` bytes given a specific event
26- Event `id` (SHA256 of payload)
27- Signature verification
28
29These vectors must be committed to the repo and validated by the JS client in Phase 4. They are the ground truth for cross-implementation correctness. A disagreement on a test vector means the spec is ambiguous — fix the spec before fixing the code.
30
31**Go dependencies:** `golang.org/x/crypto` only.
32
33---
34
35## Phase 2: Relay
36
37- WebSocket server (stdlib `net/http` + `golang.org/x/net/websocket` or `nhooyr.io/websocket`)
38- Challenge/Auth handshake on connect
39- Allowlist: authorized pubkeys in a flat config file or SQLite table
40- Ingest pipeline:
41 1. Unmarshal msgpack envelope
42 2. Verify signature using Phase 1 core
43 3. Reject duplicates (id PRIMARY KEY)
44 4. Reject expired job requests (check `expires_at` tag)
45 5. Reject events exceeding 64KB content limit
46 6. Write to index + store
47 7. Fanout to matching subscribers
48- SQLite storage via `database/sql` + `mattn/go-sqlite3` or `modernc.org/sqlite` (pure Go, no CGo)
49- Subscription management: filter matching, per-connection subscription map
50- Ephemeral events (kind 3000–3999): fanout only, skip storage
51- Error responses with HTTP-borrowed codes
52- WebSocket keepalive: ping every 30s, close after two missed
53
54**Go dependencies:** sqlite driver, websocket library. Both should be pure Go where possible.
55
56---
57
58## Phase 3: Go Client
59
60- Connect to relay + complete auth handshake
61- Publish events
62- Subscribe with filter, receive event stream
63- Unsubscribe
64- Reconnect with backoff
65
66The Go client is the primary tool for integration testing the relay. All relay behavior should be exercised via the client before moving to Phase 4.
67
68**Go dependencies:** none beyond what Phase 1 and Phase 2 already use.
69
70---
71
72## Phase 4: JS Client
73
74- Connect + auth (Ed25519 sign the challenge)
75- Publish events (msgpack encode, Ed25519 sign)
76- Subscribe / unsubscribe
77- DM encrypt/decrypt (X25519 ECDH + ChaCha20-Poly1305)
78- Validate Phase 1 test vectors — JS and Go must agree on every vector before this phase is considered complete
79
80**JS dependencies:** `@noble/curves` (Ed25519, X25519), `@msgpack/msgpack`. No others.
81
82---
83
84## Phase 5: Integration
85
86- End-to-end: publish from JS client, receive in Go client (and vice versa)
87- Cross-language signature verification: Go signs, JS verifies; JS signs, Go verifies
88- DM round-trip: encrypt in JS, decrypt in Go
89- Job protocol flow: request → feedback → result across two separate processes
90
91At the end of Phase 5 you have a working protocol implementation ready to back an agent system.
92
93---
94
95## What Comes After
96
97- Agent discovery via `KindProfile` (kind 0) — capability advertisement
98- Relay clustering / replication (out of scope for v1)
99- Retention and event expiry policies