forward-compatible AT Protocol lexicon checks and publication for CI

README.md

publex #

Forward-compatible AT Protocol lexicon checks and publication for CI, built with zat.

publex recursively discovers JSON files under ./lexicons, checks the stable Lexicon envelope without rejecting newly introduced schema types, and publishes changed schemas as com.atproto.lexicon.schema records. It exists because current schema tooling can lag experimental protocol additions such as Permissioned Data space declarations.

commands #

# validate every JSON file under ./lexicons
publex check

# inspect the authenticated repo without writing
ATPROTO_HANDLE=example.com \
ATPROTO_PASSWORD=xxxx-xxxx-xxxx-xxxx \
publex publish --dry-run

# publish only new or changed records
ATPROTO_HANDLE=example.com \
ATPROTO_PASSWORD=xxxx-xxxx-xxxx-xxxx \
publex publish

The publisher:

  • resolves the account's current PDS through its DID document;
  • authenticates with a short-lived app-password session;
  • verifies every exact NSID authority through its _lexicon DNS TXT record;
  • compares the live record structurally, ignoring JSON object key order; and
  • calls com.atproto.repo.putRecord only for new or changed schemas.

--skip-dns-check exists for recovery and diagnostics, but should not be used in routine CI. It removes the guard that prevents publishing a schema under a namespace the authenticated DID does not control.

staging namespaces #

Use --namespace FROM=TO to rewrite namespace strings in memory before they are checked or published. Source files are never changed.

publex check --namespace fm.plyr=fm.plyr.stg
publex publish --namespace fm.plyr=fm.plyr.stg

build #

Zig 0.16 is required.

zig build test --summary all
zig build -Doptimize=ReleaseSafe
./zig-out/bin/publex --help

The dependency is pinned to a released zat source archive and verified by Zig's package hash.

Tangled CI #

Keep checks and publication separate so pull request pipelines never receive publishing credentials. Ready-to-copy workflows live in examples/tangled.

The publishing workflow expects repository secrets named ATPROTO_HANDLE and ATPROTO_PASSWORD. Tangled injects repository secrets as environment variables; do not put them in the workflow's public environment map.

Tangled currently has no workflow path filters, so the example uses git diff-tree to exit successfully when neither lexicons/ nor the workflow changed. Publication is idempotent even when run manually or unnecessarily.

validation boundary #

The checker intentionally validates the durable Lexicon file envelope:

  • root object;
  • lexicon: 1;
  • syntactically valid id NSID;
  • non-empty defs object;
  • unique IDs across the directory; and
  • a non-empty string type for every named definition.

It does not maintain a closed enum of schema or permission types. That is the forward-compatibility property: new protocol declarations can be published before every downstream linter has been updated. More opinionated linting and schema-evolution analysis can run alongside it when those tools understand the schemas in use.