···11+# zat publishes its own docs to ATProto
22+33+zat uses itself to publish these docs as `site.standard.document` records. here's how.
44+55+## the idea
66+77+i'm working on [search for leaflet](https://leaflet-search.pages.dev/) and more generally, search for [standard.site](https://standard.site/) records. many are [currently thinking about how to facilitate better idea sharing on atproto right now](https://bsky.app/profile/eugenevinitsky.bsky.social/post/3mbpqpylv3s2e).
88+99+this is me doing a rep of shipping a "standard.site", so i know what i'll be searching through, and to better understand why blogging platforms choose their schema extensions etc for i start indexing/searching their record types.
1010+1111+## what we built
1212+1313+a zig script ([`scripts/publish-docs.zig`](https://tangled.sh/zat.dev/zat/tree/main/scripts/publish-docs.zig)) that:
1414+1515+1. authenticates with the PDS via `com.atproto.server.createSession`
1616+2. creates a `site.standard.publication` record
1717+3. publishes each doc as a `site.standard.document` pointing to that publication
1818+4. uses deterministic TIDs so records get the same rkey every time (idempotent updates)
1919+2020+## the mechanics
2121+2222+### TIDs
2323+2424+timestamp identifiers. base32-sortable. we use a fixed base timestamp with incrementing clock_id so each doc gets a stable rkey:
2525+2626+```zig
2727+const pub_tid = zat.Tid.fromTimestamp(1704067200000000, 0); // publication
2828+const doc_tid = zat.Tid.fromTimestamp(1704067200000000, i + 1); // docs get 1, 2, 3...
2929+```
3030+3131+### CI
3232+3333+[`.tangled/workflows/publish-docs.yml`](https://tangled.sh/zat.dev/zat/tree/main/.tangled/workflows/publish-docs.yml) triggers on `v*` tags. tag a release, docs publish automatically.
3434+3535+`putRecord` with the same rkey overwrites, so the CI job overwrites `standard.site` records when you cut a tag.