Skip to content

Add scoped-facet API routes, replace collection pool/errors with scope, and remove /v0/collections claim endpoint#330

Merged
eXamadeus merged 1 commit into
mainfrom
julian/06-14-regenerate_registry_api_types_replace_collections_with_scoped_facet_endpoints_and_rename_collection_pool_to_scope_
Jun 15, 2026
Merged

Add scoped-facet API routes, replace collection pool/errors with scope, and remove /v0/collections claim endpoint#330
eXamadeus merged 1 commit into
mainfrom
julian/06-14-regenerate_registry_api_types_replace_collections_with_scoped_facet_endpoints_and_rename_collection_pool_to_scope_

Conversation

@eXamadeus

Copy link
Copy Markdown
Member

Why

The registry API has migrated from a "collections" model to a first-class "scopes" model. Scoped facets (e.g. @julian/cowsay) now have dedicated routes rather than being addressed via encoded slashes, and the /v0/collections claim endpoint has been removed in favor of scopes being created automatically at onboarding time.

Details

Scoped facet routes added:

  • GET /v0/facets/@{scope}/{name}/latest-version — latest version pointer for a scoped facet
  • GET /v0/facets/@{scope}/{name}/versions/{version} — full version list
  • GET /v0/facets/@{scope}/{name}/{version} — version metadata
  • GET /v0/facets/@{scope}/{name}/{version}/archive — 302 redirect to presigned S3 tarball URL
  • GET /v0/facets/@{scope}/{name}/{version}/contents — verified resource bodies
  • GET /v0/facets/@{scope} — scope-root detail including owner identity and facet summaries (ScopeRootResponse)

Collections removed:

  • POST /v0/collections (claim a collection) is gone. Scopes are now provisioned automatically when a user claims their username via POST /v0/onboarding/username, which now atomically creates the USERNAME reservation, PROFILE row, COGNITO_SUB reservation, and the user's @<username> scope. The onboarding route now also returns 403 E_NAME_BLOCKED for reserved or blocked names.

Error code changes:

  • E_COLLECTION_CLAIMED and E_COLLECTION_NOT_OWNED replaced by E_SCOPE_NOT_FOUND and E_SCOPE_NOT_OWNED
  • E_FACET_NOT_OWNED added
  • Reservation pool type renamed from collection to scope
  • queue_type is now a constant global-facet (the collection-claim variant is removed)
  • ClaimCollectionIdempotent and ClaimCollectionSuccess schemas removed

Migration run responses now include created and deleted counts.

Unscoped facet name pattern updated to ^[a-z][a-z0-9-]*[a-z0-9]$ (no longer allows encoded slash for namespacing); scoped facets must use the new literal-slash routes.

Verification

CI

…endpoints and rename `collection` pool to `scope`
Copilot AI review requested due to automatic review settings June 14, 2026 23:12
@changeset-bot

changeset-bot Bot commented Jun 14, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 5722ed7

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Copy link
Copy Markdown
Member Author

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5722ed7852

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

- schema:
type: string
in: path
name: scope{(@|%40)[^

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Use valid OpenAPI templates for scoped routes

The scoped route template is malformed: the inline regex in {scope{(@|%40)[^}/]+} is being interpreted as an extra path parameter, so the snapshot (and generated client) now require a bogus parameter named scope{(@|%40)[^. Any typed caller for the new scoped endpoints cannot call them with just { scope, name }, and interpolation will not produce the intended /v0/facets/@scope/name/... URL. Please keep the OpenAPI path as /v0/facets/{scope}/{name}/... and put the regex only on the scope parameter schema.

Useful? React with 👍 / 👎.

Comment on lines +931 to +935
description: Canonical facet name. For scoped facets use the literal-slash path
(`/@scope/name/...`) instead of encoding the slash.
schema:
type: string
pattern: ^(?:[a-z][a-z0-9-]*\/)?[a-z][a-z0-9-]*$
pattern: ^[a-z][a-z0-9-]*[a-z0-9]$

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Route scoped facets off the unscoped name parameter

This contract now restricts {name} to unscoped names and says scoped facets must use the literal-slash routes, but the engine still resolves and downloads all registry facets through /v0/facets/{name}/{version} and /v0/facets/{name}/{version}/archive with the whole facet name as name in resolve-metadata.ts and download.ts. For a scoped facet such as @julian/cowsay (or the existing acme/cowsay parser form), the client will continue encoding the slash into the unscoped endpoint and get a registry 404/ownership error instead of hitting the new scoped route; split the scope/name and call the scoped paths when the name is scoped.

Useful? React with 👍 / 👎.

eXamadeus commented Jun 15, 2026

Copy link
Copy Markdown
Member Author

Merge activity

  • Jun 15, 12:19 AM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Jun 15, 12:19 AM UTC: @eXamadeus merged this pull request with Graphite.

@eXamadeus eXamadeus merged commit a330b5d into main Jun 15, 2026
5 of 6 checks passed
@eXamadeus eXamadeus deleted the julian/06-14-regenerate_registry_api_types_replace_collections_with_scoped_facet_endpoints_and_rename_collection_pool_to_scope_ branch June 15, 2026 00:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants