When I published Tuesday's proposal, I thought I might be the only one who cared that much about designing cleaner URIs for records in AT spaces. Evidently not, because now everyone's bikeshedding a new proposal the team released on Wednesday.

I applaud the effort to both:

  • address the authority conundrum for existing at:// URIs, +

  • prevent similar technical debt for space URIs

So let's use something closer to 's newest syntax to update what I was saying on Tuesday.

What's an authority?

Recall the definition from RFC 3986:

Many URI schemes include a hierarchical element for a naming
authority so that governance of the name space defined by the
remainder of the URI is delegated to that authority (which may, in
turn, delegate it further).

In existing AT contexts, the authority for a URI encapsulates:

  • who owns that resource,

  • where it's canonically stored (their current PDS location), +

  • any other information needed to resolve that resource.

Can that stay the same for spaces, or must it change? Is the relevant authority for individual records still about ownership of the data (how it's stored + synced), or more about management of the space (how it's aggregated for others to view)?

How many authorities? One or zero?

I personally don't wanna give up yet on the "DIDs make great authorities" battle (aka keep the double slashes + the colons), which would require a small-but-mighty fix to the URI spec1, but ...

... if there's strong consensus that'd be tilting at windmills, then what might it look like to keep the colons + drop the slashes entirely?

Public records:

at:RECORD, where
RECORD = {authority}/{collection}/{rkey}
or colloquially {who}/{what}/{which}

A view which aggregates all public records for a given collection:

at:VIEW, where
VIEW = */{collection}/*

The definition of a space:

at:SPACE, where 
SPACE = {spaceDid}/{spaceType}/{skey}

The type = "space" record found at that URI is a space type declaration describing which kinds of collections can be accessed via this space:

{
  "lexicon": 1,
  "id": "com.atmoboards.forum",
  "defs": {
    "main": {
      "type": "space",
      "description": "A discussion forum",
      "key": "any",
      "name": "AtmoBoards Forum",
      "name:lang": { "es": "Foro AtmoBoards", "ja": "AtmoBoards 掲示板" },
      "collections": ["com.atmoboards.thread", "com.atmoboards.reply", "org.example.reaction"]
    }
  }
}

We've gotten rid of both slashes, so from the perspective of a generic URI parser, none of the above references have paths or authorities. But we know better.

Who's the authority for each of them?

{authority} for at:RECORD
either * or undefined for at:VIEW
{spaceDid} for at:SPACE

Nothing surprising or controversial so far, right?

Two authorities?

As I argued in more depth on Tuesday, for a record to be visible in a space requires the cooperation of two authorities, not one:

  • the record owner (author) +

  • the space host

The cleanest possible URI for that record should encapsulate both where it canonically lives (on the author's PDS), + how to access it (via credentials managed by the space host).

Records belong to users, + are included in spaces, so the URI layout should reflect that:

at:RECORD?space=SPACE, where
RECORD={owner}/{collection}/{rkey}, and
SPACE={spaceDid}{spaceType}/{skey}

A view aggregating all sync-able2 records from a collection within a given space:

at:VIEW, where 
VIEW = */{collection}/*?space=SPACE and 
collection ⊂ SPACE.spaceType.collections

Asking the same question as before, who's the authority for each reference? Again, just looking at the URI should make the answer obvious:

{owner} for at:RECORD?space=SPACE
either * or {spaceDID} for at:VIEW

Any surprises there, or does this feel pretty straightforward?

Putting it all together

The beauty of this URI syntax is how clearly + directly it expresses how the AT protocol works. Each of the following Refs points to a single unique AT record:

at:SPACE
at:RECORD
at:RECORD?space=SPACE

What sync protocol do I use to access each of them?

public for at:SPACE
public for at:RECORD
permissioned for at:RECORD?space=SPACE

Who owns each one? Whose PDS do I contact to do so?

{spaceDID} for at:SPACE
{owner} for at:RECORD
{owner} for at:RECORD?space=SPACE, using credentials via {spaceDID}

Does that feel any less surprising now?

Implementation note

To be clear. Expressing the URI syntax this way is NOT intended to change anything else about how the alpha implementations of spaces work. Not over the wire, + not inside PDSes.

The following are still three distinct URIs, representing three distinct resources.

at:RECORD
at:RECORD?space=SPACE1
at:RECORD?space=SPACE2

If they exist, they'd be backed by three separate records, stored in parallel repos on the same PDS:

public repo for at:RECORD
SPACE1 repo for at:RECORD?space=SPACE1
SPACE2 repo for at:RECORD?space=SPACE2

The goal here is to improve the ergonomic experience of AT URIs by simplifying the layout, nothing more.

Record versions vs. variants

We're already familiar with the Ref vs. StrongRef distinction.

Resolving the same Ref to an AT URI at two different points in time may give you different versions of the "same" record. If you want to confirm that you continue to access the same version of that record, then you need to record its cid at the time alongside the URI, store that as a StrongRef instead + compare that to the cid of whatever's retrieved later.

By choosing which link to store in the lexicons they use, application designers communicate which behavior they feel is most relevant for what their users are doing with the data. What's written into the records expresses what kind of link to that resource they intend.

Similarly, what does it mean if you do happen to find variants of the "same" record stored in different repos?

at:RECORD
at:RECORD?space=SPACE1
at:RECORD?space=SPACE2, where
RECORD={owner}/{collection}/{rkey}, and
SPACE1={spaceDid}{spaceType}/{skey}, but
SPACE1 != SPACE2

This may or may not have application-specific significance. For example, anyone who has access to the SPACE1 variant of at:RECORD might choose to do something interesting with a public variant of at:RECORD if/when it exists (such as favoring one over the other, or comparing them, or whatever). Or not. They're still separate records with separate URIs.

My hunch is that this aspect of the URI layout might enable a bunch of other interesting use cases down the road, but YMMV. After all, a given {owner} should only find records for the "same" {collection}/{rkey} written into multiple repos on their PDS if some service they use deliberately did so on their behalf.

Comparing to the alternatives

So how does my proposal ...

at:SPACE
at:RECORD
at:RECORD?space=SPACE

... compare to what everyone's been bikeshedding?

at:global/SPACE
at:global/RECORD
at:space/SPACE/RECORD

What sync protocol do I use to access each of these Refs?

public for at:global/SPACE
public for at:global/RECORD
permissioned for at:space/SPACE/RECORD

Who owns each one? Whose PDS do I contact to do so?

{spaceDID} for at:global/SPACE
{owner} for at:global/RECORD
{owner} for at:space/SPACE/RECORD, using credentials via {spaceDID}

Honestly, the ergonomics of this layout feel decidedly worse to me -- even "funkier" than describes here:

Conceptually I think of URIs as being about namespaces, and the new top thing here (space vs global) is discriminating the type of namespace. Space records have a funky dual namespace: a global space reference, and then a space repo record reference.

What am I missing that makes bumping SPACE above RECORD in the namespace at all appealing, much less worth the ergonomic cost?

I'm stumped.