- Zig 100%
Publisher encodes DMP messages as CBOR maps:
{ "topic": <text>, "data": <text>, "ts": <uint>, "did": <bytes32> }
Signs CBOR bytes with Ed25519, appends 64-byte signature.
Sends as L0 frame payload over TCP.
Server receives, verifies Ed25519 signature against publisher's
public key, decodes CBOR structure, forwards to subscriber.
Subscriber verifies signature + decodes independently.
3 messages through 2 TCP hops, all signatures verified at both
server and subscriber. 5/5 stress clean, zero leaks.
Developed with Voxis Forge assistance
|
||
|---|---|---|
| bridge | ||
| docs/superpowers | ||
| lib | ||
| src | ||
| test | ||
| .gitignore | ||
| GAPS.md | ||
| LESSONS.md | ||
| README.md | ||
| SOVEREIGN.md | ||
LTP-Jan: Janus :service driving L0 Transport
Sprint 1: L0 Bridge Boundary (single-threaded) Sprint 2: Concurrent L0 Transport (nursery/spawn/channels) Sprint 3: TCP Network Transport (real sockets, multi-bridge) Sprint 4: DMP Gossip Over TCP (networked pub/sub) Sprint 5: Multi-Hop Gossip Relay (store-and-forward, fan-out) Sprint 6: Stdlib Capsules (typed wrappers, gap discovery)
Thesis
L0 wire encoding (packed structs, raw buffers, CRC32-C, unsigned bitops) belongs in
Janus :sovereign profile. Until :sovereign exists, Zig IS :sovereign.
This project proves Janus :service can cleanly orchestrate the existing Zig L0
transport stack through C-exported bridges — the same pattern used by DMP, crypto,
HTTP, and all other stdlib bridges. Sprint 4 achieves the first networked pub/sub
messaging: DMP messages serialized, wrapped in L0 frames, sent over TCP, decoded,
and delivered to subscribers — the full gossip pipeline. Sprint 5 proves multi-hop
store-and-forward and one-to-many fan-out — the foundations of mesh gossip.
Sprint 6 extracts four stdlib capsules (lib/*.jan) – typed wrapper functions over
the Zig bridges – and stress-tests the :service type system. See GAPS.md for the
compiler gap registry produced by this work.
Capability Envelope
Janus :service capsules validate single-file programs with scalar and pointer types
across the Zig bridge. The following patterns compile and run correctly:
use zigbridge imports with up to 76 simultaneous C-exported functions- Wrapper functions around bridge externs (i64 handles in/out)
errortype definitions withfailand!Treturnsstructdefinition, initialization as local, and field accessconstdeclarations at module scopenursery/spawn/channelorchestrating concurrent bridge calls
The following are tracked compiler gaps (see GAPS.md for reproducers):
- Struct as function parameter or return type (G-02, G-08b)
- UFCS method calls on struct values (G-02b)
?error propagation in non-!Tfunctions (G-03b)- Cross-file
.janimports (G-01 – unimplemented feature, not a bug)
These gaps block the typed wrapper pattern (struct TcpConn with methods). The current capsules use i64 handles with named wrapper functions as the workaround. When the compiler gaps are fixed, the capsules upgrade to typed structs with UFCS in place.
Architecture
Sprint 4: Point-to-Point Pipeline
TCP (port 19004/19005)
Publisher Task =========================> Server Task ========> Subscriber Task
|
1. dmpnet_pack(topic, data) 4. net_read_framed() |
2. l0_frame_new(service=0x0A80) 5. l0_frame_decode() |
set payload = packed wire bytes 6. l0_frame_verify() CRC32 |
3. l0_frame_encode() 7. dmpnet_unpack(payload) |
4. net_write_framed(encoded) 8. dmp_publish(topic, data)|
-> local broker |
Bridges: 4 simultaneous 9. dmp_recv(sub_handle) |
l0_bridge (33 funcs) verify topic + data |
net_bridge (12 funcs) |
dmp_core (19 funcs) |
dmp_net (12 funcs) |
Total: 76 C-exported functions
Sprint 5: Multi-Hop Chain Relay (2-hop store-and-forward)
Publisher ──TCP:19006──> Relay ──TCP:19007──> Subscriber
(task 1) (task 2) (task 3)
dmpnet_pack net_read_framed net_read_framed
l0_encode l0_decode + CRC ✓ l0_decode + CRC ✓
net_write_framed dmpnet_unpack dmpnet_unpack
dmpnet_pack ← repack dmp_publish (local)
l0_encode ← re-enc dmp_recv → verify
net_write_framed
Sprint 5: Fan-Out Hub (one-to-many distribution)
┌──TCP:19009──> Subscriber 1
Publisher ──TCP:19008──> Hub
└──TCP:19009──> Subscriber 2
(task 1) (task 2) (tasks 3, 4)
dmpnet_pack net_read_framed net_read_framed
l0_encode l0_decode + CRC ✓ l0_decode + CRC ✓
net_write_framed forward raw bytes dmpnet_unpack
to BOTH subscribers dmp_publish → verify
Files
| File | Purpose |
|---|---|
bridge/l0_bridge.zig |
C-exported L0 frame + micro-LCC wrapper (33 funcs) |
bridge/net_bridge.zig |
C-exported TCP pool + length-prefixed framing (12 funcs) |
bridge/dmp_core.zig |
C-exported DMP gossip broker (19 funcs) |
bridge/dmp_net_bridge.zig |
C-exported DMP message serialization (12 funcs) |
src/l0_demo.jan |
Sprint 1: LWF frame round-trip |
src/main.jan |
Sprint 1: Full DMP->L0 demo |
src/nursery_test.jan |
Sprint 2: Nursery/spawn smoke test |
src/channel_test.jan |
Sprint 2: Channel + nursery CSP |
src/concurrent_demo.jan |
Sprint 2: 3 concurrent L0 tasks |
src/net_echo_test.jan |
Sprint 3: TCP echo smoke test |
src/net_l0_demo.jan |
Sprint 3: L0 frames over real TCP |
src/net_concurrent_test.jan |
Sprint 3: 3 concurrent TCP clients |
src/dmp_smoke.jan |
Sprint 4: 4-bridge loading smoke test |
src/dmp_tcp_relay.jan |
Sprint 4: one-way DMP relay over TCP |
src/dmp_tcp_chat.jan |
Sprint 4: bidirectional DMP chat over TCP |
src/dmp_chain_relay.jan |
Sprint 5: 2-hop chain relay (store-and-forward) |
src/dmp_fanout_hub.jan |
Sprint 5: fan-out hub (one-to-many distribution) |
lib/tcp.jan |
Sprint 6: std.net.tcp capsule – TCP wrappers (12 funcs) |
lib/l0.jan |
Sprint 6: std.ltp.l0 capsule – L0 frame wrappers (33 funcs) |
lib/dmp.jan |
Sprint 6: std.dmp capsule – gossip broker wrappers (19 funcs) |
lib/wire.jan |
Sprint 6: std.ltp.wire capsule – pipeline helpers (76 funcs, all bridges) |
GAPS.md |
:service profile gap tracker + compiler target list |
SOVEREIGN.md |
:sovereign profile roadmap |
Build
# Set runtime dir (required when building outside Janus repo)
export JANUS_RUNTIME_DIR=/path/to/janus/runtime
# Sprint 1: frame round-trip
janus build src/l0_demo.jan l0_demo && ./l0_demo
# Sprint 2: concurrent L0 transport
janus build src/concurrent_demo.jan concurrent && ./concurrent
# Sprint 3: TCP echo
janus build src/net_echo_test.jan net_echo && ./net_echo
# Sprint 3: L0 frames over TCP
janus build src/net_l0_demo.jan net_l0 && ./net_l0
# Sprint 3: multi-client concurrent TCP
janus build src/net_concurrent_test.jan net_conc && ./net_conc
# Sprint 4: 4-bridge smoke test
janus build src/dmp_smoke.jan dmp_smoke && ./dmp_smoke
# Sprint 4: DMP relay over TCP (5 sensor/* messages)
janus build src/dmp_tcp_relay.jan dmp_relay && ./dmp_relay
# Sprint 4: bidirectional DMP chat (alice/* <-> bob/*)
janus build src/dmp_tcp_chat.jan dmp_chat && ./dmp_chat
# Sprint 5: 2-hop chain relay (publisher -> relay -> subscriber)
janus build src/dmp_chain_relay.jan dmp_chain && ./dmp_chain
# Sprint 5: fan-out hub (publisher -> hub -> [sub1, sub2])
janus build src/dmp_fanout_hub.jan dmp_fanout && ./dmp_fanout
# Sprint 6: stdlib capsules (requires --profile=service)
janus --profile=service build lib/tcp.jan test_tcp && ./test_tcp
janus --profile=service build lib/l0.jan test_l0 && ./test_l0
janus --profile=service build lib/dmp.jan test_dmp && ./test_dmp
janus --profile=service build lib/wire.jan test_wire && ./test_wire
Ports
| Port | Demo | Sprint |
|---|---|---|
| 19001 | net_echo_test, net_bridge tests | 3 |
| 19002 | net_l0_demo | 3 |
| 19003 | net_concurrent_test | 3 |
| 19004 | dmp_tcp_relay | 4 |
| 19005 | dmp_tcp_chat | 4 |
| 19006 | dmp_chain_relay (publisher → relay) | 5 |
| 19007 | dmp_chain_relay (relay → subscriber) | 5 |
| 19008 | dmp_fanout_hub (publisher → hub) | 5 |
| 19009 | dmp_fanout_hub (hub → subscribers) | 5 |
Related
- libertaria-stack/core/l0-transport/ — Zig L0 reference
- janus/std/bridge/dmp_core.zig — Bridge pattern reference
- RFC-0000: LWF — Wire frame spec
- RFC-0010: micro-LCC — Control channel spec