my account on the atmosphere started this series with two posts and no followers. it's a good specimen. nothing about it is big enough to hide how it works.
the identity is did:web:devarno.com. the handle is @null0.blue. the data lives on pds.devarno.com, a server i run, which takes new accounts by invite only, and every account on it is one of mine. this series is five walks through that account, one a week. this first one draws the map by starting at a single record and following it outward until it reaches someone who has never heard of me.
$ downlink · the tapestry
panel 1 of 5. i keep a notebook at my own address. anyone can read it, and anyone can check it's mine.
devarno.com 1 · this part
2 · not yet woven
? ? ? 3 · not yet woven
4 · not yet woven
app.bsky sh.tangled 5 · not yet woven
start with one question to my own server
every request in this piece is live. the button on each one sends the same request from your browser and shows what the server says today next to what it said when i wrote this.
GET pds.
repo = did:web:devarno.com
- handle
- null0.blue
- handleIsCorrect
- true
- collections
- bsky.appapp.bsky.actor.profileapp.bsky.feed.postapp.bsky.graph.follow
- bsky.chatchat.bsky.actor.declaration
- tangled.sh (a different app)sh.tangled.actor.profile
published response · run it to compare with what the server says now
five collections. four of them start with bsky. the fifth belongs to tangled, a code forge with no connection to bluesky, and its profile record for me sits in the same repo as my posts.
the repo is mine. what goes into it is decided by whichever apps i let write there, and each one labels its records with a name it owns.
pick one record and follow it
the record i trust most is my profile. i wrote it with putRecord in june to prove the identity worked. its address:
at://did:web:devarno.com/app.bsky.actor.profile/self
read left to right, that address is a route. the did says whose repo. the collection says what kind of record. self is the key inside the collection. nothing in it names a server. to find the bytes, you resolve the did first.
the did document is a small json file on devarno.com. it says two things that matter here: my data is at https://pds.devarno.com, and commits to that data are signed by the key listed under #atproto. change either line and the account moves or re-keys. no directory has to agree.
i came to this from networking, and the shape is familiar. the handle is an advertised route. the did is the address that routes resolve to. software stores the did and looks the handle up when it needs a name to show, which is why i can change the handle without breaking anything that points at me.
the repo is a signed ledger, and it has a version
GET pds.
did = did:web:devarno.com
- cid
- bafyreiep3lpk46ujw5wymhkt5337un2rybh52ue25za7c2mhx6ll72n5fa
- rev
- 3mour3bhkkk2p
published response · run it to compare with what the server says now
every write to the repo produces a new commit, signed with the key from the did document. the rev moves forward with each one. anyone holding the commit and the did document can check the signature without asking my server whether it's telling the truth.
the repo is designed to be audited by people who don't trust the host. i build verifiable-state systems for a living, and i want to know whether this one holds the way mine have to. part 2 opens it up.
where the record goes when i'm not looking
my server doesn't wait to be asked. when the repo changes, it announces the change on an outbound stream, and anything that wants my data can subscribe. i don't run anything on the reading side. that belongs to other people.
so the map has a border, and it's easy to find. everything on my side of it i can change with a deploy. everything past it, i can only check.
a stranger reads it back
in june i ran one check to close out the setup. i asked the public bluesky appview, which i've never configured or contacted, who null0.blue is. it still answers the same way:
GET public.
handle = null0.blue
- did
- did:web:devarno.com
published response · run it to compare with what the server says now
and what it knows about the account:
GET public.
actor = did:web:devarno.com
- handle
- null0.blue
- postsCount
- 2
- followersCount
- 0
- createdAt
- 2026-06-18T21:29:55Z
published response · run it to compare with what the server says now
it learned all of that from the stream, then checked it against the file on my domain. my server never told it anything directly.
what's next
part 2 goes inside the repo: what a commit holds and what the rev counts. the test i care about is whether i can verify my own history from the raw bytes without trusting the server i run.
if you want the whole protocol laid out in one long read first, kuba suder's introduction to at protocol is the reference i'd hand anyone starting out.
every claim above was checked against live endpoints on 23 september 2026. you can rerun them:
photos: alexander gluschenko (cover) and liane metzler (card), via unsplash.
