this repo has no description
1# labelz
2
3a live AT Protocol labeler, built on [zat](https://tangled.org/zat.dev/zat).
4
5this exists to pressure-test zat as an SDK — jetstream consumption, CBOR encoding,
6secp256k1 signing, and XRPC serving all running against real network traffic.
7
8## what it does
9
10connects to the bluesky jetstream firehose, watches for posts matching keyword rules,
11signs labels with secp256k1, stores them in SQLite, and serves them over the standard
12AT Protocol labeler endpoints:
13
14- `com.atproto.label.subscribeLabels` — WebSocket event stream
15- `com.atproto.label.queryLabels` — HTTP query
16
17the labeler is registered as a proper AT Protocol identity with a DID, PDS account,
18and labeler declaration record.
19
20**live instance:** [labelz.fly.dev](https://labelz.fly.dev/health) · [DID document](https://plc.directory/did:plc:ugigqebt4sm3n4xpmqvslcyo) · [PDS](https://labelz-pds.nate-8fe.workers.dev/status)
21
22## running
23
24```
25LABELZ_DID=did:plc:... LABELZ_SECRET_KEY=<64-hex-chars> zig build run
26```
27
28<details>
29<summary>environment variables</summary>
30
31| variable | required | description |
32|----------|----------|-------------|
33| `LABELZ_DID` | yes | labeler DID (src field on emitted labels) |
34| `LABELZ_SECRET_KEY` | yes | secp256k1 secret key, 64 hex chars (32 bytes) |
35| `LABELZ_PORT` | no | server port (default: 4100) |
36| `LABELZ_DB` | no | SQLite database path (default: `/data/labelz.db`) |
37
38</details>
39
40<details>
41<summary>architecture</summary>
42
43```
44jetstream ──→ keyword match ──→ sign (secp256k1) ──→ store (SQLite)
45 │
46 ┌──────────┴──────────┐
47 │ │
48 subscribeLabels (WS) queryLabels (HTTP)
49```
50
51source files:
52
53- `main.zig` — config, jetstream consumer, keyword matching
54- `label.zig` — label type, CBOR encoding, signing
55- `store.zig` — SQLite storage
56- `server.zig` — XRPC server (WebSocket + HTTP)
57- `identity.zig` — PLC identity operations (unused at runtime, used for setup)
58
59</details>
60
61<details>
62<summary>identity setup</summary>
63
64the labeler needs a full AT Protocol identity: a DID registered at plc.directory,
65a PDS hosting the account, and a labeler declaration record. this was done once
66using [pds.js](https://tangled.org/chadtmiller.com/pds.js) on cloudflare workers
67and [goat](https://github.com/bluesky-social/indigo/tree/main/cmd/goat) for PLC operations.
68
69the DID document includes both a repo signing key (P-256, used by the PDS) and a
70label signing key (secp256k1, used by labelz), plus service endpoints for both
71the PDS and the labeler.
72
73see the `justfile` for the operational recipes (`keygen`, `update-did`, `declare`).
74
75</details>
76
77<details>
78<summary>deployment</summary>
79
80runs on fly.io with a persistent SQLite volume. the Dockerfile does a multi-stage
81build: debian bookworm with zig 0.15.2 for compilation, slim runtime image with
82just libsqlite3.
83
84```
85fly deploy
86```
87
88</details>
89
90## dependencies
91
92- [zat](https://tangled.org/zat.dev/zat) — AT Protocol primitives (jetstream, CBOR, crypto, XRPC)
93- [websocket.zig](https://github.com/zzstoatzz/websocket.zig) — WebSocket client/server
94- system libsqlite3