A community app lexicon

To Boris’s point: perhaps the verification part of the lexicon should be handled with a separate lexicon via strongRef or something? I’m not familiar enough with lexicons atm to suggest more specifically. But interested because I plan to list apps on AtLast. My goal would be introducing folks to the Atmosphere options and directing them to the apps aligned with the way they like to consume content. And for the apps purposes, I also need to know if they have a separate follow lexicon or default to an existing one.

From dame’s starting lexicon, my notes:

  • handles should be removed, those should just be resolved from DID
  • think category may need fleshing out a tiny bit from the options originally presented
  • how are project status changes handled?
  • profile uri….is a whole thing, removing that seems like the best approach rn
1 Like

Verification, since it’s two-way, similar to ATProto handles, needs to be done out-of-band anyway, so I think it shouldn’t affect the lexicon too much.

i.e. all we need to do for verification is document the standard of using self as the rkey if the record is considered the official app record by the hosting account.

The actual verification needs to be done by the directory / clients so it shouldn’t need to change the lexicon.

Agree with that. :+1:


I’m mostly interested in using this as a developer making an app and wanting to be able to create verified app entries that can be loaded across different directories.

While most people’s interests are in listing ATProto apps, I think it’s worth noting that not all apps are ATProto apps, so there should be a tag or something that we can use to filter by ATProto apps, but we shouldn’t require that an app be an ATProto app to end up on the registry.

I’d use this for listing any kind of app if there were a directory for that.

1 Like

Just another thought: several of us have Semble collections and bsky lists of apps / tools / orgs / etc. in the Atmosphere. May be useful to think about whether the categories we go with can cover these with sufficient but non-detailed nuance:

Reason I think of this is because I know blueskydirectory and others include tools that are just for analytics. I don’t (partly because there’s a lot and I don’t feel like vetting them). Those are something the feel like they should be a separate category.

And what’s App vs Client? That feels very ambiguous and nuanced just for atproto and worse if this lexicon is open to non-Atproto apps/tools/etc. I think “App vs client” can be handled sufficiently with the hasCustomLexicon field for the atproto-sphere (this is also roughly how I handle bsky client vs atproto app in my collections).

1 Like

If we want this , I’d add a “authentication with Atproto” option to pair with the hasCustomLexicons option in the lexicon

1 Like

Hmm, yeah. I wonder if both of those should be left out for now, just so we can put something minimal quickly into use and then think more carefully about the extra fields we need.

Like I can imagine a lot of flags like this that could be either boolean flags or almost like tags.

But then we still want to standardize on some of those “tags”.

This reminds me of some things in Roomy where we wanted to use lexicon NSIDs as “extensions”. This can be done implicitly in lexicons already, but there it’s a questionable practice to use NSIDs as field keys, since it’s rather verbose when it comes to code generation.

I don’t know how else to say this…

…SCOPE CREEP!!!

Yes, people will want to build app lexicons for all apps (or iPhone apps or whatever)

What is the minimal set of fields that can represent an atproto app or SDK/dev resource?

I would even be willing to drop the SDKs because maybe that’s just a Semble collection called SDKs :stuck_out_tongue:

2 Likes

Yeah, I think it’d be good to leave SDKs out for now. That seems different enough in purpose to leave out for simplicity.

1 Like

I’ll be building:

  1. An AppView that listens to the firehose for records of this lexicon type and perssits in a store
  2. A client app that allows one to create this record easily.
    2a. The client app will persist the record in the store at 1. on creation time.

This will give an open source way for anyone to make their directory powered by these lexicons as well as a simple tool for adding listings via custom lexicon record.

Once that’s real, both pieces will be open source and let the scope creep go wild via PR!

1 Like

That looks not too far off from a MASL manifest structure.

2 Likes

Yep!

MASL inherits from Web Manifests IIRC Web Application Manifest

I have a prototyp of a website showing different atproto apps laying around somewhere too, some notes:

  • agreed on keeping the scope as small as possible, but also like defining some clear optional fields, otherwise everyone just tends to use different ways of adding their own stuff
  • i like `self` for “official” app records, for verification i’m a fan of what standard.site is doing instead of the rel=me having a `.well-known/{collection}` endpoint, makes thing easier regarding CORS issues when verifying on the client (and yeah that’d be out of band anyway, so would be an optional thing, the handle of the publishing account like @roomy.space could also be used as a simple verification)
  • logo should be standardized to a specific aspect ratio (imo square), really annoying to display in clients otherwise
  • different lexicons for different things (apps, sdks, etc), keeps it smaller and can start with just one

thinking about how i’d change that `garden.atproto.directory.submission` collection for apps:

required:

  • url
  • name

optional:

  • logo (image, square)
  • brandAccount (did, if not given and rkey == “self” defaults to publishing account)
  • tagline (string short, fallback to bsky description of brandAccount?)
  • customLexicons (array of collection names, should probably allow wildcards? already feel people wont update their app record :smiley:, no need for hasCustomLexicons just check if this field exists and array not empty)
  • screenshots (array of images)
  • description (string longer)
  • landingPage (e.g. for roomy’s use case where landing page != project page)
  • platforms (array, web | ios | android | mac | windows | linux)
  • creators (array of dids)
  • source (link to source code)
  • createdAt/updatedAt (string, date)
  • storeUrls ({ios: “…”, android: “…”, mac: “…”, …})

that’s already too many optional fields probably…

we could also throw something really quick together for the atmosphereconf profile pages (add more icons in "active on" · Issue #39 · ATProtocol-Community/atmosphereconf · GitHub) and then see if that works

5 Likes

My initial implementation https://store.stucco.software/ now logs in via your ATProto, creates a record to your PDS, and checks for rel=me tags on your apps site before rendering your listing to the directory.

It uses the core of the garden lexicon, and it might not be creating the record 100 percent correctly. Next would be to make sure that the record building is flexible and functional and posting records correctly.

After that, I’ll create a mircoservice that listens to the firehose for these. Right now it’s all passive through this application itself.

3 Likes

Curious what @nikolas.ws and others think about the .well-known/collection pattern of verification compared to rel=me.

I like that it’s a lot easier to use than having to parse the HTML response of a normal web-page.

I think rel=me might have a slight advantage that it works automatically on 3rd party sites like GitHub, because your profile’s links have rel=me already added to it.


Edit: One thing that bugs me about verification methods in general is that there are multiple secure ways to do it, i.e. rel=me or .well-known or DNS TXT, but if we support multiples, than every app has to support multiples. So it’s nicer if there’s only one thing to support.

I think their both fine – I’m already parsing HTML so rel=me is cheap and easy to implement.

Right now I’m not using the (good, imo) self key idea since I don;t have an ATPRoto account for this app. Instead Im using my personal account to list the app, and that account is not the app. And may want to list several.

I think the .well-known and selfkeys are both good ideas, and will try and get to them too. But I like the use case of “me as a developer, creating multiple apps, listing them as myself” and want to support it.

Oh good point re many ways; I think .well-known probably better in that case, and doesnt close any doors.

1 Like

Oh, yeah, we definitely need to support that, too. The self key version should just be a way for the official record to take precedence over everything else and be extra verified, I think.

2 Likes

finally remember my morning idea: client metadata for app oauth already has some of this info (as long as there’s oauth) and the dev fills it out — client name, uri, logo. Can’t recall if description is one but not seeing it in a few I looked up for popular apps. I did mis-remember the lexicon part being in there (they kinda are cuz scopes but not quiet).

Anyway maybe app lexicon is just:

  1. app uri
  2. custom lexicons NSID(s)
  3. tagline OR description OR category (from fixed list)

you can use 1 to then get name from client metadata json. however, do we handle non-oauth cases? if so then needing name+logo feel is more necessary…but…maybe it’ll force people to do oauth? lol

just 2 means we don’t list custom lexicons, which def won’t be kept up-to-date. but users of the app lexicon can query for them from this field and it addresses the “has custom lexicon” part. related to 1: do we add non-custom NSID field to handle non-custom lexicons cases, e.g. skylight social, community lexicons, etc. separately or just have one that’s basically “writes to collections w these NSIDs?”

3rd option is there to reflect information that may not exist elsewhere but useful for folks that might use this app lexicon.

Other optional ones suggested - brand did, creator did, source code url, etc seem less critical to start.

Unfortunately I’m still seing people who are having a lot of trouble getting OAuth working and deciding they just have to shelve it for now. :face_exhaling:

I’ve also run into several ATProto apps in app lists that require password login. Well, actually, Bluesky and Blacksky are examples. :sweat_smile:

Also, it seems like maybe it’d be good to have that info right in the lexicon. Being able to just use the ATProto client to get the info without having to make a separate OAuth metadata fetch seems good.

I kind of feel like custom lexicon lists aren’t particularly important in an app list for most people. At least for a first pass.

It seems strange to me to have it serve multiple different purposes for one field.

Agreed. :+1:


So maybe bare bones is just?

  • url
  • name
  • logo
  • short description
  • category ( from fixed list that is open ended so we can extend it later )

My thinking re:logo from oauth metadata was that logos change more than url/name might.

and by “OR” I meant one of those as a field, not any of those in a field ha.

You make good points — perhaps I went too simple :winking_face_with_tongue: I think this is a pretty good set to start from coupled with the work @dame.is started (so trimming those lexicons a bit).

1 Like

Hello, excited to jump in on this conversation (thanks @byarielm.fyi for the ping :slightly_smiling_face:).

I maintain ATproto Apps • atproto.brussels, and a shared lexicon would immediately make this kind of work easier.

To give concrete context, here are the fields I currently rely on to describe apps:

  • name
  • url
  • platform (web / ios / android / other)
  • short description
  • category (although I’m starting to think this should become tags)
  • alternative_to (many apps position themselves relative to existing products)
  • last_checked (basic health check via cron)
  • Icon (via web scrapping, defaulting to favicon.ico)

I’ve also experimented with storing user ratings in the voter’s PDS as an optional write-through ( lexicon nsid brussels.loves.appRating ).


What I’m realizing is that even with this, something important is missing:
we don’t have a shared way to describe how an app fits into the ATProto ecosystem itself.

I think of the lexicon as a shared mental model of what an app is.

It should help answer three questions:

  1. What is this app?
  2. What is it for?
  3. How does it plug into ATProto?

My directory does a decent job (self patting on the back) at #1 and #2. But #3 is almost entirely missing.


proposal

Rather than aiming for a complex ontology, I think a simple, adoptable structure would go a long way.

Each app could expose:

  • Type → Client / Tool / Service / Infrastructure / Directory
  • Domain → Photos / Messaging / Publishing / etc.
  • Protocol roles → Feed builder, Publisher, Repo tool, etc. (multiple allowed)

Examples:

SkyFeed
Type: Client
Domain: Microblogging
Roles: Account client, Feed builder

WhiteWind
Type: Service
Domain: Publishing
Roles: Publisher

PDSls
Type: Tool
Domain: Developer
Roles: Repo tool, Firehose tool


Without this separation, we end up mixing “Client”, “Tool”, and “Social” in the same bucket.


I’m less concerned about metadata like authorship (which is useful but straightforward), and more about how we consistently locate an app within the ecosystem in a way that is clear and reusable.

If others are already experimenting with similar structures (e.g. atproto.garden), I’d be very interested in aligning rather than reinventing.

3 Likes