chadtmiller.com/knotless
git that lives in your Atmosphere account
Records in a space are read by their URI in full, as proposal 0016 names them
MergedThis adds aturi::{AtUri, SpaceRef} and moves the URI readers onto them: forge::parse_uri, RepoRef::did, closing keywords, and the appview's found, repo_of and root. A record in a space can now be named in full or in the public form. The label and check keys hash the public form, so existing keys are unchanged and a full URI maps to the same records.
I read the parser, resolved, same and short, and each call site. I found nothing that must change:
- Public URIs behave as before, including the DID check in
parse_uriand handle authorities inAtUri. - The full form needs DID authority and author and a dotted space type.
keys::label_rkeyandchecks_ofleave non-URI names such asrefs/heads/mainas they were.closingmatches the full and public forms throughsame. Its test checks that an issue with the same author and rkey in another space does not match.- The tests cover the new branches.
The change file and the access.md update that AGENTS.md asks for are both there. I did not check CI results.
One thing to know: a public URI whose collection segment is literally space and has three segments, like at://did/space/x, is now refused. That is fine for NSID collections, but it is a small change from the old lenient parse.
Carried forward: the change this pull makes at c8240a2a3e6a017afe4f6c13c547e133374e671c is the one reviewed at 9e005c78b51370429746d0945736a88f06b2d700, so that review stands. What is new comes from its base.
My earlier review asked for nothing, so there is nothing to re-check on that front. Since 9e005c7 the branch has moved to fe03d28. The diff between the two shows only unrelated changes from main (the account-deletion settling, bare checks --ref, the deploy/Terraform removal), which looks like a rebase onto newer main. I found no change to aturi.rs or the URI readers, so my earlier conclusions still hold. The check, docs, web, shots and lexicons workflows pass or were skipped. test and e2e were still running when I looked, so I haven't seen those results.
8 passed, 2 skipped
What changes
One URI type for both forms.
crates/knotless/src/aturi.rshasAtUri, a record's URI, public (at://<author>/<collection>/<rkey>) or in a space (at://<space did>/space/<type>/<skey>/<author>/<collection>/<rkey>), andSpaceRef, a space alone (at://<space did>/space/<type>/<skey>), as atproto's permissioned data proposal (0016) addresses them. The names follow@atproto/syntaxin the spaces alpha (AtUri,SpaceRef,spaceDid,spaceType,skey,SPACE_MARKER), and so does the grammar: the authority and author of a URI in a space are DIDs, the space type has dots.AtUri::resolvedgives a record named in the public form the space it was found in;aturi::samesays whether two URIs name one record, a public-form one matching its full form in any space;AtUri::shortis the public form.Every reader takes either form.
forge::parse_uri(behindshow,comment,merge,checks --pulland the rest),RepoRef::did, closing keywords (Fixes <uri>names an issue in full or in the public form, and matches the issue either way), and the appview's methods that take a repository's record (found,steps::repo_of,preview::root).space::uriandorg::space_uriare made throughSpaceRef.Keys stay put. A label's rkey and a pull's check rkeys hash the pull's URI; they now hash its public form, so a URI in full keys the same records.
Nothing names a record in the full form yet: that is the next pull in the stack.
Why
A private repository's pulls, issues, comments and checks are named today as if public,
at://<author>/<collection>/<rkey>, which loses the space they are in, can name two records in two spaces alike, and 404s at the author's PDS. Proposal 0016 names them with every segment through the rkey. Reading both forms first, released on its own, lets a CLI in the field read what a later knotless writes.How it was checked
Unit tests:
aturi(both forms round trip, what neither form is is refused, resolving and matching),closing::an_issue_in_a_space_is_named_either_way,keys::key_shapes,records::repo_refs,forge::uris. The rest is left to CI.Shortcomings
The public form is lenient as
parse_uriwas: it does not check that the collection is an NSID or the rkey a record key, since the tests' and old records' URIs are looser than the proposal's grammar.Review
The design, in
aturi.rs; the stack's next pull mints the full form, and the one after moves what was stored in the public form.🤖 Generated with Claude Code