pushes on tangled
sites.wisp.place/zzstoatzz.io/punch
fun
tangled
1# punch
2
3who's pushing on [tangled.org](https://tangled.org) — push-count leaderboard across every knot. one row per `committerDid`, ranked by `sh.tangled.git.refUpdate` events.
4
5**[sites.wisp.place/zzstoatzz.io/punch](https://sites.wisp.place/zzstoatzz.io/punch/)**
6
7## stack
8
9```
10relay.waow.tech (listReposByCollection)
11 ↓
12 knot /events (WS, per-host)
13 ↓
14 CF Worker (*/10 min cron) → D1 (cursors, pushes) + KV (handles)
15 ↓
16 place.wisp.fs record on pds.zzstoatzz.io → sites.wisp.place
17```
18
19- **indexer**: [Cloudflare Workers](https://workers.cloudflare.com) + D1 + KV
20- **site**: [wisp.place](https://wisp.place) (atproto static hosting)
21- **handles**: [typeahead.waow.tech](https://typeahead.waow.tech) + bsky AppView + plc.directory
22
23## dev
24
25```sh
26bun install && bun run dev # static site at :4747
27
28cd worker && bun install
29wrangler dev # worker; GET /__run fires one cycle
30wrangler deploy
31wrangler tail
32```
33
34secrets: `PUNCH_HANDLE`, `PUNCH_APP_PASSWORD` (atproto app password for the wisp-publishing account).
35
36## publish
37
38the worker only rewrites `leaderboard.json` in the wisp manifest each tick. html/css/js changes ship with a manual wispctl:
39
40```sh
41wispctl deploy zzstoatzz.io --path public --site punch --password "$PUNCH_APP_PASSWORD" --yes
42```
43
44<details>
45<summary>why pushes, not commits</summary>
46
47tangled's own PUNCHCARD filters `meta.commitCount.byEmail[]` by the committer's private verified-emails table (`core/appview/state/knotstream.go:219` in tangled). without that table we'd massively overcount merges/rebases. one refUpdate = one push is the cleanest metric we can compute from public firehose data — and it surfaces accounts tangled's counter hides (e.g. prolific pushers who haven't run email verification).
48
49</details>