~ knotless Search/
↑↓ move↵ open⇧↵ all results

chadtmiller.com/knotless

git that lives in your Atmosphere account

knotless.dev
1 collaborator

knotless 0.13.0 Latest 2 packages, 1 image

1
10

The space type private repositories are has a lexicon, dev.knotless.space

Merged
Merged chadtmiller.com asked to merge into main from chadtmiller.com/knotless:space/lexicon

What changes

A lexicon for the space type private repositories are. lexicons/dev/knotless/space.json is dev.knotless.space, of "type": "space", modelled on grain's social.grain.group: key any (the repository's name), a name for consent screens, and the collections a private repository's space holds. Those are the ones knotless writes there: the repository's own records (repo, ref, claim, pack, redirect), what members write of it (pull, issue, comment, state, hide, block, queue, label, reaction), a runner's check, an owner's rerun, and an organization's orgMember (the collections knotless-serve's spaces.rs syncs, less the org's own org and orgAcceptance, which are public and in the org's own space, plus pack and rerun, which the client writes there but the pages do not read). publish-lexicons.yml publishes it on merge: the authority knotless.dev already has its _lexicon record, so no DNS changes (its plan, run here: 1 to put, 0 to delete, 159 unchanged).

The checks take space lexicons. goat 0.2.6 refuses the whole file (schema-json-parse: unexpected schema type: space), as it does grain's. harness/lexicons.mjs lets that one finding go, only for a file whose main is a space, and checks such a file itself against the alpha's lexiconSpaceSchema: its only def is main, a valid key, a name of 1 to 64 characters, and collections that are record lexicons here; and, against main, that no collection is taken out, since a scope naming the type alone is granted the lexicon's collections. @atproto/lex 0.4.4, which makes the pages' types, fails the build on it too (--exclude does not help, as it parses first), so npm run lex removes it from its copy; the pages make no type of a space. @atproto/lexicon 0.7.17 in harness/answers.mjs takes it as it is.

Docs. access.md's Scopes and gateway.md say why the scopes still name every space type.

The scopes do not change here: that is the pull after this, once the lexicon is published.

Why

Both OAuth scopes say space:*, every space of every type, so a knotless login can read and write other apps' spaces, grain's group pools among them. Naming dev.knotless.space needs its lexicon.

This is the first of two pulls rather than one because of what the spaces alpha (11c5d98c, the test and e2e pin) does with a named type. OAuthProvider builds the authorization page's data with lexiconManager.getSpacesFromScope(scope), which resolves the lexicon of every space type the scope names, with or without collection=, and turns any failure into invalid_scope: the login is refused. (Token issuance, buildTokenScope, resolves only a bare space:<type> with no collections, to fill them in from the lexicon.) So a scope naming dev.knotless.space deployed before the lexicon is published would break every login on a PDS with spaces. Lexicon first, scopes once it resolves.

How it was checked

node harness/lexicons.mjs passes, and fails as it should on a bad key and a collection with no lexicon. harness/answers.mjs passes with @atproto/lexicon 0.7.17. lex build with 0.4.4 fails with the file and makes all 318 types without it. deploy/publish-lexicons.mjs plans it as one schema to put. The rest is left to CI.

Shortcomings

The scopes are still space:*. Narrowing them, the next pull, has two things to settle:

  • An organization's space type is dev.knotless.org, which is also the NSID of its public record, so it can have no space lexicon, and a scope naming it would be refused by the alpha ("Lexicon document is not a space"). Naming only dev.knotless.space would cut members off from writing their orgAcceptance in the org's space and the gateway from making it. It needs a type of its own, and existing organizations' spaces moved to it.
  • The tests' and e2e's alpha resolves lexicons through DNS and its own PLC, so it cannot resolve the published one; the harness would have to put dev.knotless.space in its PDS's lexicon store before logging in.

🤖 Generated with Claude Code

Approved

This adds the dev.knotless.space lexicon and teaches harness/lexicons.mjs to accept space lexicons. The harness drops only goat's "unexpected schema type: space" finding, and only for a file whose main is a space. It then checks the file itself: key, name length, collections that are record lexicons, and no collection removed since base. npm run lex removes the file from its copy because @atproto/lex 0.4.4 can't parse it. The docs in access.md and gateway.md are updated to match.

I found nothing that must change.

  • The harness logic reads correctly. The relative paths used for spaces line up with goat's file-path, since goat is run from the repo root on lexicons/.
  • The collection list matches what the description says, and the Rust code doesn't glob lexicons/, so the new file shouldn't affect it.
  • Keeping the scopes at space:* until the lexicon is published is the right order, for the reason the body gives.

Only check has passed so far. The other checks, lexicons, web, docs, test, shots and e2e, were still queued when I looked. The lexicons and web checks are the ones that exercise the harness change and the npm run lex edit, so wait for them to pass before merging.

Merged as 730d606