Vendored AT Protocol interop test vectors #
Known-answer vectors used as an external oracle for the encoding layers of this workspace.
| Upstream | https://github.com/bluesky-social/atproto-interop-tests |
| Pinned revision | 056e5741bb330757205d6b16db5266fffcae937b (2026-07-01) |
| License | Creative Commons Zero 1.0 Universal — see LICENSE-CC0 |
CC-0 permits direct copying into other projects without restriction or attribution. The vectors are
vendored rather than added as a submodule so that the harnesses below need nothing beyond a fresh
clone, and so the revision under test is visible in the diff when it is bumped. That is true of
these vectors only: the rest of cargo test --workspace also needs the DASL conformance fixtures
in crates/atproto-dasl/tests/dasl-testing, which are a submodule, and without
git submodule update --init --recursive 13 atproto-dasl tests fail.
mst/gen_keys.py is not vendored; it is a generator for mst/example_keys.txt, which is.
Why these exist #
Every encoding test in this workspace prior to these vectors was a round trip — encode, decode, compare. A round trip passes against a wrong encoding, because it only proves the code agrees with itself. These files are the only thing in the repository that proves the code agrees with the protocol.
Which harnesses consume which files #
| Vectors | Harness |
|---|---|
mst/key_heights.json, mst/common_prefix.json, mst/example_keys.txt, firehose/commit-proof-fixtures.json |
crates/atproto-repo/tests/interop_mst.rs |
data-model/data-model-fixtures.json, data-model/data-model-{valid,invalid}.json (all but six cases of the invalid file, which it lists in NOT_AN_ENCODING_CONCERN) |
crates/atproto-dasl/tests/interop_data_model.rs |
data-model/data-model-invalid.json (those six: record structure, $type and blob shape) |
crates/atproto-lexicon/tests/interop_data_model_structure.rs |
syntax/ (all 24 files) |
crates/atproto-lexicon/tests/interop_syntax.rs |
syntax/datetime_*.txt (3 of those files, again) |
crates/atproto-record/tests/interop_datetime.rs |
crypto/ (all 3 files) |
crates/atproto-identity/tests/interop_crypto.rs |
lexicon/ (all 9 files) |
crates/atproto-lexicon/tests/interop_lexicon.rs |
Every vendored file is consumed, by seven harnesses.
The corpus is at the workspace root, outside every crate's package, so a harness is
workspace-only. Six are left out of their crate's package by its exclude, and atproto-dasl's
interop_data_model skips itself in a packaged crate, which it recognizes by the
Cargo.toml.orig that cargo package writes. A new harness needs one or the other, because
crates/readme-doctests/tests/package_contents.rs refuses a published test that reads outside its
package.
The table above is checked by an external conformance harness, which is how the three claims this
section previously got wrong were found: data-model-{valid,invalid}.json were described as
unconsumed after the harness that reads them landed, and mst/example_keys.txt appeared in neither
list at all. Keep them accurate in the same change as the harness — a map that is right about most
of the corpus is worse than no map, because a reader cannot tell which parts were maintained.
Known failures #
Each of the seven harnesses carries a KNOWN_FAILURES table naming each vector this workspace does
not yet satisfy, together with the gap-analysis finding that explains why. A listed vector is
required to fail: if it starts passing, the harness fails and instructs you to delete the entry.
That way the tables cannot silently rot, and the moment an encoding fix lands the gate tells you
which finding it closed.
Every harness enforces it, too, which this said before it was true: interop_crypto.rs declared a
table nothing read, and interop_data_model_structure.rs had none. An empty table is not an
exemption — it is the statement that nothing is pinned, and it only means that if adding the first
entry would do something. All seven now check both directions, so a rule stated here holds
everywhere it is stated about. So does an eighth table outside this map,
crates/atproto-pds/tests/integration/interop_firehose.rs, which follows the same rule for the
firehose's frames but reads nothing in this directory.
Do not add an entry to relax a genuine regression. An entry is a statement that a known, filed defect is still open.
Bumping the pin #
git clone --depth 1 https://github.com/bluesky-social/atproto-interop-tests /tmp/interop
rsync -a --delete --exclude .git --exclude .gitignore --exclude mst/gen_keys.py \
/tmp/interop/ tests/interop/
Then restore this README, update the pinned revision above, and re-run
cargo test --workspace. New vectors that fail are new findings, not licence to extend
KNOWN_FAILURES.