# lexicons ATProto lexicons for [lance.blue](https://lance.blue). Two namespaces. `blue.lance.*` is anything specific to this game — a camo, an after-action report, a pilot. `games.permadeath.*` is the identity and social layer that any game could use — a match, a challenge, an achievement, a rating. This repo holds the `blue.lance.*` schemas; the `games.permadeath.*` schemas are authored in the `permadeath.games/lexicons` repo, and the plans here cover both. [PLAN.md](PLAN.md) describes the nine stages and why they are in that order. [TODO/](TODO/) has one file per stage with the implementation tasks, plus files for work not folded into a stage. ## Layout One file per schema, in a directory per NSID segment under `lexicons/`: `lexicons/blue/lance/camo.json` is `blue.lance.camo`. That path is the one `goat` and `@atproto/lex` look in without being told, so a consumer of these schemas can point a tool at the repo and have it work. Files are written in goat's form: keys sorted, two-space indent, one trailing newline. `goat lex new` and `goat lex pull` both write that, and a record comes back from a PDS in it whatever order it went out in — so a schema here and a copy someone pulls from the network are the same bytes, and a diff between them means a real difference. `tools/lint_lexicons.py --format` rewrites a file into it; the hook fails if one is not. ## goat [goat](https://github.com/bluesky-social/goat) is the Bluesky CLI for lexicon work: it lints schemas, checks a change against the published version, checks the DNS, and publishes. It is what the atproto docs point at for publishing, and it is the only tool that does any of this for schemas that are not published yet. Install v0.2.3 from a release binary, after checking the checksum: curl -LO https://github.com/bluesky-social/goat/releases/download/v0.2.3/goat_Linux_x86_64.tar.gz curl -LO https://github.com/bluesky-social/goat/releases/download/v0.2.3/goat_0.2.3_checksums.txt sha256sum --ignore-missing -c goat_0.2.3_checksums.txt tar xzf goat_Linux_x86_64.tar.gz goat install -m 0755 goat ~/.local/bin/goat What it is used for here: goat lex lint # spec and style, run on commit goat lex check-dns # every NSID's authority resolves to a DID goat lex status # local files against what is published goat lex breaking # a change against the published version goat lex publish # write the schema records (see TODO/01-namespace.md) `goat lex pull blue.lance.camo` is one way another repo takes a copy of a schema from here. It resolves the NSID through DNS and reads the published record, so it only works once the schema is published. A consumer may pull with its own tool instead — headquarters vendors the file through `@atproto/lex` with the record's CID pinned, and goat must not rewrite those copies. ## Pre-commit hooks Hooks are managed by [prek](https://prek.j178.dev/) and configured in `prek.toml`. One-time setup: uv tool install prek prek install --prepare-hooks They then run on every commit; `prek run --all-files` runs them by hand. The schema hooks are `goat lex lint`, which is the Lexicon spec — it parses first, so there is no separate parse step — and `tools/lint_lexicons.py`, which covers what goat reports clean: - a file whose `id` disagrees with its path - a reference to a schema this repo does not define - empty `defs`, or a union with no `refs` - a file not in the form above